示例#1
0
文件: pkg.c 项目: HarryR/sanos
static int install_package(char *pkgname, struct pkgdb *db, int options) {
  char url[STRLEN];
  FILE *f;
  int rc;
  char inffile[STRLEN];
  struct section *manifest;
  struct section *dep;
  struct section *build;
  struct pkg *pkg;
  char *description;
  int time;

  // Check if package is already installed
  if (!(options & FROM_FILE)) {
    pkg = find_package(db, pkgname);
    if (pkg) {
      if (options & UPGRADE) {
        if (pkg->time == pkg->avail) return 0;
      } else if (options & DEPENDENCY) {
        return 0;
      } else if (options & UPDATE) {
        if (options & VERBOSE) printf("updating package %s\n", pkgname);
      } else {
        printf("package %s is already installed\n", pkgname);
        return 0;
      }
    }
  }

  // Open package file
  printf("Fetching %s\n", pkgname);
  if (options & FROM_FILE) {
    snprintf(url, sizeof(url), "file:///%s", pkgname);
  } else {
    snprintf(url, sizeof(url), "%s/%s.pkg", db->repo, pkgname);
  }
  if (options & VERBOSE) printf("fetching package %s from %s\n", pkgname, url);
  f = open_url(url, "pkg");
  if (!f) return 1;

  // Extract file from package file
  time = 0;
  rc = extract_files(url, f, inffile, options & VERBOSE, &time);
  fclose(f);
  if (rc != 0) return rc;

  // Read manifest
  if (options & VERBOSE) printf("reading manifest from %s\n", inffile);
  manifest = read_properties(inffile);
  if (!manifest) {
    fprintf(stderr, "%s: unable to read manifest\n", inffile);
    return 1;
  }

  // Add package to package database
  pkgname = get_property(manifest, "package", "name", pkgname);
  description = get_property(manifest, "package", "description", NULL);
  pkg = find_package(db, pkgname);
  if (pkg) {
    if (options & VERBOSE) printf("updating package %s in database\n", pkgname);
    if (description) {
      free(pkg->description);
      pkg->description = strdup(description);
      db->dirty = 1;
    }
    if (pkg->manifest) free_properties(pkg->manifest);
    free(pkg->inffile);
  } else {
    if (options & VERBOSE) printf("adding package %s to database\n", pkgname);
    pkg = add_package(db, pkgname, description);
  }
  pkg->inffile = strdup(inffile);
  pkg->manifest = manifest;
  if (time != pkg->time) {
    pkg->time = time;
    db->dirty = 1;
  }

  // Install package dependencies
  dep = find_section(manifest, "dependencies");
  if (dep) {
    struct property *p;
    for (p = dep->properties; p; p = p->next) {
      if (options & VERBOSE) printf("package %s depends on %s\n", pkgname, p->name);
      rc = install_package(p->name, db, options | DEPENDENCY);
      if (rc != 0) return rc;
    }
  }
  if ((options & ONLY_FETCH) && !(options & DEPENDENCY)) return 0;

  // Run package build/installation commands
  if (!(options & ONLY_FETCH) || (options & DEPENDENCY)) {
    build = find_section(manifest, (options & ONLY_BUILD) && !(options & DEPENDENCY) ? "build" : "install");
    if (build) {
      struct property *p;
      printf((options & ONLY_BUILD) && !(options & DEPENDENCY) ? "Building %s\n" : "Installing %s\n", pkgname);
      for (p = build->properties; p; p = p->next) {
        if (options & VERBOSE) printf("%s\n", p->name);
        rc = system(p->name);
        if (rc != 0) {
          fprintf(stderr, "%s: build failed\n", pkgname);
          return rc;
        }
      }
    }
  }

  return 0;
}
示例#2
0
文件: pkg.c 项目: HarryR/sanos
int main(int argc, char *argv[]) {
  struct pkgdb db;
  int c;
  int i;
  int rc;
  int remove = 0;
  int list = 0;
  int query = 0;
  int options = 0;
  int check = 0;

  // Parse command line options
  memset(&db, 0, sizeof(struct pkgdb));
  db.repo = DEFAULT_PKG_REPO;
  while ((c = getopt(argc, argv, "cdflquvBFR:U?")) != EOF) {
    switch (c) {
      case 'c':
        check = 1;
        break;

      case 'd':
        remove = 1;
        break;

      case 'f':
        options |= FROM_FILE;
        break;

      case 'l':
        list = 1;
        break;

      case 'q':
        query = 1;
        break;

      case 'u':
        options |= UPGRADE;
        break;

      case 'v':
        options |= VERBOSE;
        break;

      case 'B':
        options |= ONLY_BUILD;
        break;

      case 'F':
        options |= ONLY_FETCH;
        break;

      case 'R':
        db.repo = optarg;
        break;

      case 'U':
        options |= UPDATE;
        break;

      case '?':
      default:
        usage();
    }
  }
  if (optind == argc && !check && !list && !query && !(options & UPGRADE)) usage();

  // Read package database
  read_pkgdb(&db);

  // Get package timestamps from repository
  if ((options & UPGRADE) || check) {
    if (retrieve_package_timestamps(&db, db.repo) != 0) return 1;
  }

  if (check) {
    // Check for updates
    struct pkg *pkg;
    int num_updates = 0;
    for (pkg = db.head; pkg; pkg = pkg->next) {    
      if (pkg->avail > pkg->time) {
        num_updates++;
        if (options & VERBOSE) {
          printf("pkg: new version of %s available\n", pkg->name);
        }
      }
    }
    if (num_updates > 0) {
      printf("pkg: updates for %d packages available, use 'pkg -u' to update.\n", num_updates);
      rc = 1;
    } else {
      rc = 0;
    }
  } else if (list) {
    // List installed packages
    struct pkg *pkg;
    for (pkg = db.head; pkg; pkg = pkg->next) {
      if (options & VERBOSE) {
        printf("%-15s %s\n", pkg->name, pkg->description ? pkg->description : "");
      } else if (!(options & UPGRADE) || pkg->avail > pkg->time) {
        puts(pkg->name);
      }
    }
    rc = 0;
  } else if (query) {
    // Query package repository
    rc = query_repository(argv + optind, db.repo);
  } else if ((options & UPGRADE) && optind == argc) {
    // Upgrade all packages
    struct pkg *pkg;
    for (pkg = db.head; pkg; pkg = pkg->next) {
      rc = install_package(pkg->name, &db, options);
      if (rc != 0) break;
    }
  } else {
    // Install/remove packages
    for (i = optind; i < argc; i++) {
      if (remove) {
        rc = remove_package(argv[i], &db, options);
      } else {
        rc = install_package(argv[i], &db, options);
      }
      if (rc != 0) break;
    }
  }

  // Write package database
  if (rc == 0 && db.dirty) write_pkgdb(&db);
  delete_pkgdb(&db);

  return rc;
}
int
main(int argc, char **argv) {
    time_t start = time(NULL);

    // If this binary is started with the single argument "--adbd",
    // instead of being the normal recovery binary, it turns into kind
    // of a stripped-down version of adbd that only supports the
    // 'sideload' command.  Note this must be a real argument, not
    // anything in the command file or bootloader control block; the
    // only way recovery should be run with this argument is when it
    // starts a copy of itself from the apply_from_adb() function.
    if (argc == 2 && strcmp(argv[1], "--adbd") == 0) {
        adb_main();
        return 0;
    }

    // Handle alternative invocations
    char* command = argv[0];
    char* stripped = strrchr(argv[0], '/');
    if (stripped)
        command = stripped + 1;

    if (strcmp(command, "recovery") != 0) {
        struct recovery_cmd cmd = get_command(command);
        if (cmd.name)
            return cmd.main_func(argc, argv);

#ifdef BOARD_RECOVERY_HANDLES_MOUNT
        if (!strcmp(command, "mount") && argc == 2)
        {
            load_volume_table();
            return ensure_path_mounted(argv[1]);
        }
#endif
        if (!strcmp(command, "setup_adbd")) {
            load_volume_table();
            setup_adbd();
            return 0;
        }
        if (strstr(argv[0], "start")) {
            property_set("ctl.start", argv[1]);
            return 0;
        }
        if (strstr(argv[0], "stop")) {
            property_set("ctl.stop", argv[1]);
            return 0;
        }
        return busybox_driver(argc, argv);
    }

    // devices can run specific tasks on recovery start
    __system("/sbin/postrecoveryboot.sh");

    // Clear umask for packages that copy files out to /tmp and then over
    // to /system without properly setting all permissions (eg. gapps).
    umask(0);

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);

    printf("Starting recovery on %s", ctime(&start));

    load_volume_table();
    setup_data_media(1);
    vold_client_start(&v_callbacks, 0);
    vold_set_automount(1);
    setup_legacy_storage_paths();
    ensure_path_mounted(LAST_LOG_FILE);
    rotate_last_logs(10);
    get_args(&argc, &argv);

    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0, wipe_media = 0, show_text = 0, sideload = 0;
    bool just_exit = false;
    bool shutdown_after = false;

    printf("Checking arguments.\n");
    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;
        case 'w': wipe_data = wipe_cache = 1; break;
        case 'm': wipe_media = 1; break;
        case 'c': wipe_cache = 1; break;
        case 't': show_text = 1; break;
        case 'x': just_exit = true; break;
        case 'a': sideload = 1; break;
        case 'p': shutdown_after = true; break;
        case 'g': {
            if (stage == NULL || *stage == '\0') {
                char buffer[20] = "1/";
                strncat(buffer, optarg, sizeof(buffer)-3);
                stage = strdup(buffer);
            }
            break;
        }
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    printf("stage is [%s]\n", stage);

    device_ui_init(&ui_parameters);
    ui_init();
    ui_print(EXPAND(RECOVERY_MOD_VERSION_BUILD) "\n");
    ui_print("ClockworkMod " EXPAND(CWM_BASE_VERSION) "\n");
    LOGI("Device target: " EXPAND(TARGET_COMMON_NAME) "\n");
#ifdef PHILZ_TOUCH_RECOVERY
    print_libtouch_version(0);
