コード例 #1
0
// If the package contains an update binary, extract it and run it.
static int
try_update_binary(const char *path, ZipArchive *zip) {
    const ZipEntry* binary_entry =
            mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME);
    if (binary_entry == NULL) {
        return INSTALL_CORRUPT;
    }

    char* binary = "/tmp/update_binary";
    unlink(binary);
    int fd = creat(binary, 0755);
    if (fd < 0) {
        LOGE("Can't make %s\n", binary);
        return 1;
    }
    bool ok = mzExtractZipEntryToFile(zip, binary_entry, fd);
    close(fd);

    if (!ok) {
        LOGE("Can't copy %s\n", ASSUMED_UPDATE_BINARY_NAME);
        return 1;
    }

    int pipefd[2];
    pipe(pipefd);

    // When executing the update binary contained in the package, the
    // arguments passed are:
    //
    //   - the version number for this interface
    //
    //   - an fd to which the program can write in order to update the
    //     progress bar.  The program can write single-line commands:
    //
    //        progress <frac> <secs>
    //            fill up the next <frac> part of of the progress bar
    //            over <secs> seconds.  If <secs> is zero, use
    //            set_progress commands to manually control the
    //            progress of this segment of the bar
    //
    //        set_progress <frac>
    //            <frac> should be between 0.0 and 1.0; sets the
    //            progress bar within the segment defined by the most
    //            recent progress command.
    //
    //        firmware <"hboot"|"radio"> <filename>
    //            arrange to install the contents of <filename> in the
    //            given partition on reboot.  (API v2: <filename> may
    //            start with "PACKAGE:" to indicate taking a file from
    //            the OTA package.)
    //
    //        ui_print <string>
    //            display <string> on the screen.
    //
    //   - the name of the package zip file.
    //

    char** args = malloc(sizeof(char*) * 5);
    args[0] = binary;
    args[1] = EXPAND(RECOVERY_API_VERSION);   // defined in Android.mk
    args[2] = malloc(10);
    sprintf(args[2], "%d", pipefd[1]);
    args[3] = (char*)path;
    args[4] = NULL;

    pid_t pid = fork();
    if (pid == 0) {
        close(pipefd[0]);
        execv(binary, args);
        fprintf(stderr, "E:Can't run %s (%s)\n", binary, strerror(errno));
        _exit(-1);
    }
    close(pipefd[1]);

    char* firmware_type = NULL;
    char* firmware_filename = NULL;

    char buffer[81];
    FILE* from_child = fdopen(pipefd[0], "r");
    while (fgets(buffer, sizeof(buffer), from_child) != NULL) {
        LOGI("read: %s", buffer);

        char* command = strtok(buffer, " \n");
        if (command == NULL) {
            continue;
        } else if (strcmp(command, "progress") == 0) {
            char* fraction_s = strtok(NULL, " \n");
            char* seconds_s = strtok(NULL, " \n");

            float fraction = strtof(fraction_s, NULL);
            int seconds = strtol(seconds_s, NULL, 10);

            // ui_show_progress(fraction * (1-VERIFICATION_PROGRESS_FRACTION), seconds);
        } else if (strcmp(command, "set_progress") == 0) {
            char* fraction_s = strtok(NULL, " \n");
            float fraction = strtof(fraction_s, NULL);
            // ui_set_progress(fraction);
        } else if (strcmp(command, "firmware") == 0) {
            char* type = strtok(NULL, " \n");
            char* filename = strtok(NULL, " \n");

            if (type != NULL && filename != NULL) {
                if (firmware_type != NULL) {
                    LOGE("ignoring attempt to do multiple firmware updates");
                } else {
                    firmware_type = strdup(type);
                    firmware_filename = strdup(filename);
                }
            }
        } else if (strcmp(command, "ui_print") == 0) {
            char* str = strtok(NULL, "\n");
            if (str) {
                printf(str);
            } else {
                printf("\n");
            }
        } else {
            LOGE("unknown command [%s]\n", command);
        }
    }
    fclose(from_child);

    int status;
    waitpid(pid, &status, 0);
    if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
        LOGE("Error in %s\n(Status %d)\n", path, WEXITSTATUS(status));
        return INSTALL_ERROR;
    }

    if (firmware_type != NULL) {
        return handle_firmware_update(firmware_type, firmware_filename, zip);
    } else {
        return INSTALL_SUCCESS;
    }
}
コード例 #2
0
ファイル: install.c プロジェクト: XMoon/openrecovery
// If the package contains an update binary, extract it and run it.
static int
try_update_binary(const char *path, ZipArchive *zip) 
{
	int	custom_binary = 0;

	const ZipEntry* or_script_entry =
		      mzFindZipEntry(zip, ASSUMED_OR_UPDATE_SCRIPT_NAME);
		      
	if (or_script_entry != NULL)
	{
		ui_print("使用shell脚本...\n");
		return handle_or_update(path, zip);
	}

	const ZipEntry* binary_entry =
		      mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME);

	if (binary_entry == NULL)
		ui_print("使用默认的updater...\n");
	else
		custom_binary = 1;
  
  char* binary = "/tmp/update_binary";
  unlink(binary);
  
  if (custom_binary)
  {
		int fd = creat(binary, 0755);
		if (fd < 0) 
		{
		  LOGE("无法制作%s\n", binary);
		  return 1;
		}
  
		bool ok = mzExtractZipEntryToFile(zip, binary_entry, fd);
		close(fd);

		if (!ok) 
		{
	    LOGE("无法复制%s\n", ASSUMED_UPDATE_BINARY_NAME);
	    return 1;
		}
	}
	else
		binary = DEFAULT_UPDATE_BINARY_NAME;

	ui_show_indeterminate_progress();
  int pipefd[2];
  pipe(pipefd);

  // When executing the update binary contained in the package, the
  // arguments passed are:
  //
  //   - the version number for this interface
  //
  //   - an fd to which the program can write in order to update the
  //     progress bar.  The program can write single-line commands:
  //
  //        progress <frac> <secs>
  //            fill up the next <frac> part of of the progress bar
  //            over <secs> seconds.  If <secs> is zero, use
  //            set_progress commands to manually control the
  //            progress of this segment of the bar
  //
  //        set_progress <frac>
  //            <frac> should be between 0.0 and 1.0; sets the
  //            progress bar within the segment defined by the most
  //            recent progress command.
  //
  //        firmware <"hboot"|"radio"> <filename>
  //            arrange to install the contents of <filename> in the
  //            given partition on reboot.  (API v2: <filename> may
  //            start with "PACKAGE:" to indicate taking a file from
  //            the OTA package.)
  //
  //        ui_print <string>
  //            display <string> on the screen.
  //
  //				stasis
  //						quit the gui
  //   - the name of the package zip file.
  //

  char** args = malloc(sizeof(char*) * 5);
  args[0] = binary;
  args[1] = EXPAND(RECOVERY_API_VERSION);   // defined in Android.mk
  args[2] = malloc(10);
  sprintf(args[2], "%d", pipefd[1]);
  args[3] = (char*)path;
  args[4] = NULL;

  pid_t pid = fork();
  if (pid == 0) 
  {
    close(pipefd[0]);
    execv(binary, args);
    fprintf(stderr, "E:无法运行%s (%s)\n", binary, strerror(errno));
    _exit(-1);
  }
  close(pipefd[1]);

  char* firmware_type = NULL;
  char* firmware_filename = NULL;

  char buffer[1024];
  FILE* from_child = fdopen(pipefd[0], "r");
  
  ui_set_progress(0.0);
  
  while (fgets(buffer, sizeof(buffer), from_child) != NULL) 
  {
    char* command = strtok(buffer, " \n");
    if (command == NULL) 
    	continue;
   	else if (strcmp(command, "progress") == 0) 
   	{
      char* fraction_s = strtok(NULL, " \n");
      char* seconds_s = strtok(NULL, " \n");

      float fraction = strtof(fraction_s, NULL);
      int seconds = strtol(seconds_s, NULL, 10);

      ui_show_progress(fraction, seconds);
    } 
    else if (strcmp(command, "set_progress") == 0) 
    {
      char* fraction_s = strtok(NULL, " \n");
      float fraction = strtof(fraction_s, NULL);
      ui_set_progress(fraction);
    } 
    else if (strcmp(command, "firmware") == 0) 
    {
      char* type = strtok(NULL, " \n");
      char* filename = strtok(NULL, " \n");

      if (type != NULL && filename != NULL) 
      {
        if (firmware_type != NULL) 
            LOGE("忽略试图进行多个固件更新");
        else 
        {
          firmware_type = strdup(type);
          firmware_filename = strdup(filename);
        }
      }
    } 
    else if (strcmp(command, "ui_print") == 0) 
    {
      char* str = strtok(NULL, "\n");
      if (str) 
        ui_print(str);
      else
        ui_print("\n");       
    }
    else 
      LOGE("未知命令[%s]\n", command);   
  }
  
  fclose(from_child);

  int status;
  waitpid(pid, &status, 0);
  if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 
  {
    LOGE("错误!代码%s\n(Status %d)\n", path, WEXITSTATUS(status));
    return INSTALL_ERROR;
  }

  if (firmware_type != NULL) 
    return handle_firmware_update(firmware_type, firmware_filename, zip);
  else 
    return INSTALL_SUCCESS;
  
}