TWRP-ify AOSP code

Pull in most TWRP sources
Stub out partition management code
Make it compile -- probably will not boot
Kind of a mess but have to start somewhere
diff --git a/mounts.c b/mounts.c
new file mode 100644
index 0000000..e8b69e8
--- /dev/null
+++ b/mounts.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mount.h>
+
+#include "mounts.h"
+
+typedef struct {
+    MountedVolume *volumes;
+    int volumes_allocd;
+    int volume_count;
+} MountsState;
+
+static MountsState g_mounts_state = {
+    NULL,   // volumes
+    0,      // volumes_allocd
+    0       // volume_count
+};
+
+static inline void
+free_volume_internals(const MountedVolume *volume, int zero)
+{
+    free((char *)volume->device);
+    free((char *)volume->mount_point);
+    free((char *)volume->filesystem);
+    free((char *)volume->flags);
+    if (zero) {
+        memset((void *)volume, 0, sizeof(*volume));
+    }
+}
+
+#define PROC_MOUNTS_FILENAME   "/proc/mounts"
+
+int
+scan_mounted_volumes()
+{
+    char buf[2048];
+    const char *bufp;
+    int fd;
+    ssize_t nbytes;
+
+    if (g_mounts_state.volumes == NULL) {
+        const int numv = 32;
+        MountedVolume *volumes = malloc(numv * sizeof(*volumes));
+        if (volumes == NULL) {
+            errno = ENOMEM;
+            return -1;
+        }
+        g_mounts_state.volumes = volumes;
+        g_mounts_state.volumes_allocd = numv;
+        memset(volumes, 0, numv * sizeof(*volumes));
+    } else {
+        /* Free the old volume strings.
+         */
+        int i;
+        for (i = 0; i < g_mounts_state.volume_count; i++) {
+            free_volume_internals(&g_mounts_state.volumes[i], 1);
+        }
+    }
+    g_mounts_state.volume_count = 0;
+
+    /* Open and read the file contents.
+     */
+    fd = open(PROC_MOUNTS_FILENAME, O_RDONLY);
+    if (fd < 0) {
+        goto bail;
+    }
+    nbytes = read(fd, buf, sizeof(buf) - 1);
+    close(fd);
+    if (nbytes < 0) {
+        goto bail;
+    }
+    buf[nbytes] = '\0';
+
+    /* Parse the contents of the file, which looks like:
+     *
+     *     # cat /proc/mounts
+     *     rootfs / rootfs rw 0 0
+     *     /dev/pts /dev/pts devpts rw 0 0
+     *     /proc /proc proc rw 0 0
+     *     /sys /sys sysfs rw 0 0
+     *     /dev/block/mtdblock4 /system yaffs2 rw,nodev,noatime,nodiratime 0 0
+     *     /dev/block/mtdblock5 /data yaffs2 rw,nodev,noatime,nodiratime 0 0
+     *     /dev/block/mmcblk0p1 /sdcard vfat rw,sync,dirsync,fmask=0000,dmask=0000,codepage=cp437,iocharset=iso8859-1,utf8 0 0
+     *
+     * The zeroes at the end are dummy placeholder fields to make the
+     * output match Linux's /etc/mtab, but don't represent anything here.
+     */
+    bufp = buf;
+    while (nbytes > 0) {
+        char device[64];
+        char mount_point[64];
+        char filesystem[64];
+        char flags[128];
+        int matches;
+
+        /* %as is a gnu extension that malloc()s a string for each field.
+         */
+        matches = sscanf(bufp, "%63s %63s %63s %127s",
+                device, mount_point, filesystem, flags);
+
+        if (matches == 4) {
+            device[sizeof(device)-1] = '\0';
+            mount_point[sizeof(mount_point)-1] = '\0';
+            filesystem[sizeof(filesystem)-1] = '\0';
+            flags[sizeof(flags)-1] = '\0';
+
+            MountedVolume *v =
+                    &g_mounts_state.volumes[g_mounts_state.volume_count++];
+            v->device = strdup(device);
+            v->mount_point = strdup(mount_point);
+            v->filesystem = strdup(filesystem);
+            v->flags = strdup(flags);
+        } else {
+printf("matches was %d on <<%.40s>>\n", matches, bufp);
+        }
+
+        /* Eat the line.
+         */
+        while (nbytes > 0 && *bufp != '\n') {
+            bufp++;
+            nbytes--;
+        }
+        if (nbytes > 0) {
+            bufp++;
+            nbytes--;
+        }
+    }
+
+    return 0;
+
+bail:
+//TODO: free the strings we've allocated.
+    g_mounts_state.volume_count = 0;
+    return -1;
+}
+
+const MountedVolume *
+find_mounted_volume_by_device(const char *device)
+{
+    if (g_mounts_state.volumes != NULL) {
+        int i;
+        for (i = 0; i < g_mounts_state.volume_count; i++) {
+            MountedVolume *v = &g_mounts_state.volumes[i];
+            /* May be null if it was unmounted and we haven't rescanned.
+             */
+            if (v->device != NULL) {
+                if (strcmp(v->device, device) == 0) {
+                    return v;
+                }
+            }
+        }
+    }
+    return NULL;
+}
+
+const MountedVolume *
+find_mounted_volume_by_mount_point(const char *mount_point)
+{
+    if (g_mounts_state.volumes != NULL) {
+        int i;
+        for (i = 0; i < g_mounts_state.volume_count; i++) {
+            MountedVolume *v = &g_mounts_state.volumes[i];
+            /* May be null if it was unmounted and we haven't rescanned.
+             */
+            if (v->mount_point != NULL) {
+                if (strcmp(v->mount_point, mount_point) == 0) {
+                    return v;
+                }
+            }
+        }
+    }
+    return NULL;
+}
+
+int
+unmount_mounted_volume(const MountedVolume *volume)
+{
+    /* Intentionally pass NULL to umount if the caller tries
+     * to unmount a volume they already unmounted using this
+     * function.
+     */
+    int ret = umount(volume->mount_point);
+    if (ret == 0) {
+        free_volume_internals(volume, 1);
+        return 0;
+    }
+    return ret;
+}
+
+int
+remount_read_only(const MountedVolume* volume)
+{
+    return mount(volume->device, volume->mount_point, volume->filesystem,
+                 MS_NOATIME | MS_NODEV | MS_NODIRATIME |
+                 MS_RDONLY | MS_REMOUNT, 0);
+}