#endif

    int st_cur, st_max;
    if (stage != NULL && sscanf(stage, "%d/%d", &st_cur, &st_max) == 2) {
        ui_SetStage(st_cur, st_max);
    }
    // ui_SetStage(5, 8); // debug

    if (show_text) ui_ShowText(true);

    struct selinux_opt seopts[] = {
      { SELABEL_OPT_PATH, "/file_contexts" }
    };

    sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);

    if (!sehandle) {
        ui_print("Warning:  No file_contexts\n");
    }

    LOGI("device_recovery_start()\n");
    device_recovery_start();

    printf("Command:");
    for (arg = 0; arg < argc; arg++) {
        printf(" \"%s\"", argv[arg]);
    }
    printf("\n");

    if (update_package) {
        // For backwards compatibility on the cache partition only, if
        // we're given an old 'root' path "CACHE:foo", change it to
        // "/cache/foo".
        if (strncmp(update_package, "CACHE:", 6) == 0) {
            int len = strlen(update_package) + 10;
            char* modified_path = (char*)malloc(len);
            strlcpy(modified_path, "/cache/", len);
            strlcat(modified_path, update_package+6, len);
            printf("(replacing path \"%s\" with \"%s\")\n",
                   update_package, modified_path);
            update_package = modified_path;
        }
    }
    printf("\n");

    property_list(print_property, NULL);
    printf("\n");

    int status = INSTALL_SUCCESS;

    if (update_package != NULL) {
        status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE);
        if (status == INSTALL_SUCCESS && wipe_cache) {
            if (erase_volume("/cache")) {
                LOGE("Cache wipe (requested by package) failed.\n");
            }
        }
        if (status != INSTALL_SUCCESS) {
            ui_print("Installation aborted.\n");

            // If this is an eng or userdebug build, then automatically
            // turn the text display on if the script fails so the error
            // message is visible.
            char buffer[PROPERTY_VALUE_MAX+1];
            property_get("ro.build.fingerprint", buffer, "");
            if (strstr(buffer, ":userdebug/") || strstr(buffer, ":eng/")) {
                ui_ShowText(true);
            }
        }
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        if (erase_volume("/data")) status = INSTALL_ERROR;
        if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR;
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n");
    } else if (wipe_media) {
        if (is_data_media() && erase_volume("/data/media")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Media wipe failed.\n");
    } else if (sideload) {
        status = enter_sideload_mode(status);
    } else if (!just_exit) {
        // let's check recovery start up scripts (openrecoveryscript and ROM Manager extendedcommands)
        status = INSTALL_NONE; // No command specified, it is a normal recovery boot unless we find a boot script to run

        LOGI("Checking for extendedcommand & OpenRecoveryScript...\n");

        // we need show_text to show boot scripts log
        bool text_visible = ui_IsTextVisible();
        ui_SetShowText(true);
        if (0 == check_boot_script_file(EXTENDEDCOMMAND_SCRIPT)) {
            LOGI("Running extendedcommand...\n");
            status = INSTALL_ERROR;
            if (0 == run_and_remove_extendedcommand())
                status = INSTALL_SUCCESS;
        }

        if (0 == check_boot_script_file(ORS_BOOT_SCRIPT_FILE)) {
            LOGI("Running openrecoveryscript....\n");
            status = INSTALL_ERROR;
            if (0 == run_ors_boot_script())
                status = INSTALL_SUCCESS;
        }

        ui_SetShowText(text_visible);
    }

    if (status == INSTALL_ERROR || status == INSTALL_CORRUPT) {
        copy_logs();
        // ui_set_background(BACKGROUND_ICON_ERROR); // will be set in prompt_and_wait() after recovery lock check
        handle_failure();
    }
    if (status != INSTALL_SUCCESS || ui_IsTextVisible()) {
        ui_SetShowText(true);
#ifdef PHILZ_TOUCH_RECOVERY
        check_recovery_lock();
#endif
        prompt_and_wait(status);
    }

    // We reach here when in main menu we choose reboot main system or on success install of boot scripts and recovery commands
    finish_recovery(send_intent);
    if (shutdown_after) {
        ui_print("Shutting down...\n");
        reboot_main_system(ANDROID_RB_POWEROFF, 0, 0);
    } else {
        ui_print("Rebooting...\n");
        reboot_main_system(ANDROID_RB_RESTART, 0, 0);
    }
    return EXIT_SUCCESS;
}
示例#4
0
int
main(int argc, char **argv) {

    if (argc == 2 && strcmp(argv[1], "adbd") == 0) {
        adb_main();
        return 0;
    }

    // Recovery needs to install world-readable files, so clear umask
    // set by init
    umask(0);

    if (strcmp(basename(argv[0]), "recovery") != 0)
    {
        if (strstr(argv[0], "minizip") != NULL)
            return minizip_main(argc, argv);
        if (strstr(argv[0], "dedupe") != NULL)
            return dedupe_main(argc, argv);
        if (strstr(argv[0], "flash_image") != NULL)
            return flash_image_main(argc, argv);
        if (strstr(argv[0], "volume") != NULL)
            return volume_main(argc, argv);
        if (strstr(argv[0], "edify") != NULL)
            return edify_main(argc, argv);
        if (strstr(argv[0], "dump_image") != NULL)
            return dump_image_main(argc, argv);
        if (strstr(argv[0], "erase_image") != NULL)
            return erase_image_main(argc, argv);
        if (strstr(argv[0], "mkyaffs2image") != NULL)
             return mkyaffs2image_main(argc, argv);
        if (strstr(argv[0], "make_ext4fs") != NULL)
            return make_ext4fs_main(argc, argv);
        if (strstr(argv[0], "unyaffs") != NULL)
            return unyaffs_main(argc, argv);
        if (strstr(argv[0], "nandroid"))
            return nandroid_main(argc, argv);
        if (strstr(argv[0], "bu") == argv[0] + strlen(argv[0]) - 2)
            return bu_main(argc, argv);
        if (strstr(argv[0], "reboot"))
            return reboot_main(argc, argv);
#ifdef BOARD_RECOVERY_HANDLES_MOUNT
        if (strstr(argv[0], "mount") && argc == 2 && !strstr(argv[0], "umount"))
        {
            load_volume_table();
            return ensure_path_mounted(argv[1]);
        }
#endif
        if (strstr(argv[0], "poweroff")){
            return reboot_main(argc, argv);
        }
        if (strstr(argv[0], "setprop"))
            return setprop_main(argc, argv);
        if (strstr(argv[0], "getprop"))
            return getprop_main(argc, argv);
        return busybox_driver(argc, argv);
    }

#ifdef RECOVERY_CHARGEMODE
    handle_chargemode();
#endif

    //__system("/sbin/postrecoveryboot.sh");

    int is_user_initiated_recovery = 0;
    time_t start = time(NULL);

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
    printf("Starting recovery on %s\n", ctime(&start));

#ifdef RECOVERY_CHARGEMODE
    int flag;
    flag = get_chargemode();

    if(flag == 1){
//        __system("mount /dev/block/mmcblk0p12 /system");
//        __system("sleep 1");
        __system("charge");
    }else {
#endif

    device_ui_init(&ui_parameters);
    ui_init();
    ui_print(EXPAND(RECOVERY_WELCOME)"\n");
    ui_print(EXPAND(RECOVERY_VERSION_INFO)"\n");
    ui_print(EXPAND(RECOVERY_BUILD_DATE)"\n");
	__system("/sbin/postrecoveryboot.sh");

#ifdef BOARD_RECOVERY_SWIPE
#ifndef BOARD_TOUCH_RECOVERY
    //display directions for swipe controls
    ui_print("上/下滑动选择.\n");
//    ui_print("Swipe to the right for enter.\n");
//    ui_print("Swipe to the left for back.\n");
#endif
#endif

    load_volume_table();
    process_volumes();
    LOGI("Processing arguments.\n");
    get_args(&argc, &argv);

    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0;
    int sideload = 0;
//    int headless = 0;

    LOGI("Checking arguments.\n");
    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p': previous_runs = atoi(optarg); break;
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;
        case 'w': 
#ifndef BOARD_RECOVERY_ALWAYS_WIPES
        wipe_data = wipe_cache = 1;
#endif
        break;
/*        case 'h':
            ui_set_background(BACKGROUND_ICON_CID);
            ui_show_text(0);
            headless = 1;
            break; */
        case 'c': wipe_cache = 1; break;
        case 't': ui_show_text(1); break;
        case 'l': sideload = 1; break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    struct selinux_opt seopts[] = {
      { SELABEL_OPT_PATH, "/file_contexts" }
    };

    sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);

    if (!sehandle) {
        fprintf(stderr, "Warning: No file_contexts\n");
        // ui_print("Warning:  No file_contexts\n");
    }

    LOGI("device_recovery_start()\n");
    device_recovery_start();

    enable_key_backlight();

    printf("Command:");
    for (arg = 0; arg < argc; arg++) {
        printf(" \"%s\"", argv[arg]);
    }
    printf("\n");

    if (update_package) {
        // For backwards compatibility on the cache partition only, if
        // we're given an old 'root' path "CACHE:foo", change it to
        // "/cache/foo".
        if (strncmp(update_package, "CACHE:", 6) == 0) {
            int len = strlen(update_package) + 10;
            char* modified_path = malloc(len);
            strlcpy(modified_path, "/cache/", len);
            strlcat(modified_path, update_package+6, len);
            printf("(replacing path \"%s\" with \"%s\")\n",
                   update_package, modified_path);
            update_package = modified_path;
        }
    }
    printf("\n");

    property_list(print_property, NULL);
    printf("\n");

    int status = INSTALL_SUCCESS;

    if (update_package != NULL) {
        status = install_package(update_package);
        if (status != INSTALL_SUCCESS) ui_print("安装终止.\n");
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        ignore_data_media_workaround(1);
        if (erase_volume("/data")) status = INSTALL_ERROR;
        ignore_data_media_workaround(0);
        if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR;
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("清除数据失败.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("清除缓存失败.\n");
    } else if (sideload) {
        signature_check_enabled = 0;
//        if (!headless)
          ui_set_show_text(1);
        if (0 == apply_from_adb()) {
            status = INSTALL_SUCCESS;
            ui_set_show_text(0);
        }
    } else {
        LOGI("Checking for extendedcommand...\n");
        status = INSTALL_ERROR;  // No command specified
        // we are starting up in user initiated recovery here
        // let's set up some default options
        signature_check_enabled = 0;
        script_assert_enabled = 0;
        is_user_initiated_recovery = 1;
//        if (!headless) {
          ui_set_show_text(1);
          ui_set_background(BACKGROUND_ICON_CLOCKWORK);
//        }
        
        if (extendedcommand_file_exists()) {
            LOGI("Running extendedcommand...\n");
            int ret;
            if (0 == (ret = run_and_remove_extendedcommand())) {
                status = INSTALL_SUCCESS;
                ui_set_show_text(0);
            }
            else {
                handle_failure(ret);
            }
        } else {
            LOGI("Skipping execution of extendedcommand, file not found...\n");
        }
    }

    setup_adbd();

/*    if (headless) {
      headless_wait();
    } */
    if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) {
        ui_set_show_text(1);
        ui_set_background(BACKGROUND_ICON_ERROR);
    }
//    else if (status != INSTALL_SUCCESS || ui_text_visible()) {
    if (status != INSTALL_SUCCESS || ui_text_visible()) {
        prompt_and_wait();
    }

    verify_root_and_recovery();

    // If there is a radio image pending, reboot now to install it.
    maybe_install_firmware_update(send_intent);

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);

    sync();
    if(!poweroff) {
        ui_print("正在重启...\n");
        android_reboot(ANDROID_RB_RESTART, 0, 0);
    }
    else {
        ui_print("正在关机...\n");
        android_reboot(ANDROID_RB_POWEROFF, 0, 0);
    }
    return EXIT_SUCCESS;
}

