Merge "Small clean up of fuse code."
diff --git a/adb/Android.mk b/adb/Android.mk
index 0114ca3..e17240b 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -45,7 +45,6 @@
 # get enough of adb in here that we no longer need minadb. https://b/17626262
 LIBADB_SRC_FILES := \
     adb.cpp \
-    adb_auth.cpp \
     adb_io.cpp \
     adb_listeners.cpp \
     adb_trace.cpp \
@@ -103,7 +102,7 @@
 LOCAL_CFLAGS := $(LIBADB_CFLAGS) -DADB_HOST=0
 LOCAL_SRC_FILES := \
     $(LIBADB_SRC_FILES) \
-    adb_auth_client.cpp \
+    adbd_auth.cpp \
     jdwp_service.cpp \
     usb_linux_client.cpp \
 
@@ -324,7 +323,6 @@
 LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
 LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
-LOCAL_C_INCLUDES += system/extras/ext4_utils
 
 LOCAL_SANITIZE := $(adb_target_sanitize)
 LOCAL_STRIP_MODULE := keep_symbols
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 9ae3f1c..29d6e65 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -94,6 +94,18 @@
     abort();
 }
 
+uint32_t calculate_apacket_checksum(const apacket* p) {
+    const unsigned char* x = reinterpret_cast<const unsigned char*>(p->data);
+    uint32_t sum = 0;
+    size_t count = p->msg.data_length;
+
+    while (count-- > 0) {
+        sum += *x++;
+    }
+
+    return sum;
+}
+
 apacket* get_apacket(void)
 {
     apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket)));
@@ -351,19 +363,31 @@
         break;
 
     case A_AUTH:
-        if (p->msg.arg0 == ADB_AUTH_TOKEN) {
-            t->connection_state = kCsUnauthorized;
-            send_auth_response(p->data, p->msg.data_length, t);
-        } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
-            if (adb_auth_verify(t->token, sizeof(t->token), p->data, p->msg.data_length)) {
-                adb_auth_verified(t);
-                t->failed_auth_attempts = 0;
-            } else {
-                if (t->failed_auth_attempts++ > 256) adb_sleep_ms(1000);
-                send_auth_request(t);
-            }
-        } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
-            adb_auth_confirm_key(p->data, p->msg.data_length, t);
+        switch (p->msg.arg0) {
+#if ADB_HOST
+            case ADB_AUTH_TOKEN:
+                t->connection_state = kCsUnauthorized;
+                send_auth_response(p->data, p->msg.data_length, t);
+                break;
+#else
+            case ADB_AUTH_SIGNATURE:
+                if (adbd_auth_verify(t->token, sizeof(t->token), p->data, p->msg.data_length)) {
+                    adbd_auth_verified(t);
+                    t->failed_auth_attempts = 0;
+                } else {
+                    if (t->failed_auth_attempts++ > 256) adb_sleep_ms(1000);
+                    send_auth_request(t);
+                }
+                break;
+
+            case ADB_AUTH_RSAPUBLICKEY:
+                adbd_auth_confirm_key(p->data, p->msg.data_length, t);
+                break;
+#endif
+            default:
+                t->connection_state = kCsOffline;
+                handle_offline(t);
+                break;
         }
         break;
 
diff --git a/adb/adb.h b/adb/adb.h
index 0b9fe5b..8064c17 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -18,6 +18,7 @@
 #define __ADB_H
 
 #include <limits.h>
+#include <stdint.h>
 #include <sys/types.h>
 
 #include <string>
@@ -56,25 +57,27 @@
 struct usb_handle;
 
 struct amessage {
-    unsigned command;       /* command identifier constant      */
-    unsigned arg0;          /* first argument                   */
-    unsigned arg1;          /* second argument                  */
-    unsigned data_length;   /* length of payload (0 is allowed) */
-    unsigned data_check;    /* checksum of data payload         */
-    unsigned magic;         /* command ^ 0xffffffff             */
+    uint32_t command;     /* command identifier constant      */
+    uint32_t arg0;        /* first argument                   */
+    uint32_t arg1;        /* second argument                  */
+    uint32_t data_length; /* length of payload (0 is allowed) */
+    uint32_t data_check;  /* checksum of data payload         */
+    uint32_t magic;       /* command ^ 0xffffffff             */
 };
 
 struct apacket
 {
     apacket *next;
 
-    unsigned len;
-    unsigned char *ptr;
+    size_t len;
+    char* ptr;
 
     amessage msg;
-    unsigned char data[MAX_PAYLOAD];
+    char data[MAX_PAYLOAD];
 };
 
