diff --git a/extendedcommands.c b/extendedcommands.c
new file mode 100644
index 0000000..df22448
--- /dev/null
+++ b/extendedcommands.c
@@ -0,0 +1,972 @@
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <limits.h>
+#include <linux/input.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/reboot.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/wait.h>
+#include <sys/limits.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+#include <signal.h>
+#include <sys/wait.h>
+
+#include "bootloader.h"
+#include "common.h"
+#include "cutils/properties.h"
+#include "firmware.h"
+#include "install.h"
+#include "minui/minui.h"
+#include "minzip/DirUtil.h"
+#include "roots.h"
+#include "recovery_ui.h"
+
+#include "../../external/yaffs2/yaffs2/utils/mkyaffs2image.h"
+#include "../../external/yaffs2/yaffs2/utils/unyaffs.h"
+
+#include "extendedcommands.h"
+#include "nandroid.h"
+#include "mounts.h"
+
+int signature_check_enabled = 1;
+int script_assert_enabled = 1;
+static const char *SDCARD_UPDATE_FILE = "/sdcard/update.zip";
+
+void
+toggle_signature_check()
+{
+    signature_check_enabled = !signature_check_enabled;
+    ui_print("Signature Check: %s\n", signature_check_enabled ? "Enabled" : "Disabled");
+}
+
+void toggle_script_asserts()
+{
+    script_assert_enabled = !script_assert_enabled;
+    ui_print("Script Asserts: %s\n", script_assert_enabled ? "Enabled" : "Disabled");
+}
+
+int install_zip(const char* packagefilepath)
+{
+    ui_print("\n-- Installing: %s\n", packagefilepath);
+#ifndef BOARD_HAS_NO_MISC_PARTITION
+    set_sdcard_update_bootloader_message();
+#endif
+    int status = install_package(packagefilepath);
+    ui_reset_progress();
+    if (status != INSTALL_SUCCESS) {
+        ui_set_background(BACKGROUND_ICON_ERROR);
+        ui_print("Installation aborted.\n");
+        return 1;
+    }
+    ui_set_background(BACKGROUND_ICON_NONE);
+    ui_print("\nInstall from sdcard complete.\n");
+    return 0;
+}
+
+char* INSTALL_MENU_ITEMS[] = {  "apply /sdcard/update.zip",
+                                "choose zip from sdcard",
+                                "toggle signature verification",
+                                "toggle script asserts",
+                                NULL };
+#define ITEM_APPLY_SDCARD     0
+#define ITEM_CHOOSE_ZIP       1
+#define ITEM_SIG_CHECK        2
+#define ITEM_ASSERTS          3
+
+void show_install_update_menu()
+{
+    static char* headers[] = {  "Apply update from .zip file on SD card",
+                                "",
+                                NULL
+    };
+    for (;;)
+    {
+        int chosen_item = get_menu_selection(headers, INSTALL_MENU_ITEMS, 0, 0);
+        switch (chosen_item)
+        {
+            case ITEM_ASSERTS:
+                toggle_script_asserts();
+                break;
+            case ITEM_SIG_CHECK:
+                toggle_signature_check();
+                break;
+            case ITEM_APPLY_SDCARD:
+            {
+                if (confirm_selection("Confirm install?", "Yes - Install /sdcard/update.zip"))
+                    install_zip(SDCARD_UPDATE_FILE);
+                break;
+            }
+            case ITEM_CHOOSE_ZIP:
+                show_choose_zip_menu();
+                break;
+            default:
+                return;
+        }
+
+    }
+}
+
+void free_string_array(char** array)
+{
+    if (array == NULL)
+        return;
+    char* cursor = array[0];
+    int i = 0;
+    while (cursor != NULL)
+    {
+        free(cursor);
+        cursor = array[++i];
+    }
+    free(array);
+}
+
+char** gather_files(const char* directory, const char* fileExtensionOrDirectory, int* numFiles)
+{
+    char path[PATH_MAX] = "";
+    DIR *dir;
+    struct dirent *de;
+    int total = 0;
+    int i;
+    char** files = NULL;
+    int pass;
+    *numFiles = 0;
+    int dirLen = strlen(directory);
+
+    dir = opendir(directory);
+    if (dir == NULL) {
+        ui_print("Couldn't open directory.\n");
+        return NULL;
+    }
+
+    int extension_length = 0;
+    if (fileExtensionOrDirectory != NULL)
+        extension_length = strlen(fileExtensionOrDirectory);
+
+    int isCounting = 1;
+    i = 0;
+    for (pass = 0; pass < 2; pass++) {
+        while ((de=readdir(dir)) != NULL) {
+            // skip hidden files
+            if (de->d_name[0] == '.')
+                continue;
+
+            // NULL means that we are gathering directories, so skip this
+            if (fileExtensionOrDirectory != NULL)
+            {
+                // make sure that we can have the desired extension (prevent seg fault)
+                if (strlen(de->d_name) < extension_length)
+                    continue;
+                // compare the extension
+                if (strcmp(de->d_name + strlen(de->d_name) - extension_length, fileExtensionOrDirectory) != 0)
+                    continue;
+            }
+            else
+            {
+                struct stat info;
+                char fullFileName[PATH_MAX];
+                strcpy(fullFileName, directory);
+                strcat(fullFileName, de->d_name);
+                stat(fullFileName, &info);
+                // make sure it is a directory
+                if (!(S_ISDIR(info.st_mode)))
+                    continue;
+            }
+
+            if (pass == 0)
+            {
+                total++;
+                continue;
+            }
+
+            files[i] = (char*) malloc(dirLen + strlen(de->d_name) + 2);
+            strcpy(files[i], directory);
+            strcat(files[i], de->d_name);
+            if (fileExtensionOrDirectory == NULL)
+                strcat(files[i], "/");
+            i++;
+        }
+        if (pass == 1)
+            break;
+        if (total == 0)
+            break;
+        rewinddir(dir);
+        *numFiles = total;
+        files = (char**) malloc((total+1)*sizeof(char*));
+        files[total]=NULL;
+    }
+
+    if(closedir(dir) < 0) {
+        LOGE("Failed to close directory.");
+    }
+
+    if (total==0) {
+        return NULL;
+    }
+
+	// sort the result
+	if (files != NULL) {
+		for (i = 0; i < total; i++) {
+			int curMax = -1;
+			int j;
+			for (j = 0; j < total - i; j++) {
+				if (curMax == -1 || strcmp(files[curMax], files[j]) < 0)
+					curMax = j;
+			}
+			char* temp = files[curMax];
+			files[curMax] = files[total - i - 1];
+			files[total - i - 1] = temp;
+		}
+	}
+
+    return files;
+}
+
+// pass in NULL for fileExtensionOrDirectory and you will get a directory chooser
+char* choose_file_menu(const char* directory, const char* fileExtensionOrDirectory, const char* headers[])
+{
+    char path[PATH_MAX] = "";
+    DIR *dir;
+    struct dirent *de;
+    int numFiles = 0;
+    int numDirs = 0;
+    int i;
+    char* return_value = NULL;
+    int dir_len = strlen(directory);
+
+    char** files = gather_files(directory, fileExtensionOrDirectory, &numFiles);
+    char** dirs = NULL;
+    if (fileExtensionOrDirectory != NULL)
+        dirs = gather_files(directory, NULL, &numDirs);
+    int total = numDirs + numFiles;
+    if (total == 0)
+    {
+        ui_print("No files found.\n");
+    }
+    else
+    {
+        char** list = (char**) malloc((total + 1) * sizeof(char*));
+        list[total] = NULL;
+
+
+        for (i = 0 ; i < numDirs; i++)
+        {
+            list[i] = strdup(dirs[i] + dir_len);
+        }
+
+        for (i = 0 ; i < numFiles; i++)
+        {
+            list[numDirs + i] = strdup(files[i] + dir_len);
+        }
+
+        for (;;)
+        {
+            int chosen_item = get_menu_selection(headers, list, 0, 0);
+            if (chosen_item == GO_BACK)
+                break;
+            static char ret[PATH_MAX];
+            if (chosen_item < numDirs)
+            {
+                char* subret = choose_file_menu(dirs[chosen_item], fileExtensionOrDirectory, headers);
+                if (subret != NULL)
+                {
+                    strcpy(ret, subret);
+                    return_value = ret;
+                    break;
+                }
+                continue;
+            }
+            strcpy(ret, files[chosen_item - numDirs]);
+            return_value = ret;
+            break;
+        }
+        free_string_array(list);
+    }
+
+    free_string_array(files);
+    free_string_array(dirs);
+    return return_value;
+}
+
+void show_choose_zip_menu()
+{
+    if (ensure_path_mounted("/sdcard") != 0) {
+        LOGE ("Can't mount /sdcard\n");
+        return;
+    }
+
+    static char* headers[] = {  "Choose a zip to apply",
+                                "",
+                                NULL
+    };
+
+    char* file = choose_file_menu("/sdcard/", ".zip", headers);
+    if (file == NULL)
+        return;
+    static char* confirm_install  = "Confirm install?";
+    static char confirm[PATH_MAX];
+    sprintf(confirm, "Yes - Install %s", basename(file));
+    if (confirm_selection(confirm_install, confirm))
+        install_zip(file);
+}
+
+void show_nandroid_restore_menu()
+{
+    if (ensure_path_mounted("/sdcard") != 0) {
+        LOGE ("Can't mount /sdcard\n");
+        return;
+    }
+
+    static char* headers[] = {  "Choose an image to restore",
+                                "",
+                                NULL
+    };
+
+    char* file = choose_file_menu("/sdcard/clockworkmod/backup/", NULL, headers);
+    if (file == NULL)
+        return;
+
+    if (confirm_selection("Confirm restore?", "Yes - Restore"))
+        nandroid_restore(file, 1, 1, 1, 1, 1);
+}
+
+void show_mount_usb_storage_menu()
+{
+    char command[PATH_MAX];
+    Volume *vol = volume_for_path("/sdcard");
+    sprintf(command, "echo %s > /sys/devices/platform/usb_mass_storage/lun0/file", vol->device);
+    __system(command);
+    static char* headers[] = {  "USB Mass Storage device",
+                                "Leaving this menu unmount",
+                                "your SD card from your PC.",
+                                "",
+                                NULL
+    };
+
+    static char* list[] = { "Unmount", NULL };
+
+    for (;;)
+    {
+        int chosen_item = get_menu_selection(headers, list, 0, 0);
+        if (chosen_item == GO_BACK || chosen_item == 0)
+            break;
+    }
+
+    __system("echo '' > /sys/devices/platform/usb_mass_storage/lun0/file");
+    __system("echo 0 > /sys/devices/platform/usb_mass_storage/lun0/enable");
+}
+
+int confirm_selection(const char* title, const char* confirm)
+{
+    struct stat info;
+    if (0 == stat("/sdcard/clockworkmod/.no_confirm", &info))
+        return 1;
+
+    char* confirm_headers[]  = {  title, "  THIS CAN NOT BE UNDONE.", "", NULL };
+    char* items[] = { "No",
+                      "No",
+                      "No",
+                      "No",
+                      "No",
+                      "No",
+                      "No",
+                      confirm, //" Yes -- wipe partition",   // [7
+                      "No",
+                      "No",
+                      "No",
+                      NULL };
+
+    int chosen_item = get_menu_selection(confirm_headers, items, 0, 0);
+    return chosen_item == 7;
+}
+
+int format_unknown_device(const char* path)
+{
+    // if this is SDEXT:, don't worry about it.
+    if (0 == strcmp(path, "/sd-ext"))
+    {
+        struct stat st;
+        Volume *vol = volume_for_path("/sd-ext");
+        if (vol == NULL || 0 != stat(vol->device, &st))
+        {
+            ui_print("No app2sd partition found. Skipping format of /sd-ext.\n");
+            return 0;
+        }
+    }
+
+    if (0 != ensure_path_mounted(path))
+    {
+        ui_print("Error mounting %s!\n", path);
+        ui_print("Skipping format...\n");
+        return 0;
+    }
+
+    static char tmp[PATH_MAX];
+    sprintf(tmp, "rm -rf %s/*", path);
+    __system(tmp);
+    sprintf(tmp, "rm -rf %s/.*", path);
+    __system(tmp);
+
+    ensure_path_unmounted(path);
+    return 0;
+}
+
+//#define MOUNTABLE_COUNT 5
+//#define DEVICE_COUNT 4
+//#define MMC_COUNT 2
+
+void show_partition_menu()
+{
+    static char* headers[] = {  "Mounts and Storage Menu",
+                                "",
+                                NULL
+    };
+
+    typedef char* string;
+    string mounts[][3] = {
+        { "mount /system", "unmount /system", "/system" },
+        { "mount /data", "unmount /data", "/data" },
+        { "mount /cache", "unmount /cache", "/cache" },
+        { "mount /sdcard", "unmount /sdcard", "/sdcard:" },
+#ifdef BOARD_HAS_SDCARD_INTERNAL
+        { "mount /emmc", "unmount /emmc", "/emmc" },
+#endif
+        { "mount /sd-ext", "unmount /sd-ext", "/sd-ext" }
+    };
+
+    string devices[][2] = {
+        { "format boot", "boot:" },
+        { "format system", "/system" },
+        { "format data", "/data" },
+        { "format cache", "/cache" },
+        { "format sdcard", "/sdcard" },
+        { "format sd-ext", "/sd-ext" },
+#ifdef BOARD_HAS_SDCARD_INTERNAL
+        { "format internal sdcard", "/emmc" }
+#endif
+    };
+
+    const int MOUNTABLE_COUNT = sizeof(mounts) / sizeof(string) / 3;
+    const int DEVICE_COUNT = sizeof(devices) / sizeof(string) / 2;
+
+    static char* confirm_format  = "Confirm format?";
+    static char* confirm = "Yes - Format";
+
+    for (;;)
+    {
+        int ismounted[MOUNTABLE_COUNT];
+        int i;
+        static string options[MOUNTABLE_COUNT + DEVICE_COUNT + 1 + 1]; // mountables, format mtds, format mmcs, usb storage, null
+        for (i = 0; i < MOUNTABLE_COUNT; i++)
+        {
+            ismounted[i] = is_path_mounted(mounts[i][2]);
+            options[i] = ismounted[i] ? mounts[i][1] : mounts[i][0];
+        }
+
+        for (i = 0; i < DEVICE_COUNT; i++)
+        {
+            options[DEVICE_COUNT + i] = devices[i][0];
+        }
+
+        options[MOUNTABLE_COUNT + DEVICE_COUNT] = "mount USB storage";
+        options[MOUNTABLE_COUNT + DEVICE_COUNT + 1] = NULL;
+
+        int chosen_item = get_menu_selection(headers, options, 0, 0);
+        if (chosen_item == GO_BACK)
+            break;
+        if (chosen_item == MOUNTABLE_COUNT + DEVICE_COUNT)
+        {
+            show_mount_usb_storage_menu();
+        }
+        else if (chosen_item < MOUNTABLE_COUNT)
+        {
+            if (ismounted[chosen_item])
+            {
+                if (0 != ensure_path_unmounted(mounts[chosen_item][2]))
+                    ui_print("Error unmounting %s!\n", mounts[chosen_item][2]);
+            }
+            else
+            {
+                if (0 != ensure_path_mounted(mounts[chosen_item][2]))
+                    ui_print("Error mounting %s!\n", mounts[chosen_item][2]);
+            }
+        }
+        else if (chosen_item < MOUNTABLE_COUNT + DEVICE_COUNT)
+        {
+            chosen_item = chosen_item - MOUNTABLE_COUNT;
+            if (!confirm_selection(confirm_format, confirm))
+                continue;
+            ui_print("Formatting %s...\n", devices[chosen_item][1]);
+            if (0 != format_device(devices[chosen_item][1]))
+                ui_print("Error formatting %s!\n", devices[chosen_item][1]);
+            else
+                ui_print("Done.\n");
+        }
+    }
+}
+
+#define EXTENDEDCOMMAND_SCRIPT "/cache/recovery/extendedcommand"
+
+int extendedcommand_file_exists()
+{
+    struct stat file_info;
+    return 0 == stat(EXTENDEDCOMMAND_SCRIPT, &file_info);
+}
+
+int run_script_from_buffer(char* script_data, int script_len, char* filename)
+{
+    ui_print("not yet implemented.\n");
+    return -1;
+
+    /*
+    const AmCommandList *commands = parseAmendScript(script_data, script_len);
+    if (commands == NULL) {
+        printf("Syntax error in update script\n");
+        return 1;
+    } else {
+        printf("Parsed %.*s\n", script_len, filename);
+    }
+
+    int ret = execCommandList((ExecContext *)1, commands);
+    if (ret != 0) {
+        int num = ret;
+        char *line = NULL, *next = script_data;
+        while (next != NULL && ret-- > 0) {
+            line = next;
+            next = memchr(line, '\n', script_data + script_len - line);
+            if (next != NULL) *next++ = '\0';
+        }
+        printf("Failure at line %d:\n%s\n", num, next ? line : "(not found)");
+        return 1;
+    }
+    */
+}
+
+int run_script(char* filename)
+{
+    struct stat file_info;
+    if (0 != stat(filename, &file_info)) {
+        printf("Error executing stat on file: %s\n", filename);
+        return 1;
+    }
+
+    int script_len = file_info.st_size;
+    char* script_data = (char*)malloc(script_len + 1);
+    FILE *file = fopen(filename, "rb");
+    fread(script_data, script_len, 1, file);
+    // supposedly not necessary, but let's be safe.
+    script_data[script_len] = '\0';
+    fclose(file);
+    LOGI("Running script:\n");
+    LOGI("\n%s\n", script_data);
+
+    int ret = run_script_from_buffer(script_data, script_len, filename);
+    free(script_data);
+    return ret;
+}
+
+int run_and_remove_extendedcommand()
+{
+    char tmp[PATH_MAX];
+    sprintf(tmp, "cp %s /tmp/%s", EXTENDEDCOMMAND_SCRIPT, basename(EXTENDEDCOMMAND_SCRIPT));
+    __system(tmp);
+    remove(EXTENDEDCOMMAND_SCRIPT);
+    int i = 0;
+    for (i = 20; i > 0; i--) {
+        ui_print("Waiting for SD Card to mount (%ds)\n", i);
+        if (ensure_path_mounted("/sdcard") == 0) {
+            ui_print("SD Card mounted...\n");
+            break;
+        }
+        sleep(1);
+    }
+    remove("/sdcard/clockworkmod/.recoverycheckpoint");
+    if (i == 0) {
+        ui_print("Timed out waiting for SD card... continuing anyways.");
+    }
+
+    sprintf(tmp, "/tmp/%s", basename(EXTENDEDCOMMAND_SCRIPT));
+    return run_script(tmp);
+}
+
+void show_nandroid_advanced_restore_menu()
+{
+    if (ensure_path_mounted("/sdcard") != 0) {
+        LOGE ("Can't mount /sdcard\n");
+        return;
+    }
+
+    static char* advancedheaders[] = {  "Choose an image to restore",
+                                "",
+                                "Choose an image to restore",
+                                "first. The next menu will",
+                                "you more options.",
+                                "",
+                                NULL
+    };
+
+    char* file = choose_file_menu("/sdcard/clockworkmod/backup/", NULL, advancedheaders);
+    if (file == NULL)
+        return;
+
+    static char* headers[] = {  "Nandroid Advanced Restore",
+                                "",
+                                NULL
+    };
+
+    static char* list[] = { "Restore boot",
+                            "Restore system",
+                            "Restore data",
+                            "Restore cache",
+                            "Restore sd-ext",
+                            NULL
+    };
+
+
+    static char* confirm_restore  = "Confirm restore?";
+
+    int chosen_item = get_menu_selection(headers, list, 0, 0);
+    switch (chosen_item)
+    {
+        case 0:
+            if (confirm_selection(confirm_restore, "Yes - Restore boot"))
+                nandroid_restore(file, 1, 0, 0, 0, 0);
+            break;
+        case 1:
+            if (confirm_selection(confirm_restore, "Yes - Restore system"))
+                nandroid_restore(file, 0, 1, 0, 0, 0);
+            break;
+        case 2:
+            if (confirm_selection(confirm_restore, "Yes - Restore data"))
+                nandroid_restore(file, 0, 0, 1, 0, 0);
+            break;
+        case 3:
+            if (confirm_selection(confirm_restore, "Yes - Restore cache"))
+                nandroid_restore(file, 0, 0, 0, 1, 0);
+            break;
+        case 4:
+            if (confirm_selection(confirm_restore, "Yes - Restore sd-ext"))
+                nandroid_restore(file, 0, 0, 0, 0, 1);
+            break;
+    }
+}
+
+void show_nandroid_menu()
+{
+    static char* headers[] = {  "Nandroid",
+                                "",
+                                NULL
+    };
+
+    static char* list[] = { "Backup",
+                            "Restore",
+                            "Advanced Restore",
+                            NULL
+    };
+
+    int chosen_item = get_menu_selection(headers, list, 0, 0);
+    switch (chosen_item)
+    {
+        case 0:
+            {
+                char backup_path[PATH_MAX];
+                time_t t = time(NULL);
+                struct tm *tmp = localtime(&t);
+                if (tmp == NULL)
+                {
+                    struct timeval tp;
+                    gettimeofday(&tp, NULL);
+                    sprintf(backup_path, "/sdcard/clockworkmod/backup/%d", tp.tv_sec);
+                }
+                else
+                {
+                    strftime(backup_path, sizeof(backup_path), "/sdcard/clockworkmod/backup/%F.%H.%M.%S", tmp);
+                }
+                nandroid_backup(backup_path);
+            }
+            break;
+        case 1:
+            show_nandroid_restore_menu();
+            break;
+        case 2:
+            show_nandroid_advanced_restore_menu();
+            break;
+    }
+}
+
+void wipe_battery_stats()
+{
+    ensure_path_mounted("/data");
+    remove("/data/system/batterystats.bin");
+    ensure_path_unmounted("/data");
+}
+
+void show_advanced_menu()
+{
+    static char* headers[] = {  "Advanced and Debugging Menu",
+                                "",
+                                NULL
+    };
+
+    static char* list[] = { "Reboot Recovery",
+                            "Wipe Dalvik Cache",
+                            "Wipe Battery Stats",
+                            "Report Error",
+                            "Key Test",
+#ifndef BOARD_HAS_SMALL_RECOVERY
+                            "Partition SD Card",
+                            "Fix Permissions",
+#ifdef BOARD_HAS_SDCARD_INTERNAL
+                            "Partition Internal SD Card",
+#endif
+#endif
+                            NULL
+    };
+
+    for (;;)
+    {
+        int chosen_item = get_menu_selection(headers, list, 0, 0);
+        if (chosen_item == GO_BACK)
+            break;
+        switch (chosen_item)
+        {
+            case 0:
+                __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, "recovery");
+                break;
+            case 1:
+            {
+                if (0 != ensure_path_mounted("/data"))
+                    break;
+                ensure_path_mounted("/sd-ext");
+                ensure_path_mounted("/cache");
+                if (confirm_selection( "Confirm wipe?", "Yes - Wipe Dalvik Cache")) {
+                    __system("rm -r /data/dalvik-cache");
+                    __system("rm -r /cache/dalvik-cache");
+                    __system("rm -r /sd-ext/dalvik-cache");
+                }
+                ensure_path_unmounted("/data");
+                ui_print("Dalvik Cache wiped.\n");
+                break;
+            }
+            case 2:
+            {
+                if (confirm_selection( "Confirm wipe?", "Yes - Wipe Battery Stats"))
+                    wipe_battery_stats();
+                break;
+            }
+            case 3:
+                handle_failure(1);
+                break;
+            case 4:
+            {
+                ui_print("Outputting key codes.\n");
+                ui_print("Go back to end debugging.\n");
+                int key;
+                int action;
+                do
+                {
+                    key = ui_wait_key();
+                    action = device_handle_key(key, 1);
+                    ui_print("Key: %d\n", key);
+                }
+                while (action != GO_BACK);
+                break;
+            }
+            case 5:
+            {
+                static char* ext_sizes[] = { "128M",
+                                             "256M",
+                                             "512M",
+                                             "1024M",
+                                             "2048M",
+                                             "4096M",
+                                             NULL };
+
+                static char* swap_sizes[] = { "0M",
+                                              "32M",
+                                              "64M",
+                                              "128M",
+                                              "256M",
+                                              NULL };
+
+                static char* ext_headers[] = { "Ext Size", "", NULL };
+                static char* swap_headers[] = { "Swap Size", "", NULL };
+
+                int ext_size = get_menu_selection(ext_headers, ext_sizes, 0, 0);
+                if (ext_size == GO_BACK)
+                    continue;
+
+                int swap_size = get_menu_selection(swap_headers, swap_sizes, 0, 0);
+                if (swap_size == GO_BACK)
+                    continue;
+
+                char sddevice[256];
+                Volume *vol = volume_for_path("/sdcard");
+                strcpy(sddevice, vol->device);
+                // we only want the mmcblk, not the partition
+                sddevice[strlen("/dev/block/mmcblkX")] = NULL;
+                char cmd[PATH_MAX];
+                setenv("SDPATH", sddevice, 1);
+                sprintf(cmd, "sdparted -es %s -ss %s -efs ext3 -s", ext_sizes[ext_size], swap_sizes[swap_size]);
+                ui_print("Partitioning SD Card... please wait...\n");
+                if (0 == __system(cmd))
+                    ui_print("Done!\n");
+                else
+                    ui_print("An error occured while partitioning your SD Card. Please see /tmp/recovery.log for more details.\n");
+                break;
+            }
+            case 6:
+            {
+                ensure_path_mounted("/system");
+                ensure_path_mounted("/data");
+                ui_print("Fixing permissions...\n");
+                __system("fix_permissions");
+                ui_print("Done!\n");
+                break;
+            }
+            case 7:
+            {
+                static char* ext_sizes[] = { "128M",
+                                             "256M",
+                                             "512M",
+                                             "1024M",
+                                             "2048M",
+                                             "4096M",
+                                             NULL };
+
+                static char* swap_sizes[] = { "0M",
+                                              "32M",
+                                              "64M",
+                                              "128M",
+                                              "256M",
+                                              NULL };
+
+                static char* ext_headers[] = { "Data Size", "", NULL };
+                static char* swap_headers[] = { "Swap Size", "", NULL };
+
+                int ext_size = get_menu_selection(ext_headers, ext_sizes, 0, 0);
+                if (ext_size == GO_BACK)
+                    continue;
+
+                int swap_size = 0;
+                if (swap_size == GO_BACK)
+                    continue;
+
+                char sddevice[256];
+                Volume *vol = volume_for_path("/emmc");
+                strcpy(sddevice, vol->device);
+                // we only want the mmcblk, not the partition
+                sddevice[strlen("/dev/block/mmcblkX")] = NULL;
+                char cmd[PATH_MAX];
+                setenv("SDPATH", sddevice, 1);
+                sprintf(cmd, "sdparted -es %s -ss %s -efs ext3 -s", ext_sizes[ext_size], swap_sizes[swap_size]);
+                ui_print("Partitioning Internal SD Card... please wait...\n");
+                if (0 == __system(cmd))
+                    ui_print("Done!\n");
+                else
+                    ui_print("An error occured while partitioning your Internal SD Card. Please see /tmp/recovery.log for more details.\n");
+                break;
+            }
+        }
+    }
+}
+
+/*
+void write_fstab_root(char *root_path, FILE *file)
+{
+    RootInfo *info = get_root_info_for_path(root_path);
+    if (info == NULL) {
+        LOGW("Unable to get root info for %s during fstab generation!", root_path);
+        return;
+    }
+    char device[PATH_MAX];
+    int ret = get_root_partition_device(root_path, device);
+    if (ret == 0)
+    {
+        fprintf(file, "%s ", device);
+    }
+    else
+    {
+        fprintf(file, "%s ", info->device);
+    }
+
+    fprintf(file, "%s ", info->mount_point);
+    fprintf(file, "%s %s\n", info->filesystem, info->filesystem_options == NULL ? "rw" : info->filesystem_options);
+}
+
+void create_fstab()
+{
+    __system("touch /etc/mtab");
+    FILE *file = fopen("/etc/fstab", "w");
+    if (file == NULL) {
+        LOGW("Unable to create /etc/fstab!");
+        return;
+    }
+    write_fstab_root("CACHE:", file);
+    write_fstab_root("DATA:", file);
+#ifdef BOARD_HAS_DATADATA
+    write_fstab_root("DATADATA:", file);
+#endif
+    write_fstab_root("SYSTEM:", file);
+    write_fstab_root("SDCARD:", file);
+    write_fstab_root("SDEXT:", file);
+    fclose(file);
+}
+*/
+
+void handle_failure(int ret)
+{
+    if (ret == 0)
+        return;
+    if (0 != ensure_path_mounted("/sdcard"))
+        return;
+    mkdir("/sdcard/clockworkmod", S_IRWXU);
+    __system("cp /tmp/recovery.log /sdcard/clockworkmod/recovery.log");
+    ui_print("/tmp/recovery.log was copied to /sdcard/clockworkmod/recovery.log. Please open ROM Manager to report the issue.\n");
+}
+
+int format_device(const char* device) {
+    if (device == NULL)
+        return -1;
+    if (device[0] == '/') {
+        Volume *vol = volume_for_path(device);
+        if (vol == NULL)
+            return -1;
+        return erase_partition(device, vol->fs_type);
+    }
+    return erase_raw_partition(device);
+}
+
+int is_path_mounted(const char* path) {
+    Volume* v = volume_for_path(path);
+    if (v == NULL) {
+        return 0;
+    }
+    if (strcmp(v->fs_type, "ramdisk") == 0) {
+        // the ramdisk is always mounted.
+        return 1;
+    }
+
+    int result;
+    result = scan_mounted_volumes();
+    if (result < 0) {
+        LOGE("failed to scan mounted volumes\n");
+        return 0;
+    }
+
+    const MountedVolume* mv =
+        find_mounted_volume_by_mount_point(v->mount_point);
+    if (mv) {
+        // volume is already mounted
+        return 1;
+    }
+    return 0;
+}