#ifdef RECOVERY_CHARGEMODE
	return 0;
}
int
main(int argc, char **argv) {

    if (argc == 2 && strcmp(argv[1], "adbd") == 0) {
        adb_main();
        return 0;
    }

    // Recovery needs to install world-readable files, so clear umask
    // set by init
    umask(0);

    char* command = argv[0];
    char* stripped = strrchr(argv[0], '/');
    if (stripped)
        command = stripped + 1;

    if (strcmp(command, "recovery") != 0)
    {
        struct recovery_cmd cmd = get_command(command);
        if (cmd.name)
            return cmd.main_func(argc, argv);

#ifdef BOARD_RECOVERY_HANDLES_MOUNT
        if (!strcmp(command, "mount") && argc == 2)
        {
            load_volume_table();
            return ensure_path_mounted(argv[1]);
        }
#endif
        if (!strcmp(command, "setup_adbd")) {
            load_volume_table();
            setup_adbd();
            return 0;
        }
        if (!strcmp(command, "start")) {
            property_set("ctl.start", argv[1]);
            return 0;
        }
        if (!strcmp(command, "stop")) {
            property_set("ctl.stop", argv[1]);
            return 0;
        }
        return busybox_driver(argc, argv);
    }
    //__system("/sbin/postrecoveryboot.sh");

    int is_user_initiated_recovery = 0;
    time_t start = time(NULL);

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
    printf("Starting recovery on %s\n", ctime(&start));

    device_ui_init(&ui_parameters);
    ui_init();
    ui_print(EXPAND(RECOVERY_VERSION)"\n");
	ui_print("Builder: "EXPAND(RECOVERY_BUILDER)"\n");
	ui_print("Date: "EXPAND(RECOVERY_BUILD_TIME)"\n");
	ui_print("weibo:@nx-baby\n");
	__system("/sbin/postrecoveryboot.sh");

//#ifdef BOARD_RECOVERY_SWIPE
//#ifndef BOARD_TOUCH_RECOVERY
    //display directions for swipe controls
    ui_print("Swipe up/down to change selections.\n");
    ui_print("Swipe to the right for enter.\n");
    ui_print("Swipe to the left for back.\n");
//#endif
//#endif

    load_volume_table();
    process_volumes();
    vold_init();
    setup_legacy_storage_paths();
#ifdef QCOM_HARDWARE
    parse_t_daemon_data_files();
	apply_time_zone();
#endif
    LOGI("Processing arguments.\n");
    ensure_path_mounted(LAST_LOG_FILE);
    rotate_last_logs(10);
    get_args(&argc, &argv);

    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0;
    int sideload = 0;
    int headless = 0;
    int shutdown_after = 0;

    LOGI("Checking arguments.\n");
    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 's': send_intent = optarg; break;
        case 'u':
            if (update_package == NULL)
                update_package = optarg;
            break;
        case 'w':
#ifndef BOARD_RECOVERY_ALWAYS_WIPES
        wipe_data = wipe_cache = 1;
#endif
        break;
        case 'h':
            ui_set_background(BACKGROUND_ICON_CID);
            ui_show_text(0);
            headless = 1;
            break;
        case 'c': wipe_cache = 1; break;
        case 't': ui_show_text(1); break;
        case 'l': sideload = 1; break;
        case 'p': shutdown_after = 1; break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    struct selinux_opt seopts[] = {
      { SELABEL_OPT_PATH, "/file_contexts" }
    };

    sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);

    if (!sehandle) {
        fprintf(stderr, "Warning: No file_contexts\n");
        //ui_print("Warning:  No file_contexts\n");
    }

    LOGI("device_recovery_start()\n");
    device_recovery_start();

    printf("Command:");
    for (arg = 0; arg < argc; arg++) {
        printf(" \"%s\"", argv[arg]);
    }
    printf("\n");

    if (update_package) {
        // For backwards compatibility on the cache partition only, if
        // we're given an old 'root' path "CACHE:foo", change it to
        // "/cache/foo".
        if (strncmp(update_package, "CACHE:", 6) == 0) {
            int len = strlen(update_package) + 10;
            char* modified_path = malloc(len);
            strlcpy(modified_path, "/cache/", len);
            strlcat(modified_path, update_package+6, len);
            printf("(replacing path \"%s\" with \"%s\")\n",
                   update_package, modified_path);
            update_package = modified_path;
        }
    }
    printf("\n");

    property_list(print_property, NULL);
    printf("\n");

    int status = INSTALL_SUCCESS;

    if (update_package != NULL) {
        status = install_package(update_package);
        if (status != INSTALL_SUCCESS) {
            copy_logs();
            ui_print("Installation aborted.\n");
        } else if (!strcmp(TARGET_DEVICE, "A0001")) { //hack for a0001 ota
            if (strstr(update_package, "/.OTA/"))
                send_intent = "0";
        }
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        preserve_data_media(0);
        if (erase_volume("/data")) status = INSTALL_ERROR;
        preserve_data_media(1);
        if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR;
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) {
            copy_logs();
            ui_print("Data wipe failed.\n");
        }
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) {
            copy_logs();
            ui_print("Cache wipe failed.\n");
        }
    } else {
        LOGI("Checking for extendedcommand...\n");
        status = INSTALL_ERROR;  // No command specified
        // we are starting up in user initiated recovery here
        // let's set up some default options
        signature_check_enabled = 0;
        is_user_initiated_recovery = 1;
        if (!headless) {
            ui_set_show_text(1);
            ui_set_background(BACKGROUND_ICON_CLOCKWORK);
        }

        if (extendedcommand_file_exists()) {
            LOGI("Running extendedcommand...\n");
            int ret;
            if (0 == (ret = run_and_remove_extendedcommand())) {
                status = INSTALL_SUCCESS;
                ui_set_show_text(0);
            }
            else {
                handle_failure(ret);
            }
        } else {
            LOGI("Skipping execution of extendedcommand, file not found...\n");
        }
    }

    if (sideload) {
        signature_check_enabled = 0;
        if (!headless)
            ui_set_show_text(1);
        if (0 == apply_from_adb()) {
            status = INSTALL_SUCCESS;
            ui_set_show_text(0);
        }
    }

    if (headless) {
        headless_wait();
    }
    if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) {
        ui_set_show_text(1);
        ui_set_background(BACKGROUND_ICON_ERROR);
    }
    else if (status != INSTALL_SUCCESS || ui_text_visible()) {
        prompt_and_wait();
    }

    // We reach here when in main menu we choose reboot main system or for some wipe commands on start
    // If there is a radio image pending, reboot now to install it.
    maybe_install_firmware_update(send_intent);

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    if (shutdown_after) {
        ui_print("Shutting down...\n");
        reboot_main_system(ANDROID_RB_POWEROFF, 0, 0);
    } else {
        ui_print("Rebooting...\n");
        reboot_main_system(ANDROID_RB_RESTART, 0, 0);
    }
    return EXIT_SUCCESS;
}
int
main(int argc, char **argv) {
	if (strcmp(basename(argv[0]), "recovery") != 0)
	{
	    if (strstr(argv[0], "flash_image") != NULL)
	        return flash_image_main(argc, argv);
	    if (strstr(argv[0], "volume") != NULL)
	        return volume_main(argc, argv);
	    if (strstr(argv[0], "edify") != NULL)
	        return edify_main(argc, argv);
	    if (strstr(argv[0], "dump_image") != NULL)
	        return dump_image_main(argc, argv);
	    if (strstr(argv[0], "erase_image") != NULL)
	        return erase_image_main(argc, argv);
	    if (strstr(argv[0], "mkyaffs2image") != NULL)
	        return mkyaffs2image_main(argc, argv);
	    if (strstr(argv[0], "unyaffs") != NULL)
	        return unyaffs_main(argc, argv);
        if (strstr(argv[0], "nandroid"))
            return nandroid_main(argc, argv);
        if (strstr(argv[0], "reboot"))
            return reboot_main(argc, argv);
#ifdef BOARD_RECOVERY_HANDLES_MOUNT
        if (strstr(argv[0], "mount") && argc == 2 && !strstr(argv[0], "umount"))
        {
            load_volume_table();
            return ensure_path_mounted(argv[1]);
        }
#endif
        if (strstr(argv[0], "poweroff")){
            return reboot_main(argc, argv);
        }
        if (strstr(argv[0], "setprop"))
            return setprop_main(argc, argv);
		return busybox_driver(argc, argv);
	}
    __system("/sbin/postrecoveryboot.sh");

    int is_user_initiated_recovery = 0;
    time_t start = time(NULL);

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
    printf("Starting recovery on %s", ctime(&start));

    device_ui_init(&ui_parameters);
    ui_init();
    ui_print(EXPAND(RECOVERY_VERSION)"\n");
    load_volume_table();
    process_volumes();
    LOGI("Processing arguments.\n");
    get_args(&argc, &argv);

    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0;

    LOGI("Checking arguments.\n");
    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p': previous_runs = atoi(optarg); break;
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;
        case 'w': 
#ifndef BOARD_RECOVERY_ALWAYS_WIPES
		wipe_data = wipe_cache = 1;
#endif
		break;
        case 'c': wipe_cache = 1; break;
        case 't': ui_show_text(1); break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    LOGI("device_recovery_start()\n");
    device_recovery_start();

    printf("Command:");
    for (arg = 0; arg < argc; arg++) {
        printf(" \"%s\"", argv[arg]);
    }
    printf("\n");

    if (update_package) {
        // For backwards compatibility on the cache partition only, if
        // we're given an old 'root' path "CACHE:foo", change it to
        // "/cache/foo".
        if (strncmp(update_package, "CACHE:", 6) == 0) {
            int len = strlen(update_package) + 10;
            char* modified_path = malloc(len);
            strlcpy(modified_path, "/cache/", len);
            strlcat(modified_path, update_package+6, len);
            printf("(replacing path \"%s\" with \"%s\")\n",
                   update_package, modified_path);
            update_package = modified_path;
        }
    }
    printf("\n");

    property_list(print_property, NULL);
    printf("\n");

    int status = INSTALL_SUCCESS;

    if (update_package != NULL) {
        status = install_package(update_package);
        if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        if (erase_volume("/data")) status = INSTALL_ERROR;
        if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR;
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n");
    } else {
        LOGI("Checking for extendedcommand...\n");
        status = INSTALL_ERROR;  // No command specified
        // we are starting up in user initiated recovery here
        // let's set up some default options
        signature_check_enabled = 0;
        script_assert_enabled = 0;
        is_user_initiated_recovery = 1;
        ui_set_show_text(1);
        ui_set_background(BACKGROUND_ICON_CLOCKWORK);
        
        if (extendedcommand_file_exists()) {
            LOGI("Running extendedcommand...\n");
            int ret;
            if (0 == (ret = run_and_remove_extendedcommand())) {
                status = INSTALL_SUCCESS;
                ui_set_show_text(0);
            }
            else {
                handle_failure(ret);
            }
        } else {
            LOGI("Skipping execution of extendedcommand, file not found...\n");
        }
    }

    if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) {
        ui_set_show_text(1);
        ui_set_background(BACKGROUND_ICON_ERROR);
    }
    if (status != INSTALL_SUCCESS || ui_text_visible()) {
        prompt_and_wait();
    }

    // If there is a radio image pending, reboot now to install it.
    maybe_install_firmware_update(send_intent);

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);

    sync();
    if(!poweroff) {
        ui_print("Rebooting...\n");
        android_reboot(ANDROID_RB_RESTART, 0, 0);
    }
    else {
        ui_print("Shutting down...\n");
        android_reboot(ANDROID_RB_POWEROFF, 0, 0);
    }
    return EXIT_SUCCESS;
}
示例#7
0
int
main(int argc, char **argv) {
        if (strstr(argv[0], "recovery") == NULL)
        {
            if (strstr(argv[0], "flash_image") != NULL)
                return flash_image_main(argc, argv);
            if (strstr(argv[0], "dump_image") != NULL)
                return dump_image_main(argc, argv);
            if (strstr(argv[0], "erase_image") != NULL)
                return erase_image_main(argc, argv);
            if (strstr(argv[0], "mkyaffs2image") != NULL)
                return mkyaffs2image_main(argc, argv);
            if (strstr(argv[0], "unyaffs") != NULL)
                return unyaffs_main(argc, argv);
            if (strstr(argv[0], "nandroid"))
                return nandroid_main(argc, argv);
            if (strstr(argv[0], "reboot"))
                return reboot_main(argc, argv);
            if (strstr(argv[0], "setprop"))
                return setprop_main(argc, argv);
            if (strstr(argv[0], "getprop"))
                return getprop_main(argc, argv);
            return busybox_driver(argc, argv);
        }
    
    int is_user_initiated_recovery = 0;
    time_t start = time(NULL);

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
    fprintf(stderr, "Starting recovery on %s", ctime(&start));
    
    ui_init();
    ui_print(EXPAND(RECOVERY_VERSION)"\n");
    //get_args(&argc, &argv);

    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0;

    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p': previous_runs = atoi(optarg); break;
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;
        case 'w': wipe_data = wipe_cache = 1; break;
        case 'c': wipe_cache = 1; break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    //device_recovery_start();

    fprintf(stderr, "Command:");
    for (arg = 0; arg < argc; arg++) {
        fprintf(stderr, " \"%s\"", argv[arg]);
    }
    fprintf(stderr, "\n\n");

    property_list(print_property, NULL);
    fprintf(stderr, "\n");

    int status = INSTALL_SUCCESS;

    //Register amend commands
    RecoveryCommandContext ctx = { NULL };
    if (register_update_commands(&ctx)) {
        LOGE("Can't install update commands\n");
    }

    if (update_package != NULL) {
        status = install_package(update_package);
        if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        if (erase_root("DATA:")) status = INSTALL_ERROR;
        if (wipe_cache && erase_root("CACHE:")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_root("CACHE:")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n");
    } else {
        status = INSTALL_ERROR;  // No command specified
    }

    if (status != INSTALL_SUCCESS || ui_text_visible()) prompt_and_wait();

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui_print("Rebooting...\n");
    sync();
    reboot(RB_AUTOBOOT);
    return EXIT_SUCCESS;
}
int
apply_from_adb() {
#ifdef ENABLE_LOKI
    int loki_support;
#endif
    stop_adbd();
    set_usb_driver(1);

    ui_print("\n\nSideload started ...\nNow send the package you want to apply\n"
              "to the device with \"adb sideload <filename>\"...\n\n");

    struct sideload_waiter_data data;
    if ((data.child = fork()) == 0) {
        execl("/sbin/recovery", "recovery", "adbd", NULL);
        _exit(-1);
    }
    
    pthread_t sideload_thread;
    pthread_create(&sideload_thread, NULL, &adb_sideload_thread, &data);
    
    static const char* headers[] = {  "ADB Sideload",
                                "",
                                NULL
    };

    static char* list[] = { "Cancel sideload", NULL };
    
    get_menu_selection(headers, list, 0, 0);

    set_usb_driver(0);
    maybe_restart_adbd();

    // kill the child
    kill(data.child, SIGTERM);
    pthread_join(sideload_thread, NULL);
    ui_clear_key_queue();

    struct stat st;
    if (stat(ADB_SIDELOAD_FILENAME, &st) != 0) {
        if (errno == ENOENT) {
            ui_print("No package received.\n");
            ui_set_background(BACKGROUND_ICON_ERROR);
        } else {
            ui_print("Error reading package:\n  %s\n", strerror(errno));
            ui_set_background(BACKGROUND_ICON_ERROR);
        }
        return INSTALL_ERROR;
    }

    int install_status = install_package(ADB_SIDELOAD_FILENAME);
    ui_reset_progress();

    if (install_status != INSTALL_SUCCESS) {
        ui_set_background(BACKGROUND_ICON_ERROR);
        ui_print("Installation aborted.\n");
    }

    remove(ADB_SIDELOAD_FILENAME);
#ifdef ENABLE_LOKI
    if(loki_support_enabled) {
       ui_print("Checking if loki-fying is needed");
       int result;
       if(result = loki_check()) {
           return result;
       }
    }
#endif
    return install_status;
}
示例#9
0
int
main(int argc, char **argv) {

    if (argc == 2 && strcmp(argv[1], "adbd") == 0) {
        adb_main();
        return 0;
    }

    // Recovery needs to install world-readable files, so clear umask
    // set by init
    umask(0);

    char* command = argv[0];
    char* stripped = strrchr(argv[0], '/');
    if (stripped)
        command = stripped + 1;

    if (strcmp(command, "recovery") != 0)
    {
        struct recovery_cmd cmd = get_command(command);
        if (cmd.name)
            return cmd.main_func(argc, argv);

#ifdef BOARD_RECOVERY_HANDLES_MOUNT
        if (!strcmp(command, "mount") && argc == 2)
        {
            load_volume_table();
            return ensure_path_mounted(argv[1]);
        }
#endif
        if (!strcmp(command, "setup_adbd")) {
            load_volume_table();
            setup_adbd();
            return 0;
        }
        if (!strcmp(command, "start")) {
            property_set("ctl.start", argv[1]);
            return 0;
        }
        if (!strcmp(command, "stop")) {
            property_set("ctl.stop", argv[1]);
            return 0;
        }
        /* Make sure stdout is not fully buffered, we don't want to
         * have issues when calling busybox commands */
        setlinebuf(stdout);
        return busybox_driver(argc, argv);
    }
    __system("/sbin/postrecoveryboot.sh");

    int is_user_initiated_recovery = 0;
    time_t start = time(NULL);

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
    printf("Starting recovery on %s\n", ctime(&start));

    device_ui_init(&ui_parameters);
    ui_init();
    ui_print(EXPAND(RECOVERY_VERSION)"\n");

#ifdef BOARD_RECOVERY_SWIPE
#ifndef BOARD_TOUCH_RECOVERY
    //display directions for swipe controls
    ui_print("Swipe up/down to change selections.\n");
    ui_print("Swipe to the right for enter.\n");
    ui_print("Swipe to the left for back.\n");
#endif
#endif

    load_volume_table();
    process_volumes();
    vold_client_start(&v_callbacks, 0);
    vold_set_automount(1);
    setup_legacy_storage_paths();
    LOGI("Processing arguments.\n");
    ensure_path_mounted(LAST_LOG_FILE);
    rotate_last_logs(10);
    get_args(&argc, &argv);

    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    const char *update_ubuntu_package = NULL;
    const char *user_data_update_package = NULL;
    int wipe_data = 0, wipe_cache = 0;
    int sideload = 0;
    int headless = 0;

    try_autodeploy(AUTODEPLOY_PACKAGE_FILE);
    try_autodeploy(AUTODEPLOY_PACKAGE_FILE_MULTI);

    LOGI("Checking arguments.\n");
    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p': previous_runs = atoi(optarg); break;
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;
        case 'd': user_data_update_package = optarg; break;
        case 'w':
#ifndef BOARD_RECOVERY_ALWAYS_WIPES
        wipe_data = wipe_cache = 1;
#endif
        break;
        case 'h':
            ui_set_background(BACKGROUND_ICON_CID);
            ui_show_text(0);
            headless = 1;
            break;
        case 'c': wipe_cache = 1; break;
        case 't': ui_show_text(1); break;
        case 'l': sideload = 1; break;
        case 'v': update_ubuntu_package = UBUNTU_UPDATE_SCRIPT; break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    struct selinux_opt seopts[] = {
      { SELABEL_OPT_PATH, "/file_contexts" }
    };

    sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);

    if (!sehandle) {
        fprintf(stderr, "Warning: No file_contexts\n");
        ui_print("Warning:  No file_contexts\n");
    }

    LOGI("device_recovery_start()\n");
    device_recovery_start();

    printf("Command:");
    for (arg = 0; arg < argc; arg++) {
        printf(" \"%s\"", argv[arg]);
    }
    printf("\n");

    if (update_package) {
        // For backwards compatibility on the cache partition only, if
        // we're given an old 'root' path "CACHE:foo", change it to
        // "/cache/foo".
        if (strncmp(update_package, "CACHE:", 6) == 0) {
            int len = strlen(update_package) + 10;
            char* modified_path = malloc(len);
            strlcpy(modified_path, "/cache/", len);
            strlcat(modified_path, update_package+6, len);
            printf("(replacing path \"%s\" with \"%s\")\n",
                   update_package, modified_path);
            update_package = modified_path;
        }
    }
    printf("\n");

    property_list(print_property, NULL);
    printf("\n");

    int status = INSTALL_SUCCESS;

    if (update_package != NULL) {
        status = install_package(update_package);
        if (status != INSTALL_SUCCESS) {
            copy_logs();
            ui_print("Installation aborted.\n");
        }
    } else if (update_ubuntu_package != NULL) {
        LOGI("Performing Ubuntu update");
        ui_set_background(BACKGROUND_ICON_INSTALLING);
        ui_show_indeterminate_progress();
        ui_print("Installing Ubuntu update.\n");
        char tmp[PATH_MAX];
        sprintf(tmp, "%s %s", UBUNTU_UPDATE_SCRIPT, UBUNTU_COMMAND_FILE );
        __system(tmp);
        LOGI("Ubuntu update complete");
        ui_print("Ubuntu update complete.\n");
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        ignore_data_media_workaround(1);
        if (erase_volume("/data")) status = INSTALL_ERROR;
        ignore_data_media_workaround(0);
        if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR;
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) {
            copy_logs();
            ui_print("Data wipe failed.\n");
        }
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) {
            copy_logs();
            ui_print("Cache wipe failed.\n");
        }
    } else {
        LOGI("Checking for extendedcommand...\n");
        status = INSTALL_ERROR;  // No command specified
        // we are starting up in user initiated recovery here
        // let's set up some default options
        signature_check_enabled = 0;
        script_assert_enabled = 0;
        is_user_initiated_recovery = 1;
        if (!headless) {
            ui_set_show_text(1);
            ui_set_background(BACKGROUND_ICON_UBUNTU);
        }

        if (extendedcommand_file_exists()) {
            LOGI("Running extendedcommand...\n");
            int ret;
            if (0 == (ret = run_and_remove_extendedcommand())) {
                status = INSTALL_SUCCESS;
                ui_set_show_text(0);
            }
            else {
                handle_failure(ret);
            }
        } else {
            LOGI("Skipping execution of extendedcommand, file not found...\n");
        }
    }

    if (sideload) {
        signature_check_enabled = 0;
        if (!headless)
            ui_set_show_text(1);
        if (0 == apply_from_adb()) {
            status = INSTALL_SUCCESS;
            ui_set_show_text(0);
        }
    }

    if (headless) {
        headless_wait();
    }

    if (user_data_update_package != NULL) {
        status = install_package(user_data_update_package);
        if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
    }

    if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) {
        ui_set_show_text(1);
        ui_set_background(BACKGROUND_ICON_ERROR);
    }
    else if (status != INSTALL_SUCCESS || ui_text_visible()) {
        prompt_and_wait();
    }

    // We reach here when in main menu we choose reboot main system or for some wipe commands on start
    // If there is a radio image pending, reboot now to install it.
    maybe_install_firmware_update(send_intent);

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui_print("Rebooting...\n");
    reboot_main_system(ANDROID_RB_RESTART, 0, 0);

    return EXIT_SUCCESS;
}
示例#10
0
int
main(int argc, char **argv) {
    time_t start = time(NULL);

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout);
    setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr);
    setbuf(stderr, NULL);
    printf("Starting recovery on %s", ctime(&start));

    device_ui_init(&ui_parameters);
    ui_init();
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    load_volume_table();
    get_args(&argc, &argv);

    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0;

    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p':
            previous_runs = atoi(optarg);
            break;
        case 's':
            send_intent = optarg;
            break;
        case 'u':
            update_package = optarg;
            break;
        case 'w':
            wipe_data = wipe_cache = 1;
            break;
        case 'c':
            wipe_cache = 1;
            break;
        case 't':
            ui_show_text(1);
            break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    device_recovery_start();

    printf("Command:");
    for (arg = 0; arg < argc; arg++) {
        printf(" \"%s\"", argv[arg]);
    }
    printf("\n");

    if (update_package) {
        // For backwards compatibility on the cache partition only, if
        // we're given an old 'root' path "CACHE:foo", change it to
        // "/cache/foo".
        if (strncmp(update_package, "CACHE:", 6) == 0) {
            int len = strlen(update_package) + 10;
            char* modified_path = malloc(len);
            strlcpy(modified_path, "/cache/", len);
            strlcat(modified_path, update_package+6, len);
            printf("(replacing path \"%s\" with \"%s\")\n",
                   update_package, modified_path);
            update_package = modified_path;
        }
    }
    printf("\n");

    property_list(print_property, NULL);
    printf("\n");

    int status = INSTALL_SUCCESS;

    if (update_package != NULL) {
        status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE);
        if (status == INSTALL_SUCCESS && wipe_cache) {
            if (erase_volume("/cache")) {
                LOGE("Cache wipe (requested by package) failed.");
            }
        }
        if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        if (erase_volume("/data")) status = INSTALL_ERROR;
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n");
    } else {
        status = INSTALL_ERROR;  // No command specified
    }

    if (status != INSTALL_SUCCESS) ui_set_background(BACKGROUND_ICON_ERROR);
    if (status != INSTALL_SUCCESS || ui_text_visible()) {
        prompt_and_wait();
    }

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui_print("Rebooting...\n");
    android_reboot(ANDROID_RB_RESTART, 0, 0);
    return EXIT_SUCCESS;
}
示例#11
0
int
main(int argc, char **argv) {
    time_t start = time(NULL);
	char firmware[50] = {0};
	property_get("ro.reversion.aw_sdk_tag", firmware, "unknow");
	strcat(reversion,firmware);
	
	char storage_type[50] = {0};
	property_get("ro.sys.storage_type",storage_type,"");
	if(!strcmp(storage_type,"emulated")){
		internal_storage_type = 1;
	}

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
    

    // If this binary is started with the single argument "--adbd",
    // instead of being the normal recovery binary, it turns into kind
    // of a stripped-down version of adbd that only supports the
    // 'sideload' command.  Note this must be a real argument, not
    // anything in the command file or bootloader control block; the
    // only way recovery should be run with this argument is when it
    // starts a copy of itself from the apply_from_adb() function.
    if (argc == 2 && strcmp(argv[1], "--adbd") == 0) {
        adb_main();
        return 0;
    }
    
    printf("Starting recovery on %s", ctime(&start));

    load_volume_table();
    get_args(&argc, &argv);

    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0, show_text = 0;
    bool just_exit = false;

    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p': previous_runs = atoi(optarg); break;
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;
        case 'w': wipe_data = wipe_cache = 1; break;
        case 'c': wipe_cache = 1; break;
        case 't': show_text = 1; break;
        case 'x': just_exit = true; break;
        case 'l': locale = optarg; break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    if (locale == NULL) {
        load_locale_from_cache();
    }
    printf("locale is [%s]\n", locale);

    Device* device = make_device();
    ui = device->GetUI();

    ui->Init();
    ui->SetLocale(locale);
    ui->SetBackground(RecoveryUI::NONE);
    if (show_text) ui->ShowText(true);

#ifdef HAVE_SELINUX
    struct selinux_opt seopts[] = {
      { SELABEL_OPT_PATH, "/file_contexts" }
    };

    sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);

    if (!sehandle) {
        fprintf(stderr, "Warning: No file_contexts\n");
        ui->Print("Warning:  No file_contexts\n");
    }