+uint32_t calculate_apacket_checksum(const apacket* packet);
+
 /* the adisconnect structure is used to record a callback that
 ** will be called whenever a transport is disconnected (e.g. by the user)
 ** this should be used to cleanup objects that depend on the
diff --git a/adb/adb_auth.cpp b/adb/adb_auth.cpp
deleted file mode 100644
index 0b07158..0000000
--- a/adb/adb_auth.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG ADB
-
-#include "adb.h"
-#include "adb_auth.h"
-#include "transport.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-bool auth_required = true;
-
-void send_auth_request(atransport *t)
-{
-    LOG(INFO) << "Calling send_auth_request...";
-
-    if (!adb_auth_generate_token(t->token, sizeof(t->token))) {
-        PLOG(ERROR) << "Error generating token";
-        return;
-    }
-
-    apacket* p = get_apacket();
-    memcpy(p->data, t->token, sizeof(t->token));
-    p->msg.command = A_AUTH;
-    p->msg.arg0 = ADB_AUTH_TOKEN;
-    p->msg.data_length = sizeof(t->token);
-    send_packet(p, t);
-}
-
-static void send_auth_publickey(atransport* t) {
-    LOG(INFO) << "Calling send_auth_publickey";
-
-    std::string key = adb_auth_get_userkey();
-    if (key.empty()) {
-        D("Failed to get user public key");
-        return;
-    }
-
-    if (key.size() >= MAX_PAYLOAD_V1) {
-        D("User public key too large (%zu B)", key.size());
-        return;
-    }
-
-    apacket* p = get_apacket();
-    memcpy(p->data, key.c_str(), key.size() + 1);
-
-    p->msg.command = A_AUTH;
-    p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY;
-
-    // adbd expects a null-terminated string.
-    p->msg.data_length = key.size() + 1;
-    send_packet(p, t);
-}
-
-void send_auth_response(uint8_t* token, size_t token_size, atransport* t) {
-    std::shared_ptr<RSA> key = t->NextKey();
-    if (key == nullptr) {
-        // No more private keys to try, send the public key.
-        send_auth_publickey(t);
-        return;
-    }
-
-    LOG(INFO) << "Calling send_auth_response";
-    apacket* p = get_apacket();
-
-    int ret = adb_auth_sign(key.get(), token, token_size, p->data);
-    if (!ret) {
-        D("Error signing the token");
-        put_apacket(p);
-        return;
-    }
-
-    p->msg.command = A_AUTH;
-    p->msg.arg0 = ADB_AUTH_SIGNATURE;
-    p->msg.data_length = ret;
-    send_packet(p, t);
-}
-
-void adb_auth_verified(atransport *t)
-{
-    handle_online(t);
-    send_connect(t);
-}
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index 59b80d8..a6f224f 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -24,14 +24,6 @@
 
 #include <openssl/rsa.h>
 
-extern bool auth_required;
-
-int adb_auth_keygen(const char* filename);
-void adb_auth_verified(atransport *t);
-
-void send_auth_request(atransport *t);
-void send_auth_response(uint8_t *token, size_t token_size, atransport *t);
-
 /* AUTH packets first argument */
 /* Request */
 #define ADB_AUTH_TOKEN         1
@@ -42,25 +34,25 @@
 #if ADB_HOST
 
 void adb_auth_init();
-int adb_auth_sign(RSA* key, const unsigned char* token, size_t token_size, unsigned char* sig);
+
+int adb_auth_keygen(const char* filename);
 std::string adb_auth_get_userkey();
 std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys();
 
-static inline bool adb_auth_generate_token(void*, size_t) { abort(); }
-static inline bool adb_auth_verify(void*, size_t, void*, int) { abort(); }
-static inline void adb_auth_confirm_key(unsigned char*, size_t, atransport*) { abort(); }
+void send_auth_response(const char* token, size_t token_size, atransport* t);
 
 #else // !ADB_HOST
 
-static inline int adb_auth_sign(void*, const unsigned char*, size_t, unsigned char*) { abort(); }
-static inline std::string adb_auth_get_userkey() { abort(); }
-static inline std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys() { abort(); }
+extern bool auth_required;
 
 void adbd_auth_init(void);
