int main(int argc, char **argv) { int wants_wipe = 0; int wants_reboot = 0; int wants_reboot_bootloader = 0; int erase_first = 1; void *data; unsigned sz; int status; int c; int longindex; const struct option longopts[] = { {"base", required_argument, 0, 'b'}, {"kernel_offset", required_argument, 0, 'k'}, {"page_size", required_argument, 0, 'n'}, {"ramdisk_offset", required_argument, 0, 'r'}, {"tags_offset", required_argument, 0, 't'}, {"help", no_argument, 0, 'h'}, {"unbuffered", no_argument, 0, 0}, {"version", no_argument, 0, 0}, {0, 0, 0, 0} }; serial = getenv("ANDROID_SERIAL"); while (1) { c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:h", longopts, &longindex); if (c < 0) { break; } /* Alphabetical cases */ switch (c) { case 'b': base_addr = strtoul(optarg, 0, 16); break; case 'c': cmdline = optarg; break; case 'h': usage(); return 1; case 'i': { char *endptr = NULL; unsigned long val; val = strtoul(optarg, &endptr, 0); if (!endptr || *endptr != '\0' || (val & ~0xffff)) die("invalid vendor id '%s'", optarg); vendor_id = (unsigned short)val; break; } case 'k': kernel_offset = strtoul(optarg, 0, 16); break; case 'l': long_listing = 1; break; case 'n': page_size = (unsigned)strtoul(optarg, NULL, 0); if (!page_size) die("invalid page size"); break; case 'p': product = optarg; break; case 'r': ramdisk_offset = strtoul(optarg, 0, 16); break; case 't': tags_offset = strtoul(optarg, 0, 16); break; case 's': serial = optarg; break; case 'S': sparse_limit = parse_num(optarg); if (sparse_limit < 0) { die("invalid sparse limit"); } break; case 'u': erase_first = 0; break; case 'w': wants_wipe = 1; break; case '?': return 1; case 0: if (strcmp("unbuffered", longopts[longindex].name) == 0) { setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); } else if (strcmp("version", longopts[longindex].name) == 0) { fprintf(stdout, "fastboot version %s\n", FASTBOOT_REVISION); return 0; } break; default: abort(); } } argc -= optind; argv += optind; if (argc == 0 && !wants_wipe) { usage(); return 1; } if (argc > 0 && !strcmp(*argv, "devices")) { skip(1); list_devices(); return 0; } if (argc > 0 && !strcmp(*argv, "help")) { usage(); return 0; } usb_handle* usb = open_device(); while (argc > 0) { if(!strcmp(*argv, "getvar")) { require(2); fb_queue_display(argv[1], argv[1]); skip(2); } else if(!strcmp(*argv, "erase")) { require(2); if (fb_format_supported(usb, argv[1], NULL)) { fprintf(stderr, "******** Did you mean to fastboot format this partition?\n"); } fb_queue_erase(argv[1]); skip(2); } else if(!strncmp(*argv, "format", strlen("format"))) { char *overrides; char *type_override = NULL; char *size_override = NULL; require(2); /* * Parsing for: "format[:[type][:[size]]]" * Some valid things: * - select ontly the size, and leave default fs type: * format::0x4000000 userdata * - default fs type and size: * format userdata * format:: userdata */ overrides = strchr(*argv, ':'); if (overrides) { overrides++; size_override = strchr(overrides, ':'); if (size_override) { size_override[0] = '\0'; size_override++; } type_override = overrides; } if (type_override && !type_override[0]) type_override = NULL; if (size_override && !size_override[0]) size_override = NULL; if (erase_first && needs_erase(usb, argv[1])) { fb_queue_erase(argv[1]); } fb_perform_format(usb, argv[1], 0, type_override, size_override); skip(2); } else if(!strcmp(*argv, "signature")) { require(2); data = load_file(argv[1], &sz); if (data == 0) die("could not load '%s': %s", argv[1], strerror(errno)); if (sz != 256) die("signature must be 256 bytes"); fb_queue_download("signature", data, sz); fb_queue_command("signature", "installing signature"); skip(2); } else if(!strcmp(*argv, "reboot")) { wants_reboot = 1; skip(1); if (argc > 0) { if (!strcmp(*argv, "bootloader")) { wants_reboot = 0; wants_reboot_bootloader = 1; skip(1); } } require(0); } else if(!strcmp(*argv, "reboot-bootloader")) { wants_reboot_bootloader = 1; skip(1); } else if (!strcmp(*argv, "continue")) { fb_queue_command("continue", "resuming boot"); skip(1); } else if(!strcmp(*argv, "boot")) { char *kname = 0; char *rname = 0; skip(1); if (argc > 0) { kname = argv[0]; skip(1); } if (argc > 0) { rname = argv[0]; skip(1); } data = load_bootable_image(kname, rname, &sz, cmdline); if (data == 0) return 1; fb_queue_download("boot.img", data, sz); fb_queue_command("boot", "booting"); } else if(!strcmp(*argv, "flash")) { char *pname = argv[1]; char *fname = 0; require(2); if (argc > 2) { fname = argv[2]; skip(3); } else { fname = find_item(pname, product); skip(2); } if (fname == 0) die("cannot determine image filename for '%s'", pname); if (erase_first && needs_erase(usb, pname)) { fb_queue_erase(pname); } do_flash(usb, pname, fname); } else if(!strcmp(*argv, "flash:raw")) { char *pname = argv[1]; char *kname = argv[2]; char *rname = 0; require(3); if(argc > 3) { rname = argv[3]; skip(4); } else { skip(3); } data = load_bootable_image(kname, rname, &sz, cmdline); if (data == 0) die("cannot load bootable image"); fb_queue_flash(pname, data, sz); } else if(!strcmp(*argv, "flashall")) { skip(1); do_flashall(usb, erase_first); wants_reboot = 1; } else if(!strcmp(*argv, "update")) { if (argc > 1) { do_update(usb, argv[1], erase_first); skip(2); } else { do_update(usb, "update.zip", erase_first); skip(1); } wants_reboot = 1; } else if(!strcmp(*argv, "oem")) { argc = do_oem_command(argc, argv); } else if(!strcmp(*argv, "flashing") && argc == 2) { if(!strcmp(*(argv+1), "unlock") || !strcmp(*(argv+1), "lock") || !strcmp(*(argv+1), "unlock_critical") || !strcmp(*(argv+1), "lock_critical") || !strcmp(*(argv+1), "get_unlock_ability")) { argc = do_oem_command(argc, argv); } else { usage(); return 1; } } else { usage(); return 1; } } if (wants_wipe) { fb_queue_erase("userdata"); fb_perform_format(usb, "userdata", 1, NULL, NULL); fb_queue_erase("cache"); fb_perform_format(usb, "cache", 1, NULL, NULL); } if (wants_reboot) { fb_queue_reboot(); fb_queue_wait_for_disconnect(); } else if (wants_reboot_bootloader) { fb_queue_command("reboot-bootloader", "rebooting into bootloader"); fb_queue_wait_for_disconnect(); } if (fb_queue_is_empty()) return 0; status = fb_execute_queue(usb); return (status) ? 1 : 0; }
int main(int argc, char **argv) { int wants_wipe = 0; int wants_reboot = 0; int wants_reboot_bootloader = 0; int erase_first = 1; void *data; unsigned sz; unsigned page_size = 2048; int status; int c; int r; const struct option longopts = { 0, 0, 0, 0 }; serial = getenv("ANDROID_SERIAL"); while (1) { c = getopt_long(argc, argv, "wub:n:s:S:lp:c:i:m:ht:", &longopts, NULL); if (c < 0) { break; } switch (c) { case 'w': wants_wipe = 1; break; case 'u': erase_first = 0; break; case 'b': base_addr = strtoul(optarg, 0, 16); break; case 'n': page_size = (unsigned)strtoul(optarg, NULL, 0); if (!page_size) die("invalid page size"); break; case 's': serial = optarg; break; case 'S': sparse_limit = parse_num(optarg); if (sparse_limit < 0) { die("invalid sparse limit"); } break; case 'l': long_listing = 1; break; case 'p': product = optarg; break; case 'c': cmdline = optarg; break; case 'i': { char *endptr = NULL; unsigned long val; val = strtoul(optarg, &endptr, 0); if (!endptr || *endptr != '\0' || (val & ~0xffff)) die("invalid vendor id '%s'", optarg); vendor_id = (unsigned short)val; break; } case 't': host = optarg; break; case 'h': usage(); return 1; case '?': return 1; default: abort(); } } argc -= optind; argv += optind; if (argc == 0 && !wants_wipe) { usage(); return 1; } if (argc > 0 && !strcmp(*argv, "devices")) { skip(1); list_devices(); return 0; } if (argc > 0 && !strcmp(*argv, "help")) { usage(); return 0; } if(host) { transport.userdata = open_device_tcp(); transport.close = tcp_close; transport.read = tcp_read; transport.write = tcp_write; } else { transport.userdata = open_device(); transport.close = usb_close; transport.read = usb_read; transport.write = usb_write; } while (argc > 0) { if(!strcmp(*argv, "getvar")) { require(2); fb_queue_display(argv[1], argv[1]); skip(2); } else if(!strcmp(*argv, "erase")) { require(2); fb_queue_erase(argv[1]); skip(2); } else if(!strcmp(*argv, "format")) { require(2); fb_queue_format(argv[1], 0); skip(2); } else if(!strcmp(*argv, "signature")) { require(2); data = load_file(argv[1], &sz); if (data == 0) die("could not load '%s': %s", argv[1], strerror(errno)); if (sz != 256) die("signature must be 256 bytes"); fb_queue_download("signature", data, sz); fb_queue_command("signature", "installing signature"); skip(2); } else if(!strcmp(*argv, "reboot")) { wants_reboot = 1; skip(1); } else if(!strcmp(*argv, "reboot-bootloader")) { wants_reboot_bootloader = 1; skip(1); } else if (!strcmp(*argv, "continue")) { fb_queue_command("continue", "resuming boot"); skip(1); } else if(!strcmp(*argv, "boot")) { char *kname = 0; char *rname = 0; skip(1); if (argc > 0) { kname = argv[0]; skip(1); } if (argc > 0) { rname = argv[0]; skip(1); } data = load_bootable_image(page_size, kname, rname, &sz, cmdline); if (data == 0) return 1; fb_queue_download("boot.img", data, sz); fb_queue_command("boot", "booting"); } else if(!strcmp(*argv, "flash")) { char *pname = argv[1]; char *fname = 0; require(2); if (argc > 2) { fname = argv[2]; skip(3); } else { fname = find_item(pname, product); skip(2); } if (fname == 0) die("cannot determine image filename for '%s'", pname); if (erase_first && needs_erase(pname)) { fb_queue_erase(pname); } data = load_file(fname, &sz); if (data == 0) die("cannot load '%s': %s\n", fname, strerror(errno)); fb_queue_flash(pname, data, sz); } else if(!strcmp(*argv, "flash:raw")) { char *pname = argv[1]; char *kname = argv[2]; char *rname = 0; require(3); if(argc > 3) { rname = argv[3]; skip(4); } else { skip(3); } data = load_bootable_image(page_size, kname, rname, &sz, cmdline); if (data == 0) die("cannot load bootable image"); fb_queue_flash(pname, data, sz); } else if(!strcmp(*argv, "flashall")) { skip(1); do_flashall(erase_first); wants_reboot = 1; } else if(!strcmp(*argv, "update")) { if (argc > 1) { do_update(argv[1], erase_first); skip(2); } else { do_update("update.zip", erase_first); skip(1); } wants_reboot = 1; } else if(!strcmp(*argv, "oem")) { argc = do_oem_command(argc, argv); } else { usage(); return 1; } } if (wants_wipe) { fb_queue_erase("userdata"); fb_queue_format("userdata", 1); fb_queue_erase("cache"); fb_queue_format("cache", 1); } if (wants_reboot) { fb_queue_reboot(); } else if (wants_reboot_bootloader) { fb_queue_command("reboot-bootloader", "rebooting into bootloader"); } if (fb_queue_is_empty()) return 0; status = fb_execute_queue(&transport); return (status) ? 1 : 0; }
int main(int argc, char **argv) { int wants_wipe = 0; int wants_reboot = 0; int wants_reboot_bootloader = 0; void *data; unsigned sz; unsigned page_size = 2048; int status; skip(1); if (argc == 0) { usage(); return 1; } if (!strcmp(*argv, "devices")) { list_devices(); return 0; } if (!strcmp(*argv, "help")) { usage(); return 0; } serial = getenv("ANDROID_SERIAL"); while (argc > 0) { if(!strcmp(*argv, "-w")) { wants_wipe = 1; skip(1); } else if(!strcmp(*argv, "-b")) { require(2); base_addr = strtoul(argv[1], 0, 16); skip(2); } else if(!strcmp(*argv, "-n")) { require(2); page_size = (unsigned)strtoul(argv[1], NULL, 0); if (!page_size) die("invalid page size"); skip(2); } else if(!strcmp(*argv, "-s")) { require(2); serial = argv[1]; skip(2); } else if(!strcmp(*argv, "-p")) { require(2); product = argv[1]; skip(2); } else if(!strcmp(*argv, "-c")) { require(2); cmdline = argv[1]; skip(2); } else if(!strcmp(*argv, "-i")) { char *endptr = NULL; unsigned long val; require(2); val = strtoul(argv[1], &endptr, 0); if (!endptr || *endptr != '\0' || (val & ~0xffff)) die("invalid vendor id '%s'", argv[1]); vendor_id = (unsigned short)val; skip(2); } else if(!strcmp(*argv, "getvar")) { require(2); fb_queue_display(argv[1], argv[1]); skip(2); } else if(!strcmp(*argv, "erase")) { require(2); fb_queue_erase(argv[1]); skip(2); } else if(!strcmp(*argv, "signature")) { require(2); data = load_file(argv[1], &sz); if (data == 0) die("could not load '%s'", argv[1]); if (sz != 256) die("signature must be 256 bytes"); fb_queue_download("signature", data, sz); fb_queue_command("signature", "installing signature"); skip(2); } else if(!strcmp(*argv, "reboot")) { wants_reboot = 1; skip(1); } else if(!strcmp(*argv, "reboot-bootloader")) { wants_reboot_bootloader = 1; skip(1); } else if (!strcmp(*argv, "continue")) { fb_queue_command("continue", "resuming boot"); skip(1); } else if(!strcmp(*argv, "boot")) { char *kname = 0; char *rname = 0; skip(1); if (argc > 0) { kname = argv[0]; skip(1); } if (argc > 0) { rname = argv[0]; skip(1); } data = load_bootable_image(page_size, kname, rname, &sz, cmdline); if (data == 0) return 1; fb_queue_download("boot.img", data, sz); fb_queue_command("boot", "booting"); } else if(!strcmp(*argv, "flash")) { char *pname = argv[1]; char *fname = 0; require(2); if (argc > 2) { fname = argv[2]; skip(3); } else { fname = find_item(pname, product); skip(2); } if (fname == 0) die("cannot determine image filename for '%s'", pname); data = load_file(fname, &sz); if (data == 0) die("cannot load '%s'\n", fname); fb_queue_flash(pname, data, sz); } else if(!strcmp(*argv, "flash:raw")) { char *pname = argv[1]; char *kname = argv[2]; char *rname = 0; require(3); if(argc > 3) { rname = argv[3]; skip(4); } else { skip(3); } data = load_bootable_image(page_size, kname, rname, &sz, cmdline); if (data == 0) die("cannot load bootable image"); fb_queue_flash(pname, data, sz); } else if(!strcmp(*argv, "flashall")) { skip(1); do_flashall(); wants_reboot = 1; } else if(!strcmp(*argv, "update")) { if (argc > 1) { do_update(argv[1]); skip(2); } else { do_update("update.zip"); skip(1); } wants_reboot = 1; } else if(!strcmp(*argv, "oem")) { argc = do_oem_command(argc, argv); } else { usage(); return 1; } } if (wants_wipe) { fb_queue_erase("userdata"); fb_queue_erase("cache"); } if (wants_reboot) { fb_queue_reboot(); } else if (wants_reboot_bootloader) { fb_queue_command("reboot-bootloader", "rebooting into bootloader"); } usb = open_device(); status = fb_execute_queue(usb); return (status) ? 1 : 0; }
int main(int argc, char **argv) { int wants_wipe = 0; int wants_reboot = 0; int wants_reboot_bootloader = 0; int erase_first = 1; void *data; unsigned sz; int status; int c; int r; const struct option longopts[] = { {"base", required_argument, 0, 'b'}, {"kernel_offset", required_argument, 0, 'k'}, {"page_size", required_argument, 0, 'n'}, {"ramdisk_offset", required_argument, 0, 'r'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; serial = getenv("ANDROID_SERIAL"); while (1) { int option_index = 0; c = getopt_long(argc, argv, "wub:k:n:r:s:S:lp:c:i:m:h", longopts, NULL); if (c < 0) { break; } /* Alphabetical cases */ switch (c) { case 'b': base_addr = strtoul(optarg, 0, 16); break; case 'c': cmdline = optarg; break; case 'h': usage(); return 1; case 'i': { char *endptr = NULL; unsigned long val; val = strtoul(optarg, &endptr, 0); if (!endptr || *endptr != '\0' || (val & ~0xffff)) die("invalid vendor id '%s'", optarg); vendor_id = (unsigned short)val; break; } case 'k': kernel_offset = strtoul(optarg, 0, 16); break; case 'l': long_listing = 1; break; case 'n': page_size = (unsigned)strtoul(optarg, NULL, 0); if (!page_size) die("invalid page size"); break; case 'p': product = optarg; break; case 'r': ramdisk_offset = strtoul(optarg, 0, 16); break; case 's': serial = optarg; break; case 'S': sparse_limit = parse_num(optarg); if (sparse_limit < 0) { die("invalid sparse limit"); } break; case 'u': erase_first = 0; break; case 'w': wants_wipe = 1; break; case '?': return 1; default: abort(); } } argc -= optind; argv += optind; if (argc == 0 && !wants_wipe) { usage(); return 1; } if (argc > 0 && !strcmp(*argv, "devices")) { skip(1); list_devices(); return 0; } if (argc > 0 && !strcmp(*argv, "help")) { usage(); return 0; } usb = open_device(); while (argc > 0) { if(!strcmp(*argv, "getvar")) { require(2); fb_queue_display(argv[1], argv[1]); skip(2); } else if(!strcmp(*argv, "erase")) { require(2); if (fb_format_supported(usb, argv[1])) { fprintf(stderr, "******** Did you mean to fastboot format this partition?\n"); } fb_queue_erase(argv[1]); skip(2); } else if(!strcmp(*argv, "format")) { require(2); if (erase_first && needs_erase(argv[1])) { fb_queue_erase(argv[1]); } fb_queue_format(argv[1], 0); skip(2); } else if(!strcmp(*argv, "signature")) { require(2); data = load_file(argv[1], &sz); if (data == 0) die("could not load '%s': %s", argv[1], strerror(errno)); if (sz != 256) die("signature must be 256 bytes"); fb_queue_download("signature", data, sz); fb_queue_command("signature", "installing signature"); skip(2); } else if(!strcmp(*argv, "reboot")) { wants_reboot = 1; skip(1); } else if(!strcmp(*argv, "reboot-bootloader")) { wants_reboot_bootloader = 1; skip(1); } else if (!strcmp(*argv, "continue")) { fb_queue_command("continue", "resuming boot"); skip(1); } else if(!strcmp(*argv, "boot")) { char *kname = 0; char *rname = 0; skip(1); if (argc > 0) { kname = argv[0]; skip(1); } if (argc > 0) { rname = argv[0]; skip(1); } data = load_bootable_image(kname, rname, &sz, cmdline); if (data == 0) return 1; fb_queue_download("boot.img", data, sz); fb_queue_command("boot", "booting"); } else if(!strcmp(*argv, "flash")) { char *pname = argv[1]; char *fname = 0; require(2); if (argc > 2) { fname = argv[2]; skip(3); } else { fname = find_item(pname, product); skip(2); } if (fname == 0) die("cannot determine image filename for '%s'", pname); if (erase_first && needs_erase(pname)) { fb_queue_erase(pname); } do_flash(usb, pname, fname); } else if(!strcmp(*argv, "flash:raw")) { char *pname = argv[1]; char *kname = argv[2]; char *rname = 0; require(3); if(argc > 3) { rname = argv[3]; skip(4); } else { skip(3); } data = load_bootable_image(kname, rname, &sz, cmdline); if (data == 0) die("cannot load bootable image"); fb_queue_flash(pname, data, sz); } else if(!strcmp(*argv, "flashall")) { skip(1); do_flashall(usb, erase_first); wants_reboot = 1; } else if(!strcmp(*argv, "update")) { if (argc > 1) { do_update(usb, argv[1], erase_first); skip(2); } else { do_update(usb, "update.zip", erase_first); skip(1); } wants_reboot = 1; } else if(!strcmp(*argv, "oem")) { argc = do_oem_command(argc, argv); } else { usage(); return 1; } } if (wants_wipe) { fb_queue_erase("userdata"); fb_queue_format("userdata", 1); fb_queue_erase("cache"); fb_queue_format("cache", 1); } if (wants_reboot) { fb_queue_reboot(); } else if (wants_reboot_bootloader) { fb_queue_command("reboot-bootloader", "rebooting into bootloader"); } if (fb_queue_is_empty()) return 0; status = fb_execute_queue(usb); return (status) ? 1 : 0; }