#endif

    device->StartRecovery();

    printf("Command:");
    for (arg = 0; arg < argc; arg++) {
        printf(" \"%s\"", argv[arg]);
    }
    printf("\n");

    if (update_package) {
        // For backwards compatibility on the cache partition only, if
        // we're given an old 'root' path "CACHE:foo", change it to
        // "/cache/foo".
        if (strncmp(update_package, "CACHE:", 6) == 0) {
            int len = strlen(update_package) + 10;
            char* modified_path = (char*)malloc(len);
            strlcpy(modified_path, "/cache/", len);
            strlcat(modified_path, update_package+6, len);
            printf("(replacing path \"%s\" with \"%s\")\n",
                   update_package, modified_path);
            update_package = modified_path;
        }
    }
    printf("\n");

    property_list(print_property, NULL);
    printf("\n");

    int status = INSTALL_SUCCESS;

    if (update_package != NULL) {
        status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE);
        if (status == INSTALL_SUCCESS && wipe_cache) {
            if (erase_volume("/cache")) {
                LOGE("Cache wipe (requested by package) failed.");
            }
        }
        if (status != INSTALL_SUCCESS) ui->Print("Installation aborted.\n");
    } else if (wipe_data) {
        if (device->WipeData()) status = INSTALL_ERROR;
        if (erase_volume("/data")) status = INSTALL_ERROR;
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
		copy_databk_to_data();
        if (status != INSTALL_SUCCESS) ui->Print("Data wipe failed.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui->Print("Cache wipe failed.\n");
    } else if (!just_exit) {
        status = INSTALL_NONE;  // No command specified
//        ui->SetBackground(RecoveryUI::NO_COMMAND); // modify by cjcheng
    }

    if (status == INSTALL_ERROR || status == INSTALL_CORRUPT) {
        ui->SetBackground(RecoveryUI::ERROR);
    }
    if (status != INSTALL_SUCCESS || ui->IsTextVisible()) {
        ui->ShowText(false); // modify by cjcheng
        ui->SetTipTitle(RecoveryUI::TIP_TITLE_READY); // add by cjcheng
        prompt_and_wait(device, status);

	/* add by cjcheng start... */
        if (install_flag == INSTALL_SUCCESS){
            ui->SetTipTitle(RecoveryUI::TIP_TITLE_SUCCESS);
            status = INSTALL_SUCCESS;
        }
	/* add by cjcheng end... */
    }

    /* add by cjcheng start... */
    if (status != INSTALL_SUCCESS){
        ui->SetBackground(RecoveryUI::ERROR);
        ui->SetTipTitle(RecoveryUI::TIP_TITLE_ERROR);
    }
    /* add by cjcheng end... */

    sleep(2);

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui->Print("Rebooting...\n");
    sync();
    android_reboot(ANDROID_RB_RESTART, 0, 0);
    return EXIT_SUCCESS;
}
示例#12
0
static void
prompt_and_wait()
{
	char* menu_files[MAX_MENU_LEVEL] = { NULL };
	char* menu_scripts[MAX_MENU_LEVEL] = { NULL };
	int menu_sel[MAX_MENU_LEVEL] = { 0 };
	unsigned int menu_level = 0;  
	int menu_result;
  
  //always ensure if mountings are good
  ensure_common_roots_mounted();
  
	//initialize the recovery -> either call the script for initalization, or switch to full version
#if !OPEN_RCVR_VERSION_LITE
	run_shell_script("/bin/init_recovery.sh "OPEN_RECOVERY_PHONE_SWITCH, 1, NULL);
#endif 

  menu_files[0] = malloc(strlen(MAIN_MENU_FILE)+1);
  strcpy(menu_files[0], MAIN_MENU_FILE);
  ui_led_blink(1);
  create_menu(menu_files[0], menu_scripts[0]);
  ui_led_toggle(0);
  int title_length;  
	char** headers;
	headers = prepend_title(MENU_HEADERS, &title_length);
	int override_initial_selection = -1;	
	
	int call_finish_in_loop = 1;
			
  for (;;) {  

		if (call_finish_in_loop)
		{
			finish_recovery(NULL);
			call_finish_in_loop = 0;
		}

		int menu_item;		
		
		if (override_initial_selection != -1)
		{
			menu_item = get_menu_selection(headers, MENU_ITEMS, MENU_ITEMS_SELECTABLE, title_length, override_initial_selection, 0);
			override_initial_selection = -1;
		}
		else
    	menu_item = get_menu_selection(headers, MENU_ITEMS, MENU_ITEMS_SELECTABLE, title_length, 0, 0);

    // Parse open recovery commands
    int chosen_item = select_action(menu_item);
    chosen_item = device_perform_action(chosen_item);

		//if tag, menu, or scripted menu -> don't hide menu
		//do it here explicitly, it would be a mess in the switch
		if (chosen_item != ITEM_TAG && chosen_item != ITEM_NEW_MENU 
		    && chosen_item != ITEM_NEW_MENU_SCRIPTED)
			hide_menu_selection();

		fprintf(stderr, "Menu: %d, %d, %s\n", menu_item, chosen_item, MENU_ITEMS_TARGET[menu_item]);

    switch (chosen_item) {
    	case ITEM_REBOOT:
       	return;

      case ITEM_WIPE_DATA:
        wipe_data(ui_text_visible());

        if (!ui_text_visible()) 
        	return;
        	
        ui_set_background(BACKGROUND_ICON_ERROR);
        break;

      case ITEM_WIPE_CACHE:
        ui_print("\n-- Wiping cache...\n");
				ui_led_blink(1);
        erase_root("CACHE:");
        ensure_common_roots_mounted();
				ui_led_toggle(0);
        ui_print("Cache wipe complete.\n");
        if (!ui_text_visible()) 
        	return;
        ui_set_background(BACKGROUND_ICON_ERROR);
        break;

      case ITEM_APPLY_SDCARD:
      
      	//HACK for "error: a label can only be part of a statement and a declaration is not a statement"
      	//the rule is retarted, the follwing "dummy" statement is cut in optimization
      	override_initial_selection=override_initial_selection; 
      
      	//confirm it	
      	char* confirm_headers[] = { "Confirm installing update package?",
      															 MENU_ITEMS[menu_item],
      															 "",
      															 NULL
      														};
      	char* confirm_items[] = { "Yes", "No", NULL };
      	int confirm_item = show_interactive_menu(confirm_headers, confirm_items);
      	
      	if (confirm_item == 1) //YES!
      	{      	
		      ui_print("\n-- Install from sdcard...\n");
		      ui_led_blink(1);
		      ensure_common_roots_unmounted();
		      ensure_root_path_mounted("SDCARD:");
		      set_sdcard_update_bootloader_message();
		      call_finish_in_loop = 1;
		      int status = install_package(MENU_ITEMS_TARGET[menu_item]);
		      ensure_common_roots_mounted();
		      if (status != INSTALL_SUCCESS) 
		      {
						ui_set_background(BACKGROUND_ICON_ERROR);
						ui_print("Installation aborted.\n");
		      } 
		      else if (!ui_text_visible()) 
	          return;  // reboot if logs aren't visible
		      else 
		      {
		        if (firmware_update_pending()) 
		        {
	        		ui_set_background(BACKGROUND_ICON_ERROR);
	            ui_print("\nReboot via menu to complete\n"
	                     "installation.\n");
		        } 
		        else 
		        {
	        		ui_set_background(BACKGROUND_ICON_ERROR);
	            ui_print("\nInstall from sdcard complete.\n");
		        }
		      }
		      
		      create_menu(menu_files[menu_level], menu_scripts[menu_level]);
		      free(headers);
		      headers = prepend_title(MENU_HEADERS, &title_length);
		      ui_led_toggle(0);
		    }
        
        override_initial_selection = menu_item;											
 				break; 

      case ITEM_SHELL_SCRIPT:
        ui_print("\n-- Shell script...\n");
        ui_print("%s\n", MENU_ITEMS_TARGET[menu_item]);
				ui_led_blink(1);
				ensure_common_roots_mounted();
				
				run_shell_script(MENU_ITEMS_TARGET[menu_item], 1, NULL);
				create_menu(menu_files[menu_level], menu_scripts[menu_level]);
				free(headers);
				headers = prepend_title(MENU_HEADERS, &title_length);
				
				ui_led_toggle(0);
        ui_print("Done.\n");
				
				override_initial_selection = menu_item;											
 				break; 
				
			case ITEM_TAG:
			
				if (MENU_ITEMS_TAG[menu_item] == 0x00)
				{
					int tag_fd = creat(MENU_ITEMS_TARGET[menu_item], 0644);
					if (tag_fd < 0)
						LOGE("Failed to set the tag.\n");
					else
					{
						MENU_ITEMS_TAG[menu_item] = 0x01;
						MENU_ITEMS[menu_item][1] = 'X';
						close(tag_fd);
					}					 
				}
				else if (MENU_ITEMS_TAG[menu_item] == 0x01) //just a little check if 0xFF aint there if bug is present
				{
					remove(MENU_ITEMS_TARGET[menu_item]);
					MENU_ITEMS_TAG[menu_item] = 0x00;
					MENU_ITEMS[menu_item][1] = ' '; 
				}
			
				override_initial_selection = menu_item;											
 				break; 

      case ITEM_NEW_MENU:
				if (menu_level + 1 >= MAX_MENU_LEVEL)
				{
					//too much menus, ignore
					break;
				}
							
				ui_led_blink(1);
				if (!strcmp(MENU_ITEMS_TARGET[menu_item], ".."))
				{
					if (menu_level)
					{
						free(menu_files[menu_level]);
						menu_files[menu_level] = NULL;
						
						if (menu_scripts[menu_level])
						{
							free(menu_scripts[menu_level]);
							menu_scripts[menu_level] = NULL;
						}
						
						menu_sel[menu_level] = 0;
						menu_level--;
						override_initial_selection = menu_sel[menu_level];
					}
				}
				else
				{
					menu_sel[menu_level] = menu_item;
					menu_level++;
					menu_files[menu_level] = malloc(strlen(MENU_ITEMS_TARGET[menu_item]) + 1);
					strcpy(menu_files[menu_level], MENU_ITEMS_TARGET[menu_item]);				
				}
					
				ensure_common_roots_mounted();	
				menu_result = create_menu(menu_files[menu_level], menu_scripts[menu_level]);
				
				//if fail, remove the new menu
				if (menu_result && menu_level)
				{
					free(menu_files[menu_level]);
					menu_files[menu_level] = NULL;
					
					if (menu_scripts[menu_level])
					{
						free(menu_scripts[menu_level]);
						menu_scripts[menu_level] = NULL;
					}
					
					menu_level--;
				}
				
				free(headers);
				headers = prepend_title(MENU_HEADERS, &title_length);
				ui_led_toggle(0);
				break;
			
			case ITEM_NEW_MENU_SCRIPTED:
			
				if (menu_level + 1 >= MAX_MENU_LEVEL)
				{
					//too much menus, ignore
					break;
				}
			
				ui_led_blink(1);
				char cmdBuff[MAX_LINE_LENGTH];
				strcpy(cmdBuff, MENU_ITEMS_TARGET[menu_item]);
				char* ptr;
										
				//menufile:script
				ptr = strtok(cmdBuff, ":");
				if (ptr != NULL)
				{
					menu_sel[menu_level] = menu_item;
					menu_level++;
					menu_files[menu_level] = malloc(strlen(ptr) + 1);
					strcpy(menu_files[menu_level], ptr);						
					
					ptr = strtok(NULL, "");
					if (ptr != NULL)
					{
						if (ptr[0] == '/' || (ptr[0] == '\"' && ptr[1] == '/'))
						{
							menu_scripts[menu_level] = malloc(strlen(ptr) + 1);
							strcpy(menu_scripts[menu_level], ptr);					
						}
						else
						{
							menu_scripts[menu_level] = malloc(strlen(CUSTOM_SHELL_SCRIPT_PATH) + strlen(ptr) + 2);
						
							if (ptr[0] == '\"')
								sprintf(menu_scripts[menu_level], "\"%s/%s", CUSTOM_SHELL_SCRIPT_PATH, ptr+1);
							else
								sprintf(menu_scripts[menu_level], "%s/%s", CUSTOM_SHELL_SCRIPT_PATH, ptr);

						}
					}
					
					ensure_common_roots_mounted();
					menu_result = create_menu(menu_files[menu_level], menu_scripts[menu_level]);
					
					//if fail, remove the new menu
					if (menu_result && menu_level)
					{
						free(menu_files[menu_level]);
						menu_files[menu_level] = NULL;
						
						if (menu_scripts[menu_level])
						{
							free(menu_scripts[menu_level]);
							menu_scripts[menu_level] = NULL;
						}
						
						menu_level--;
					}
					
					free(headers);
					headers = prepend_title(MENU_HEADERS, &title_length);
				}
					
				ui_led_toggle(0);
				break;
			
			case ITEM_CONSOLE:
#if OPEN_RECOVERY_HAVE_CONSOLE
				ensure_common_roots_mounted();
				
				ui_print("Opening console...\n");
				int console_error = run_console(NULL);
				
				if (console_error)
					if (console_error == CONSOLE_FORCE_QUIT)
						ui_print("Console was forcibly closed.\n");
					else if (console_error == CONSOLE_FAILED_START)
						ui_print("Console failed to start.\n");
					else
					{
						ui_print("Closing console...\n"); //don't bother printing error to UI
						fprintf(stderr, "Console closed with error %d.\n", console_error);
					}		
				else
					ui_print("Closing console...\n");
					
				create_menu(menu_files[menu_level], menu_scripts[menu_level]);
				free(headers);
				headers = prepend_title(MENU_HEADERS, &title_length);
#else
				LOGE("This phone doesn't support console.\n");
#endif
				override_initial_selection = menu_item;											
 				break; 
			
			case ITEM_ERROR:
				LOGE("Unknown command: %s.\n", MENU_ITEMS_ACTION[menu_item]);
				break;
    }
  }
}
示例#13
0
int
main(int argc, char **argv)
{
  if (getppid() != 1)
  {
  	fprintf(stderr, "Parent process must be init.\n"); 
		return EXIT_FAILURE;
  }
  
	time_t start = time(NULL);

	// If these fail, there's not really anywhere to complain...
	freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
	freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
	fprintf(stderr, "Starting Open Recovery on %s", ctime(&start));

	//menu title
	//lite - just the base
	//full - look for mod
	
#if OPEN_RCVR_VERSION_LITE
	MENU_TITLE = BASE_MENU_TITLE;
#else
	//keep'em malloced even if empty :p
	char* mod_author = malloc(81);
	char* mod_version = malloc(81);
	
	char mod_author_prop[81];
	char mod_version_prop[81];
	
	property_get(MOD_AUTHOR_PROP, mod_author_prop, "");
	property_get(MOD_VERSION_PROP, mod_version_prop, "");
	
	//assume there are some mod properties, leave NULL if there ain't
	MENU_TITLE = malloc((sizeof(BASE_MENU_TITLE) + 3) * sizeof(char*));
	memset(MENU_TITLE, 0, (sizeof(BASE_MENU_TITLE) + 3) * sizeof(char*));
	
	char** b = BASE_MENU_TITLE;
	char** m = MENU_TITLE;
	while (*b)
	{
		*m = *b;
		m++;
		b++;
	}
	
	//append "" if one of the props exist
	int append_empty = 0;	
	
	if (mod_author_prop[0] != '\0')
	{
		//mod version only if mod author
		if (mod_version_prop[0] != '\0')
		{
			snprintf(mod_version, 80, MOD_VERSION_BASE, mod_version_prop);
			*m = mod_version;
			m++;
		}

		snprintf(mod_author, 80, MOD_AUTHOR_BASE, mod_author_prop);
		*m = mod_author;
		m++;
		append_empty = 1;
	}		
			
	if (append_empty)
	{
		*m = malloc(1);
		(*m)[0] = '\0';
		m++;
	}
	
#endif

	ui_init();

	//react on the command
	//full version only checks for it's own command file
	//the rest is done by lite version
#if OPEN_RCVR_VERSION_LITE
	get_args(&argc, &argv);
#else
	argc = 1;
	get_cmd_file_args(&argc, &argv);
#endif
	

	int previous_runs = 0;
	const char *send_intent = NULL;
	const char *update_package = NULL;
	int wipe_data = 0, wipe_cache = 0;

  int arg;
  while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) 
  {
    switch (arg) 
    {
      case 'p': previous_runs = atoi(optarg); break;
      case 's': send_intent = optarg; break;
      case 'u': update_package = optarg; break;
      case 'w': wipe_data = wipe_cache = 1; break;
      case 'c': wipe_cache = 1; break;
      case '?':
        LOGE("Invalid command argument\n");
        continue;
    }
  }

	device_recovery_start();

  fprintf(stderr, "Command:");
  for (arg = 0; arg < argc; arg++) 
    fprintf(stderr, " \"%s\"", argv[arg]);
  
  fprintf(stderr, "\n\n");

  property_list(print_property, NULL);
  fprintf(stderr, "\n");

  int status = INSTALL_SUCCESS;

  if (update_package != NULL) 
  {
    status = install_package(update_package);
    if (status != INSTALL_SUCCESS) 
    	ui_print("Installation aborted.\n");
    
    char package_path[PATH_MAX] = "";
    if (!ensure_root_path_mounted(update_package) &&
    		translate_root_path(update_package, package_path, sizeof(package_path)))
    	unlink(package_path);
  } 
  else if (wipe_data) 
  {
    if (device_wipe_data()) 
    	status = INSTALL_ERROR;
    if (erase_root("DATA:")) 
    	status = INSTALL_ERROR;
    if (wipe_cache && erase_root("CACHE:")) 
    	status = INSTALL_ERROR;
    if (status != INSTALL_SUCCESS)
    	ui_print("Data wipe failed.\n");
  } 
  else if (wipe_cache) 
  {
    if (wipe_cache && erase_root("CACHE:")) 
    	status = INSTALL_ERROR;
    if (status != INSTALL_SUCCESS) 
    	ui_print("Cache wipe failed.\n");
  } 
  else 
    status = INSTALL_ERROR;  // No command specified
 