+void adbd_auth_verified(atransport *t);
+
 void adbd_cloexec_auth_socket();
-bool adb_auth_generate_token(void* token, size_t token_size);
-bool adb_auth_verify(uint8_t* token, size_t token_size, uint8_t* sig, int sig_len);
-void adb_auth_confirm_key(unsigned char *data, size_t len, atransport *t);
+bool adbd_auth_verify(const char* token, size_t token_size, const char* sig, int sig_len);
+void adbd_auth_confirm_key(const char* data, size_t len, atransport* t);
+
+void send_auth_request(atransport *t);
 
 #endif // ADB_HOST
 
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index 072c7f5..ff2d76d 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -45,6 +45,7 @@
 #include "adb_auth.h"
 #include "adb_utils.h"
 #include "sysdeps.h"
+#include "transport.h"
 
 static std::mutex& g_keys_mutex = *new std::mutex;
 static std::map<std::string, std::shared_ptr<RSA>>& g_keys =
@@ -297,14 +298,15 @@
     return result;
 }
 
-int adb_auth_sign(RSA* key, const unsigned char* token, size_t token_size, unsigned char* sig) {
+static int adb_auth_sign(RSA* key, const char* token, size_t token_size, char* sig) {
     if (token_size != TOKEN_SIZE) {
         D("Unexpected token size %zd", token_size);
         return 0;
     }
 
     unsigned int len;
-    if (!RSA_sign(NID_sha1, token, token_size, sig, &len, key)) {
+    if (!RSA_sign(NID_sha1, reinterpret_cast<const uint8_t*>(token), token_size,
+                  reinterpret_cast<uint8_t*>(sig), &len, key)) {
         return 0;
     }
 
@@ -421,3 +423,52 @@
         read_keys(path.c_str());
     }
 }
+
+static void send_auth_publickey(atransport* t) {
+    LOG(INFO) << "Calling send_auth_publickey";
+
+    std::string key = adb_auth_get_userkey();
+    if (key.empty()) {
+        D("Failed to get user public key");
+        return;
+    }
+
+    if (key.size() >= MAX_PAYLOAD_V1) {
+        D("User public key too large (%zu B)", key.size());
+        return;
+    }
+
+    apacket* p = get_apacket();
+    memcpy(p->data, key.c_str(), key.size() + 1);
+
+    p->msg.command = A_AUTH;
+    p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY;
+
+    // adbd expects a null-terminated string.
+    p->msg.data_length = key.size() + 1;
+    send_packet(p, t);
+}
+
+void send_auth_response(const char* token, size_t token_size, atransport* t) {
+    std::shared_ptr<RSA> key = t->NextKey();
+    if (key == nullptr) {
+        // No more private keys to try, send the public key.
+        send_auth_publickey(t);
+        return;
+    }
+
+    LOG(INFO) << "Calling send_auth_response";
+    apacket* p = get_apacket();
+
+    int ret = adb_auth_sign(key.get(), token, token_size, p->data);
+    if (!ret) {
+        D("Error signing the token");
+        put_apacket(p);
+        return;
+    }
+
+    p->msg.command = A_AUTH;
+    p->msg.arg0 = ADB_AUTH_SIGNATURE;
+    p->msg.data_length = ret;
+    send_packet(p, t);
+}
diff --git a/adb/adb_auth_client.cpp b/adb/adbd_auth.cpp
similarity index 79%
rename from adb/adb_auth_client.cpp
rename to adb/adbd_auth.cpp
index 84ad6ef..b5f87be 100644
--- a/adb/adb_auth_client.cpp
+++ b/adb/adbd_auth.cpp
@@ -44,7 +44,9 @@
 static atransport* usb_transport;
 static bool needs_retry = false;
 
-bool adb_auth_verify(uint8_t* token, size_t token_size, uint8_t* sig, int sig_len) {
+bool auth_required = true;
+
+bool adbd_auth_verify(const char* token, size_t token_size, const char* sig, int sig_len) {
     static constexpr const char* key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", nullptr };
 
     for (const auto& path : key_paths) {
@@ -76,7 +78,9 @@
                     continue;
                 }
 
-                bool verified = (RSA_verify(NID_sha1, token, token_size, sig, sig_len, key) == 1);
+                bool verified =
+                    (RSA_verify(NID_sha1, reinterpret_cast<const uint8_t*>(token), token_size,
+                                reinterpret_cast<const uint8_t*>(sig), sig_len, key) == 1);
                 RSA_free(key);
                 if (verified) return true;
             }
@@ -85,7 +89,7 @@
     return false;
 }
 
-bool adb_auth_generate_token(void* token, size_t token_size) {
+static bool adbd_auth_generate_token(void* token, size_t token_size) {
     FILE* fp = fopen("/dev/urandom", "re");
     if (!fp) return false;
     bool okay = (fread(token, token_size, 1, fp) == 1);
@@ -105,7 +109,7 @@
     framework_fd = -1;
 }
 
-static void adb_auth_event(int fd, unsigned events, void*) {
+static void adbd_auth_event(int fd, unsigned events, void*) {
     if (events & FDE_READ) {
         char response[2];
         int ret = unix_read(fd, response, sizeof(response));
@@ -113,13 +117,13 @@
             framework_disconnected();
         } else if (ret == 2 && response[0] == 'O' && response[1] == 'K') {
             if (usb_transport) {
-                adb_auth_verified(usb_transport);
+                adbd_auth_verified(usb_transport);
             }
         }
     }
 }
 
-void adb_auth_confirm_key(unsigned char* key, size_t len, atransport* t) {
+void adbd_auth_confirm_key(const char* key, size_t len, atransport* t) {
     if (!usb_transport) {
         usb_transport = t;
         t->AddDisconnect(&usb_disconnect);
@@ -150,7 +154,7 @@
     }
 }
 
-static void adb_auth_listener(int fd, unsigned events, void* data) {
+static void adbd_auth_listener(int fd, unsigned events, void* data) {
     int s = adb_socket_accept(fd, nullptr, nullptr);
     if (s < 0) {
         PLOG(ERROR) << "Failed to accept";
@@ -163,7 +167,7 @@
     }
 
     framework_fd = s;
-    fdevent_install(&framework_fde, framework_fd, adb_auth_event, nullptr);
+    fdevent_install(&framework_fde, framework_fd, adbd_auth_event, nullptr);
     fdevent_add(&framework_fde, FDE_READ);
 
     if (needs_retry) {
@@ -193,6 +197,28 @@
         return;
     }
 
-    fdevent_install(&listener_fde, fd, adb_auth_listener, NULL);
+    fdevent_install(&listener_fde, fd, adbd_auth_listener, NULL);
     fdevent_add(&listener_fde, FDE_READ);
 }
+
+void send_auth_request(atransport* t) {
+    LOG(INFO) << "Calling send_auth_request...";
+
+    if (!adbd_auth_generate_token(t->token, sizeof(t->token))) {
+        PLOG(ERROR) << "Error generating token";
+        return;
+    }
+
+    apacket* p = get_apacket();
+    memcpy(p->data, t->token, sizeof(t->token));
+    p->msg.command = A_AUTH;
+    p->msg.arg0 = ADB_AUTH_TOKEN;
+    p->msg.data_length = sizeof(t->token);
+    send_packet(p, t);
+}
+
+void adbd_auth_verified(atransport *t)
+{
+    handle_online(t);
+    send_connect(t);
+}
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index b809c4f..fff6049 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -122,7 +122,7 @@
 }
 
 static int local_socket_enqueue(asocket* s, apacket* p) {
-    D("LS(%d): enqueue %d", s->id, p->len);
+    D("LS(%d): enqueue %zu", s->id, p->len);
 
     p->ptr = p->data;
 
@@ -195,7 +195,7 @@
 
     /* dispose of any unwritten data */
     for (p = s->pkt_first; p; p = n) {
-        D("LS(%d): discarding %d bytes", s->id, p->len);
+        D("LS(%d): discarding %zu bytes", s->id, p->len);
         n = p->next;
         put_apacket(p);
     }
@@ -305,7 +305,7 @@
 
     if (ev & FDE_READ) {
         apacket* p = get_apacket();
-        unsigned char* x = p->data;
+        char* x = p->data;
         const size_t max_payload = s->get_max_payload();
         size_t avail = max_payload;
         int r = 0;
@@ -553,7 +553,7 @@
     s->close(s);
 }
 
-static unsigned unhex(unsigned char* s, int len) {
+static unsigned unhex(char* s, int len) {
     unsigned n = 0, c;
 
     while (len-- > 0) {
@@ -665,7 +665,7 @@
     TransportType type = kTransportAny;
 #endif
 
-    D("SS(%d): enqueue %d", s->id, p->len);
+    D("SS(%d): enqueue %zu", s->id, p->len);
 
     if (s->pkt_first == 0) {
         s->pkt_first = p;
@@ -698,7 +698,7 @@
     D("SS(%d): len is %d", s->id, len);
     /* can't do anything until we have the full header */
     if ((len + 4) > p->len) {
-        D("SS(%d): waiting for %d more bytes", s->id, len + 4 - p->len);
+        D("SS(%d): waiting for %zu more bytes", s->id, len + 4 - p->len);
         return 0;
     }
 
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 87712fc..7b4bb1c 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -150,32 +150,17 @@
     }
 }
 
-void send_packet(apacket *p, atransport *t)
-{
-    unsigned char *x;
-    unsigned sum;
-    unsigned count;
-
+void send_packet(apacket* p, atransport* t) {
     p->msg.magic = p->msg.command ^ 0xffffffff;
-
-    count = p->msg.data_length;
-    x = (unsigned char *) p->data;
-    sum = 0;
-    while(count-- > 0){
-        sum += *x++;
-    }
-    p->msg.data_check = sum;
+    p->msg.data_check = calculate_apacket_checksum(p);
 
     print_packet("send", p);
 
     if (t == NULL) {
-        D("Transport is null");
-        // Zap errno because print_packet() and other stuff have errno effect.
-        errno = 0;
-        fatal_errno("Transport is null");
+        fatal("Transport is null");
     }
 
-    if(write_packet(t->transport_socket, t->serial, &p)){
+    if (write_packet(t->transport_socket, t->serial, &p)) {
         fatal_errno("cannot enqueue packet on transport socket");
     }
 }
@@ -1052,25 +1037,14 @@
     return 0;
 }
 
-int check_data(apacket *p)
-{
-    unsigned count, sum;
-    unsigned char *x;
-
-    count = p->msg.data_length;
-    x = p->data;
-    sum = 0;
-    while(count-- > 0) {
-        sum += *x++;
-    }
-
-    if(sum != p->msg.data_check) {
+int check_data(apacket* p) {
+    if (calculate_apacket_checksum(p) != p->msg.data_check) {
         return -1;
-    } else {
-        return 0;
     }
+    return 0;
 }
 
+#if ADB_HOST
 std::shared_ptr<RSA> atransport::NextKey() {
     if (keys_.empty()) keys_ = adb_auth_get_private_keys();
 
@@ -1078,3 +1052,4 @@
     keys_.pop_front();
     return result;
 }
+#endif
diff --git a/adb/transport.h b/adb/transport.h
index 959681f..621516c 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -108,9 +108,11 @@
         return type == kTransportLocal && local_port_for_emulator_ == -1;
     }
 
+#if ADB_HOST
     std::shared_ptr<RSA> NextKey();
+#endif
 
-    unsigned char token[TOKEN_SIZE] = {};
+    char token[TOKEN_SIZE] = {};
     size_t failed_auth_attempts = 0;
 
     const std::string connection_state_name() const;
@@ -161,7 +163,9 @@
     // A list of adisconnect callbacks called when the transport is kicked.
     std::list<adisconnect*> disconnects_;
 
+#if ADB_HOST
     std::deque<std::shared_ptr<RSA>> keys_;
+#endif
 
     DISALLOW_COPY_AND_ASSIGN(atransport);
 };
diff --git a/base/include/android-base/parseint.h b/base/include/android-base/parseint.h
index ed75e2d..7415409 100644
--- a/base/include/android-base/parseint.h
+++ b/base/include/android-base/parseint.h
@@ -31,7 +31,7 @@
 template <typename T>
 bool ParseUint(const char* s, T* out,
                T max = std::numeric_limits<T>::max()) {
-  int base = (s[0] == '0' && s[1] == 'x') ? 16 : 10;
+  int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10;
   errno = 0;
   char* end;
   unsigned long long int result = strtoull(s, &end, base);
@@ -53,7 +53,7 @@
 bool ParseInt(const char* s, T* out,
               T min = std::numeric_limits<T>::min(),
               T max = std::numeric_limits<T>::max()) {
-  int base = (s[0] == '0' && s[1] == 'x') ? 16 : 10;
+  int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10;
   errno = 0;
   char* end;
   long long int result = strtoll(s, &end, base);
diff --git a/cpio/mkbootfs.c b/cpio/mkbootfs.c
index 0e35323..b89c395 100644
--- a/cpio/mkbootfs.c
+++ b/cpio/mkbootfs.c
@@ -51,6 +51,8 @@
 #define CANNED_LINE_LENGTH  (1024)
 #endif
 
+#define TRAILER "TRAILER!!!"
+
 static int verbose = 0;
 static int total_size = 0;
 
@@ -80,8 +82,8 @@
     } else {
         // Use the compiled-in fs_config() function.
         unsigned st_mode = s->st_mode;
-        fs_config(path, S_ISDIR(s->st_mode), target_out_path,
-                       &s->st_uid, &s->st_gid, &st_mode, &capabilities);
+        int is_dir = S_ISDIR(s->st_mode) || strcmp(path, TRAILER) == 0;
+        fs_config(path, is_dir, target_out_path, &s->st_uid, &s->st_gid, &st_mode, &capabilities);
         s->st_mode = (typeof(s->st_mode)) st_mode;
     }
 }
@@ -140,7 +142,7 @@
 {
     struct stat s;
     memset(&s, 0, sizeof(s));
-    _eject(&s, "TRAILER!!!", 10, 0, 0);
+    _eject(&s, TRAILER, 10, 0, 0);
 
     while(total_size & 0xff) {
         total_size++;
diff --git a/include/cutils/native_handle.h b/include/cutils/native_handle.h
index 31695cb..813dadc 100644
--- a/include/cutils/native_handle.h
+++ b/include/cutils/native_handle.h
@@ -57,6 +57,15 @@
 native_handle_t* native_handle_create(int numFds, int numInts);
 
 /*
+ * native_handle_clone
+ *
+ * creates a native_handle_t and initializes it from another native_handle_t.
+ * Must be destroyed with native_handle_delete().
+ *
+ */
+native_handle_t* native_handle_clone(const native_handle_t* handle);
+
+/*
  * native_handle_delete
  * 
  * frees a native_handle_t allocated with native_handle_create().
diff --git a/init/init_parser.cpp b/init/init_parser.cpp
index 9ec26af..d017390 100644
--- a/init/init_parser.cpp
+++ b/init/init_parser.cpp
@@ -122,14 +122,20 @@
         return false;
     }
     dirent* current_file;
+    std::vector<std::string> files;
     while ((current_file = readdir(config_dir.get()))) {
-        std::string current_path =
-            android::base::StringPrintf("%s/%s", path.c_str(), current_file->d_name);
         // Ignore directories and only process regular files.
         if (current_file->d_type == DT_REG) {
-            if (!ParseConfigFile(current_path)) {
-                LOG(ERROR) << "could not import file '" << current_path << "'";
-            }
+            std::string current_path =
+                android::base::StringPrintf("%s/%s", path.c_str(), current_file->d_name);
+            files.emplace_back(current_path);
+        }
+    }
+    // Sort first so we load files in a consistent order (bug 31996208)
+    std::sort(files.begin(), files.end());
+    for (const auto& file : files) {
+        if (!ParseConfigFile(file)) {
+            LOG(ERROR) << "could not import file '" << file << "'";
         }
     }
     return true;
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 8624d13..955c0ec 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -87,12 +87,6 @@
                 "uevent.c",
             ],
 
-            // TODO: remove liblog as whole static library, once we don't have prebuilt that requires
-            // liblog symbols present in libcutils.
-            whole_static_libs: [
-                "liblog",
-            ],
-
             static_libs: ["libdebuggerd_client"],
             export_static_lib_headers: ["libdebuggerd_client"],
 
diff --git a/libcutils/native_handle.c b/libcutils/native_handle.c
index 7f3479d..cae146d 100644
--- a/libcutils/native_handle.c
+++ b/libcutils/native_handle.c
@@ -44,6 +44,27 @@
     return h;
 }
 
+native_handle_t* native_handle_clone(const native_handle_t* handle)
+{
+    native_handle_t* clone = native_handle_create(handle->numFds, handle->numInts);
+    int i;
+
+    for (i = 0; i < handle->numFds; i++) {
+        clone->data[i] = dup(handle->data[i]);
+        if (clone->data[i] < 0) {
+            clone->numFds = i;
+            native_handle_close(clone);
+            native_handle_delete(clone);
+            return NULL;
+        }
+    }
+
+    memcpy(&clone->data[handle->numFds], &handle->data[handle->numFds],
+            sizeof(int) * handle->numInts);
+
+    return clone;
+}
+
 int native_handle_delete(native_handle_t* h)
 {
     if (h) {
diff --git a/libsparse/output_file.c b/libsparse/output_file.c
index 6578d99..2115998 100644
--- a/libsparse/output_file.c
+++ b/libsparse/output_file.c
@@ -63,7 +63,7 @@
 	int (*open)(struct output_file *, int fd);
 	int (*skip)(struct output_file *, int64_t);
 	int (*pad)(struct output_file *, int64_t);
-	int (*write)(struct output_file *, void *, int);
+	int (*write)(struct output_file *, void *, size_t);
 	void (*close)(struct output_file *);
 };
 
@@ -149,18 +149,23 @@
 	return 0;
 }
 
-static int file_write(struct output_file *out, void *data, int len)
+static int file_write(struct output_file *out, void *data, size_t len)
 {
-	int ret;
+	ssize_t ret;
 	struct output_file_normal *outn = to_output_file_normal(out);
 
-	ret = write(outn->fd, data, len);
-	if (ret < 0) {
-		error_errno("write");
-		return -1;
-	} else if (ret < len) {
-		error("incomplete write");
-		return -1;
+	while (len > 0) {
+		ret = write(outn->fd, data, len);
+		if (ret < 0) {
+			if (errno == EINTR) {
+				continue;
+			}
+			error_errno("write");
+			return -1;
+		}
+
+		data = (char *)data + ret;
+		len -= ret;
 	}
 
 	return 0;
@@ -232,18 +237,20 @@
 	return 0;
 }
 
-static int gz_file_write(struct output_file *out, void *data, int len)
+static int gz_file_write(struct output_file *out, void *data, size_t len)
 {
 	int ret;
 	struct output_file_gz *outgz = to_output_file_gz(out);
 
-	ret = gzwrite(outgz->gz_fd, data, len);
-	if (ret < 0) {
-		error_errno("gzwrite");
-		return -1;
-	} else if (ret < len) {
-		error("incomplete gzwrite");
-		return -1;
+	while (len > 0) {
+		ret = gzwrite(outgz->gz_fd, data,
+			      min(len, (unsigned int)INT_MAX));
+		if (ret == 0) {
+			error("gzwrite %s", gzerror(outgz->gz_fd, NULL));
+			return -1;
+		}
+		len -= ret;
+		data = (char *)data + ret;
 	}
 
 	return 0;
@@ -293,7 +300,7 @@
 	return -1;
 }
 
-static int callback_file_write(struct output_file *out, void *data, int len)
+static int callback_file_write(struct output_file *out, void *data, size_t len)
 {
 	struct output_file_callback *outc = to_output_file_callback(out);
 
@@ -698,14 +705,16 @@
 	int ret;
 	int64_t aligned_offset;
 	int aligned_diff;
-	int buffer_size;
+	uint64_t buffer_size;
 	char *ptr;
 
 	aligned_offset = offset & ~(4096 - 1);
 	aligned_diff = offset - aligned_offset;
-	buffer_size = len + aligned_diff;
+	buffer_size = (uint64_t)len + (uint64_t)aligned_diff;
 
 #ifndef _WIN32
+	if (buffer_size > SIZE_MAX)
+		return -E2BIG;
 	char *data = mmap64(NULL, buffer_size, PROT_READ, MAP_SHARED, fd,
 			aligned_offset);
 	if (data == MAP_FAILED) {
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index c6ebd52..f69bc50 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -21,6 +21,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <list>
+
 #include <log/logger.h>
 
 #include "LogStatistics.h"
@@ -467,55 +469,86 @@
     short spaces = 1;
 
     log_id_for_each(id) {
-        if (!(logMask & (1 << id))) {
-            continue;
-        }
+        if (!(logMask & (1 << id))) continue;
         oldLength = output.length();
-        if (spaces < 0) {
-            spaces = 0;
-        }
+        if (spaces < 0) spaces = 0;
         output += android::base::StringPrintf("%*s%s", spaces, "",
                                               android_log_id_to_name(id));
         spaces += spaces_total + oldLength - output.length();
     }
+    if (spaces < 0) spaces = 0;
+    output += android::base::StringPrintf("%*sTotal", spaces, "");
 
-    spaces = 4;
-    output += "\nTotal";
+    static const char TotalStr[] = "\nTotal";
+    spaces = 10 - strlen(TotalStr);
+    output += TotalStr;
 
+    size_t totalSize = 0;
+    size_t totalEls = 0;
     log_id_for_each(id) {
-        if (!(logMask & (1 << id))) {
-            continue;
-        }
+        if (!(logMask & (1 << id))) continue;
         oldLength = output.length();
-        if (spaces < 0) {
-            spaces = 0;
-        }
-        output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
-                                              sizesTotal(id),
-                                              elementsTotal(id));
+        if (spaces < 0) spaces = 0;
+        size_t szs = sizesTotal(id);
+        totalSize += szs;
+        size_t els = elementsTotal(id);
+        totalEls += els;
+        output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
         spaces += spaces_total + oldLength - output.length();
     }
+    if (spaces < 0) spaces = 0;
+    output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, totalEls);
 
-    spaces = 6;
-    output += "\nNow";
+    static const char NowStr[] = "\nNow";
+    spaces = 10 - strlen(NowStr);
+    output += NowStr;
 
+    totalSize = 0;
+    totalEls = 0;
     log_id_for_each(id) {
-        if (!(logMask & (1 << id))) {
-            continue;
-        }
+        if (!(logMask & (1 << id))) continue;
 
         size_t els = elements(id);
         if (els) {
             oldLength = output.length();
-            if (spaces < 0) {
-                spaces = 0;
-            }
-            output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
-                                                  sizes(id), els);
+            if (spaces < 0) spaces = 0;
+            size_t szs = sizes(id);
+            totalSize += szs;
+            totalEls += els;
+            output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els);
             spaces -= output.length() - oldLength;
         }
         spaces += spaces_total;
     }
+    if (spaces < 0) spaces = 0;
+    output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, totalEls);
+
+    static const char OverheadStr[] = "\nOverhead";
+    spaces = 10 - strlen(OverheadStr);
+    output += OverheadStr;
+
+    totalSize = 0;
+    log_id_for_each(id) {
+        if (!(logMask & (1 << id))) continue;
+
+        size_t els = elements(id);
+        if (els) {
+            oldLength = output.length();
+            if (spaces < 0) spaces = 0;
+            // estimate the std::list overhead.
+            static const size_t overhead =
+                ((sizeof(LogBufferElement) + sizeof(uint64_t) - 1) &
+                    -sizeof(uint64_t)) +
+                sizeof(std::list<LogBufferElement*>);
+            size_t szs = sizes(id) + els * overhead;
+            totalSize += szs;
+            output += android::base::StringPrintf("%*s%zu", spaces, "", szs);
+            spaces -= output.length() - oldLength;
+        }
+        spaces += spaces_total;
+    }
+    if (spaces < 0) spaces = 0;
+    output += android::base::StringPrintf("%*s%zu", spaces, "", totalSize);
 
     // Report on Chattiest
 
@@ -523,9 +556,7 @@
 
     // Chattiest by application (UID)
     log_id_for_each(id) {
-        if (!(logMask & (1 << id))) {
-            continue;
-        }
+        if (!(logMask & (1 << id))) continue;
 
         name = (uid == AID_ROOT)
             ? "Chattiest UIDs in %s log buffer:"
@@ -539,27 +570,21 @@
             : "Logging for this PID:";
         output += pidTable.format(*this, uid, pid, name);
         name = "Chattiest TIDs";
-        if (pid) {
-            name += android::base::StringPrintf(" for PID %d", pid);
-        }
+        if (pid) name += android::base::StringPrintf(" for PID %d", pid);
         name += ":";
         output += tidTable.format(*this, uid, pid, name);
     }
 
     if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
         name = "Chattiest events log buffer TAGs";
-        if (pid) {
-            name += android::base::StringPrintf(" for PID %d", pid);
-        }
+        if (pid) name += android::base::StringPrintf(" for PID %d", pid);
         name += ":";
         output += tagTable.format(*this, uid, pid, name, LOG_ID_EVENTS);
     }
 
     if (enable && (logMask & (1 << LOG_ID_SECURITY))) {
         name = "Chattiest security log buffer TAGs";
-        if (pid) {
-            name += android::base::StringPrintf(" for PID %d", pid);
-        }
+        if (pid) name += android::base::StringPrintf(" for PID %d", pid);
         name += ":";
         output += securityTagTable.format(*this, uid, pid, name, LOG_ID_SECURITY);
     }