Exemplo n.º 1
0
static void cmd_gpt_layout(struct protocol_handle *phandle, const char *arg) {
    struct GPT_entry_table *oldtable;
    int location;
    struct GPT_content content;
    const char *device;
    device = fastboot_getvar("blockdev");

    if (!strcmp(device, "")) {
        fastboot_fail(phandle, "blockdev not defined in config file");
        return;
    }

    //TODO: add same verification as in cmd_flash
    if (phandle->download_fd < 0) {
        fastboot_fail(phandle, "no layout file");
        return;
    }

    location = GPT_header_location();
    oldtable = GPT_get_device(device, location);

    GPT_default_content(&content, oldtable);
    if (oldtable == NULL)
        D(WARN, "Could not get old gpt table");
    else
        GPT_release_device(oldtable);

    if (!GPT_parse_file(phandle->download_fd, &content)) {
        fastboot_fail(phandle, "Could not parse partition config file");
        return;
    }

    if (trigger_gpt_layout(&content)) {
        fastboot_fail(phandle, "Vendor forbids this opperation");
        GPT_release_content(&content);
        return;
    }

    if (!GPT_write_content(device, &content)) {
        fastboot_fail(phandle, "Unable to write gpt file");
        GPT_release_content(&content);
        return;
    }

    GPT_release_content(&content);
    fastboot_okay(phandle, "");
}
int main(int argc, char *argv[]) {
    int print_cmd = 0;
    int config_cmd = 0;
    int add_cmd = 0;
    int del_cmd = 0;
    int sync_cmd = 0;
    int c;
    const char *new_partition = NULL;
    const char *old_partition = NULL;
    const char *type_guid = NULL;
    const char *partition_guid = NULL;
    unsigned gpt_location = 1;

    klog_init();
    klog_set_level(6);

    const struct option longopts[] = {
        {"print", no_argument, 0, 'p'},
        {"config-print", no_argument, 0, 'c'},
        {"add", no_argument, 0, 'a'},
        {"del", no_argument, 0, 'd'},
        {"new", required_argument, 0, 'n'},
        {"old", required_argument, 0, 'o'},
        {"type", required_argument, 0, 't'},
        {"sync", required_argument, 0, 's'},
        {"guid", required_argument, 0, 'g'},
        {"location", required_argument, 0, 'l'},
        {0, 0, 0, 0}
    };

    while (1) {
        c = getopt_long(argc, argv, "pcadt:g:n:o:sl:", longopts, NULL);
        /* Alphabetical cases */
        if (c < 0)
            break;
        switch (c) {
        case 'p':
            print_cmd = 1;
            break;
        case 'c':
            config_cmd = 1;
            break;
        case 'a':
            add_cmd = 1;
            break;
        case 'd':
            del_cmd = 1;
            break;
        case 'n':
            new_partition = optarg;
            break;
        case 'o':
            old_partition = optarg;
            break;
        case 't':
            type_guid = optarg;
        case 'g':
            partition_guid = optarg;
            break;
        case 's':
            sync_cmd = 1;
            break;
        case 'l':
            gpt_location = strtoul(optarg, NULL, 10);
            fprintf(stderr, "Got offset as %d", gpt_location);
            break;
        case '?':
            return 1;
        default:
            abort();
        }
    }

    argc -= optind;
    argv += optind;

    if (argc < 1) {
        usage();
        return 1;
    }

    const char *path = argv[0];
    struct GPT_entry_table *table = GPT_get_device(path, gpt_location);
    if (table == NULL) {
        fprintf(stderr, "unable to get GPT table from %s\n", path);
        return 1;
    }

    if (add_cmd)
        addGPT(table, new_partition, partition_guid, type_guid);
    if (del_cmd)
        deleteGPT(table, old_partition);
    if (print_cmd)
        printGPT(table);
    if (config_cmd)
        configPrintGPT(table);
    if (sync_cmd)
        GPT_sync(table);

    GPT_release_device(table);

    return 0;
}