#if OPEN_RCVR_VERSION_LITE
	int or_up_sts = install_package(FULL_PACKAGE_FILE);
  if (or_up_sts != INSTALL_SUCCESS) 
  {
		ui_print("Failed to switch into the full version.\n");
		ui_print("Running Lite version only.\n");
  } 
#endif

	//lite OR doesn't have text visible by default
	//but full OR does

#if OPEN_RCVR_VERSION_LITE
  if (status != INSTALL_SUCCESS) 
  	ui_set_background(BACKGROUND_ICON_ERROR);
  if (status != INSTALL_SUCCESS || ui_text_visible())
  	prompt_and_wait();
#else
	if (status != INSTALL_SUCCESS) 
	{
		ui_set_background(BACKGROUND_ICON_ERROR);
		prompt_and_wait();
	}
#endif

  // If there is a radio image pending, reboot now to install it.
  maybe_install_firmware_update(send_intent);

  // Otherwise, get ready to boot the main system...
  finish_recovery(send_intent);

  ui_print("Rebooting...\n");
  sync();
  ensure_common_roots_unmounted();
  reboot(RB_AUTOBOOT);
  return EXIT_SUCCESS;
}
示例#14
0
int
main(int argc, char **argv)
{
    time_t start = time(NULL);

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
    fprintf(stderr, "Starting recovery on %s", ctime(&start));

    ui_init();
    ui_print("Android system recovery utility\n");
    get_args(&argc, &argv);

    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0;

    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p': previous_runs = atoi(optarg); break;
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;
        case 'w': wipe_data = wipe_cache = 1; break;
        case 'c': wipe_cache = 1; break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    fprintf(stderr, "Command:");
    for (arg = 0; arg < argc; arg++) {
        fprintf(stderr, " \"%s\"", argv[arg]);
    }
    fprintf(stderr, "\n\n");

    property_list(print_property, NULL);
    fprintf(stderr, "\n");

#if TEST_AMEND
    test_amend();
#endif

    RecoveryCommandContext ctx = { NULL };
    if (register_update_commands(&ctx)) {
        LOGE("Can't install update commands\n");
    }

    int status = INSTALL_SUCCESS;

    if (update_package != NULL) {
        status = install_package(update_package);
        if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
    } else if (wipe_data || wipe_cache) {
        if (wipe_data && erase_root("DATA:")) status = INSTALL_ERROR;
        if (wipe_cache && erase_root("CACHE:")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
    } else {
        status = INSTALL_ERROR;  // No command specified
    }

    if (status != INSTALL_SUCCESS) ui_set_background(BACKGROUND_ICON_ERROR);
    if (status != INSTALL_SUCCESS || ui_text_visible()) prompt_and_wait();

    // If there is a radio image pending, reboot now to install it.
    maybe_install_firmware_update(send_intent);

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui_print("Rebooting...\n");
    sync();
    reboot(RB_AUTOBOOT);
    return EXIT_SUCCESS;
}
static void
prompt_and_wait() {
    char** headers = prepend_title((const char**)MENU_HEADERS);

    for (;;) {
        finish_recovery(NULL);
        ui_reset_progress();

        allow_display_toggle = 1;
        int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0);
        allow_display_toggle = 0;

        // device-specific code may take some action here.  It may
        // return one of the core actions handled in the switch
        // statement below.
        chosen_item = device_perform_action(chosen_item);

        switch (chosen_item) {
            case ITEM_REBOOT:
                poweroff=0;
                return;

            case ITEM_WIPE_DATA:
                wipe_data(ui_text_visible());
                if (!ui_text_visible()) return;
                break;

            case ITEM_WIPE_CACHE:
                if (confirm_selection("Confirm wipe?", "Yes - Wipe Cache"))
                {
                    ui_print("\n-- Wiping cache...\n");
                    erase_volume("/cache");
                    ui_print("Cache wipe complete.\n");
                    if (!ui_text_visible()) return;
                }
                break;

            case ITEM_APPLY_SDCARD:
                if (confirm_selection("Confirm install?", "Yes - Install /sdcard/update.zip"))
                {
                    ui_print("\n-- Install from sdcard...\n");
                    int status = install_package(SDCARD_PACKAGE_FILE);
                    if (status != INSTALL_SUCCESS) {
                        ui_set_background(BACKGROUND_ICON_ERROR);
                        ui_print("Installation aborted.\n");
                    } else if (!ui_text_visible()) {
                        return;  // reboot if logs aren't visible
                    } else {
                        ui_print("\nInstall from sdcard complete.\n");
                    }
                }
                break;
            case ITEM_INSTALL_ZIP:
                show_install_update_menu();
                break;
            case ITEM_NANDROID:
                show_nandroid_menu();
                break;
            case ITEM_PARTITION:
                show_partition_menu();
                break;
            case ITEM_ADVANCED:
                show_advanced_menu();
                break;
            case ITEM_POWEROFF:
                poweroff=1;
                return;
        }
    }
}
static int
update_directory(const char* path, const char* unmount_when_done) {
    ensure_path_mounted(path);

    const char* MENU_HEADERS[] = { "Choose a package to install:",
                                   path,
                                   "",
                                   NULL };
    DIR* d;
    struct dirent* de;
    d = opendir(path);
    if (d == NULL) {
        LOGE("error opening %s: %s\n", path, strerror(errno));
        if (unmount_when_done != NULL) {
            ensure_path_unmounted(unmount_when_done);
        }
        return 0;
    }

    char** headers = prepend_title(MENU_HEADERS);

    int d_size = 0;
    int d_alloc = 10;
    char** dirs = malloc(d_alloc * sizeof(char*));
    int z_size = 1;
    int z_alloc = 10;
    char** zips = malloc(z_alloc * sizeof(char*));
    zips[0] = strdup("../");

    while ((de = readdir(d)) != NULL) {
        int name_len = strlen(de->d_name);

        if (de->d_type == DT_DIR) {
            // skip "." and ".." entries
            if (name_len == 1 && de->d_name[0] == '.') continue;
            if (name_len == 2 && de->d_name[0] == '.' &&
                de->d_name[1] == '.') continue;

            if (d_size >= d_alloc) {
                d_alloc *= 2;
                dirs = realloc(dirs, d_alloc * sizeof(char*));
            }
            dirs[d_size] = malloc(name_len + 2);
            strcpy(dirs[d_size], de->d_name);
            dirs[d_size][name_len] = '/';
            dirs[d_size][name_len+1] = '\0';
            ++d_size;
        } else if (de->d_type == DT_REG &&
                   name_len >= 4 &&
                   strncasecmp(de->d_name + (name_len-4), ".zip", 4) == 0) {
            if (z_size >= z_alloc) {
                z_alloc *= 2;
                zips = realloc(zips, z_alloc * sizeof(char*));
            }
            zips[z_size++] = strdup(de->d_name);
        }
    }
    closedir(d);

    qsort(dirs, d_size, sizeof(char*), compare_string);
    qsort(zips, z_size, sizeof(char*), compare_string);

    // append dirs to the zips list
    if (d_size + z_size + 1 > z_alloc) {
        z_alloc = d_size + z_size + 1;
        zips = realloc(zips, z_alloc * sizeof(char*));
    }
    memcpy(zips + z_size, dirs, d_size * sizeof(char*));
    free(dirs);
    z_size += d_size;
    zips[z_size] = NULL;

    int result;
    int chosen_item = 0;
    do {
        chosen_item = get_menu_selection(headers, zips, 1, chosen_item);

        char* item = zips[chosen_item];
        int item_len = strlen(item);
        if (chosen_item == 0) {          // item 0 is always "../"
            // go up but continue browsing (if the caller is update_directory)
            result = -1;
            break;
        } else if (item[item_len-1] == '/') {
            // recurse down into a subdirectory
            char new_path[PATH_MAX];
            strlcpy(new_path, path, PATH_MAX);
            strlcat(new_path, "/", PATH_MAX);
            strlcat(new_path, item, PATH_MAX);
            new_path[strlen(new_path)-1] = '\0';  // truncate the trailing '/'
            result = update_directory(new_path, unmount_when_done);
            if (result >= 0) break;
        } else {
            // selected a zip file:  attempt to install it, and return
            // the status to the caller.
            char new_path[PATH_MAX];
            strlcpy(new_path, path, PATH_MAX);
            strlcat(new_path, "/", PATH_MAX);
            strlcat(new_path, item, PATH_MAX);

            ui_print("\n-- Install %s ...\n", path);
            set_sdcard_update_bootloader_message();
            char* copy = copy_sideloaded_package(new_path);
            if (unmount_when_done != NULL) {
                ensure_path_unmounted(unmount_when_done);
            }
            if (copy) {
                result = install_package(copy);
                free(copy);
            } else {
                result = INSTALL_ERROR;
            }
            break;
        }
    } while (true);

    int i;
    for (i = 0; i < z_size; ++i) free(zips[i]);
    free(zips);
    free(headers);

    if (unmount_when_done != NULL) {
        ensure_path_unmounted(unmount_when_done);
    }
    return result;
}
示例#17
0
gpointer worker_thread_cb(gpointer data)
{
	UpdaterAppState *app_state;
	CURL *curl;
	CURLcode result;
	FILE *package_file;
	GError *error = NULL;
	int fd;

	//g_return_val_if_fail (data != NULL, NULL);
	app_state = (UpdaterAppState *) data;

	try {

		if(!app_state->url.empty())
		{
			char* tmp_local_filename = NULL;
			// create temporary file to store the package.
			fd = g_file_open_tmp
				("secondlife-update-XXXXXX", &tmp_local_filename, &error);
			if (error != NULL)
			{
				llerrs << "Unable to create temporary file: "
					   << error->message
					   << llendl;

				g_error_free(error);
				throw 0;
			}

			if(tmp_local_filename != NULL)
			{
				app_state->file = tmp_local_filename;
				g_free(tmp_local_filename);
			}

			package_file = fdopen(fd, "wb");
			if (package_file == NULL)
			{
				llerrs << "Failed to create temporary file: "
					   << app_state->file.c_str()
					   << llendl;

				gdk_threads_enter();
				display_error(app_state->window,
							  LLTrans::getString("UpdaterFailDownloadTitle"),
							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
				gdk_threads_leave();
				throw 0;
			}

			// initialize curl and start downloading the package
			llinfos << "Downloading package: " << app_state->url << llendl;

			curl = curl_easy_init();
			if (curl == NULL)
			{
				llerrs << "Failed to initialize libcurl" << llendl;

				gdk_threads_enter();
				display_error(app_state->window,
							  LLTrans::getString("UpdaterFailDownloadTitle"),
							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
				gdk_threads_leave();
				throw 0;
			}

			curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str());
			curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE);
			curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE);
			curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file);
			curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
			curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION,
							 &download_progress_cb);
			curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state);

			result = curl_easy_perform(curl);
			fclose(package_file);
			curl_easy_cleanup(curl);

			if (result)
			{
				llerrs << "Failed to download update: "
					   << app_state->url
					   << llendl;

				gdk_threads_enter();
				display_error(app_state->window,
							  LLTrans::getString("UpdaterFailDownloadTitle"),
							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
				gdk_threads_leave();

				throw 0;
			}
		}

		// now pulse the progres bar back and forth while the package is
		// being unpacked
		gdk_threads_enter();
		std::string installing_msg = LLTrans::getString("UpdaterNowInstalling");
		gtk_progress_bar_set_text(
			GTK_PROGRESS_BAR(app_state->progress_bar),
			installing_msg.c_str());
		app_state->activity_mode = TRUE;
		gdk_threads_leave();

		// *TODO: if the destination is not writable, terminate this
		// thread and show file chooser?
		if (!install_package(app_state->file.c_str(), app_state->dest_dir))
		{
			llwarns << "Failed to install package to destination: "
				<< app_state->dest_dir
				<< llendl;

			gdk_threads_enter();
			display_error(app_state->window,
						  LLTrans::getString("UpdaterFailInstallTitle"),
						  LLTrans::getString("UpdaterFailUpdateDescriptive"));
			//"Failed to update " + app_state->app_name,
			gdk_threads_leave();
			throw 0;
		}

		// try to spawn the new viewer
		if (!spawn_viewer(app_state))
		{
			llwarns << "Viewer was not installed properly in : "
				<< app_state->dest_dir
				<< llendl;

			gdk_threads_enter();
			display_error(app_state->window,
						  LLTrans::getString("UpdaterFailStartTitle"),
						  LLTrans::getString("UpdaterFailUpdateDescriptive"));
			gdk_threads_leave();
			throw 0;
		}
	}
	catch (...)
	{
		app_state->failure = TRUE;
	}

	gdk_threads_enter();
	updater_app_quit(app_state);
	gdk_threads_leave();

	return NULL;
}