bool RamdiskUpdater::create_zip()
{
    ErrorCode result;

    // Unlike the old patcher, we'll write directly to the new file
    if (!open_output_archive()) {
        return false;
    }

    void *handle = MinizipUtils::ctx_get_zip_handle(m_z_output);

    if (m_cancelled) return false;

    std::string arch_dir(m_pc.data_directory());
    arch_dir += "/binaries/android/";
    arch_dir += m_info->device().architecture();

    std::vector<CopySpec> toCopy{
        {
            arch_dir + "/mbtool_recovery",
            "META-INF/com/google/android/update-binary"
        }, {
            arch_dir + "/mbtool_recovery.sig",
            "META-INF/com/google/android/update-binary.sig"
        }, {
            m_pc.data_directory() + "/scripts/bb-wrapper.sh",
            "multiboot/bb-wrapper.sh"
        }, {
            m_pc.data_directory() + "/scripts/bb-wrapper.sh.sig",
            "multiboot/bb-wrapper.sh.sig"
        }
    };

    std::vector<std::string> binaries{
        "file-contexts-tool",
        "file-contexts-tool.sig",
        "fsck-wrapper",
        "fsck-wrapper.sig",
        "mbtool",
        "mbtool.sig",
        "mount.exfat",
        "mount.exfat.sig",
    };

    for (auto const &binary : binaries) {
        toCopy.push_back({arch_dir + "/" + binary,
                          "multiboot/binaries/" + binary});
    }

    for (const CopySpec &spec : toCopy) {
        if (m_cancelled) return false;

        result = MinizipUtils::add_file_from_path(
                handle, spec.target, spec.source);
        if (result != ErrorCode::NoError) {
            m_error = result;
            return false;
        }
    }

    if (m_cancelled) return false;

    result = MinizipUtils::add_file_from_data(
            handle, "multiboot/info.prop",
            ZipPatcher::create_info_prop(m_info->rom_id()));
    if (result != ErrorCode::NoError) {
        m_error = result;
        return false;
    }

    if (m_cancelled) return false;

    std::string json;
    if (!device::device_to_json(m_info->device(), json)) {
        m_error = ErrorCode::MemoryAllocationError;
        return false;
    }

    result = MinizipUtils::add_file_from_data(
            handle, "multiboot/device.json", json);
    if (result != ErrorCode::NoError) {
        m_error = result;
        return false;
    }

    if (m_cancelled) return false;

    // Create dummy "installer"
    result = MinizipUtils::add_file_from_data(
            handle, "META-INF/com/google/android/update-binary.orig",
            "#!/sbin/sh");
    if (result != ErrorCode::NoError) {
        m_error = result;
        return false;
    }

    if (m_cancelled) return false;

    return true;
}
예제 #2
0
bool ZIP_Wrapper::uncompress (char* zip_archive, char* path, bool verbose)
{
  //open the zip archive
  unzFile uf=0;
  uf = unzOpen(zip_archive);
  if (uf==0)
    {
      DANCE_ERROR (DANCE_LOG_ERROR,
                   (LM_DEBUG,ACE_TEXT("unzOpen failed to open the")
                    ACE_TEXT(" zipfile\n")));
      return false;
    }
  //get the name of the archive
  ACE_CString arch_dir (path);
  arch_dir += "/";
  //get only the name of the archive; remove path info
  char* n = ACE_OS::strstr (zip_archive, "/");
  char* zip_name = 0;
  while (n != 0)
    {
      zip_name = ++n;
      n = ACE_OS::strstr (n, "/");
    }
  arch_dir += zip_name;
  //NOTE: Assumes .zip or cpk extension
  arch_dir = arch_dir.substring (0, arch_dir.length () - 4);
  //create directory with the name of zip archive
  ACE_OS::mkdir(arch_dir.c_str());
  //if dir exists -1 is returned and ignored
  unz_global_info gi;
  int err = unzGetGlobalInfo(uf, &gi);
  if (err!=UNZ_OK)
    {
      DANCE_ERROR (DANCE_LOG_ERROR, (LM_DEBUG, ACE_TEXT("unzGetGlobalInfo failed to get global")
                           ACE_TEXT(" information about zipfile\n"), err));
      return false;
    }
  err =unzGoToFirstFile(uf);
  if (err!=UNZ_OK)
    {
      DANCE_ERROR (DANCE_LOG_ERROR, (LM_DEBUG,ACE_TEXT("error %d with zipfile in"
                 ACE_TEXT(" unzGoToFirstFile\n")), err));
      return false;
    }
  /* read each entry of zip file, create directory structure if it is
     a non existing directory whereas if it is a file, write the file
     at the proper path in the directory structure */
  for (uLong i=0;i<gi.number_entry;i++)
    {
      char filename_inzip[256];
      unz_file_info file_info;
      err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip,
                                  sizeof(filename_inzip), 0, 0, 0, 0);
      if (err!=UNZ_OK)
        {
          DANCE_ERROR (DANCE_LOG_ERROR,
                       (LM_DEBUG, ACE_TEXT("unzGetCurrentFileInfo failed")
                        ACE_TEXT(" while trying to get information")
                        ACE_TEXT(" about currentfile\n"), err));
          break;
        }
      int direc = checkdir(filename_inzip);
      /* If it is a directory, we create directory structure */
      if (direc==1)
        {
          makethedir(filename_inzip, arch_dir);
        }
      /* If it is a file, we read its data and write the uncompressed
         data to the file with proper path.*/
      else if (direc==0)
        {
          handlethefile(filename_inzip, uf, file_info, verbose, arch_dir);
        }
      if ((i+1)<gi.number_entry)
        {
          err = unzGoToNextFile(uf);
          if (err!=UNZ_OK)
            {
              DANCE_ERROR (DANCE_LOG_ERROR,
                           (LM_ERROR,ACE_TEXT("unzGoToNextFile failed")
                            ACE_TEXT(" while trying to go to")
                            ACE_TEXT(" nextfile\n"), err));
              break;
            }
        }
    }
  unzClose(uf);
  return true;
}