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; }