Esempio n. 1
0
    def patch(self, directory, file_info, bootimages=None):
        # My ROM has dual-boot support built in, so we'll hack around that to
        # support triple, quadruple, ... boot
        updater_script = 'META-INF/com/google/android/updater-script'
        lines = fileio.all_lines(os.path.join(directory, updater_script))

        i = 0
        while i < len(lines):
            # Remove existing dualboot.sh lines
            if 'system/bin/dualboot.sh' in lines[i]:
                del lines[i]

            # Remove confusing messages
            elif 'boot installation is' in lines[i]:
                # Can't remove - sole line inside if statement
                lines[i] = 'ui_print("");\n'
                i += 1

            elif 'set-secondary' in lines[i]:
                lines[i] = 'ui_print("");\n'
                i += 1

            else:
                i += 1

        fileio.write_lines(os.path.join(directory, updater_script), lines)

        # Create /tmp/dualboot.prop
        lines = fileio.all_lines(os.path.join(directory, 'dualboot.sh'))

        lines.append("echo 'ro.dualboot=0' > /tmp/dualboot.prop")

        fileio.write_lines(os.path.join(directory, 'dualboot.sh'), lines)
def multi_boot(directory, bootimg = None, device_check = True,
               partition_config = None):
  updater_script = 'META-INF/com/google/android/updater-script'
  lines = fileio.all_lines(updater_script, directory = directory)

  i = 0
  while i < len(lines):
    # Remove existing dualboot.sh lines
    if 'system/bin/dualboot.sh' in lines[i]:
      del lines[i]

    # Remove confusing messages
    elif 'boot installation is' in lines[i]:
      # Can't remove - sole line inside if statement
      lines[i] = 'ui_print("");\n'
      i += 1

    elif 'set-secondary' in lines[i]:
      lines[i] = 'ui_print("");\n'
      i += 1

    else:
      i += 1

  fileio.write_lines(updater_script, lines, directory = directory)

  # Create /tmp/dualboot.prop
  lines = fileio.all_lines('dualboot.sh', directory = directory)

  lines.append("echo 'ro.dualboot=0' > /tmp/dualboot.prop")

  fileio.write_lines('dualboot.sh', lines, directory = directory)
def system_prop(directory, bootimg = None, device_check = True,
                partition_config = None):
  lines = fileio.all_lines('system/build.prop', directory = directory)

  lines.append('ro.chenxiaolong.patched=%s\n' % partition_config.id)

  fileio.write_lines('system/build.prop', lines, directory = directory)
Esempio n. 4
0
    def patch(self, directory, file_info, bootimages=None):
        # The auto-updater in my ROM needs to know if the ROM has been patched
        lines = fileio.all_lines(os.path.join(directory, 'system/build.prop'))

        lines.append('ro.chenxiaolong.patched=%s\n' % file_info.partconfig.id)

        fileio.write_lines(os.path.join(directory, 'system/build.prop'), lines)
Esempio n. 5
0
    def patch(self, directory, file_info, bootimages=None):
        # My ROM has dual-boot support built in, so we'll hack around that to
        # support triple, quadruple, ... boot
        updater_script = 'META-INF/com/google/android/updater-script'
        lines = fileio.all_lines(os.path.join(directory, updater_script))

        i = 0
        while i < len(lines):
            # Remove existing dualboot.sh lines
            if 'system/bin/dualboot.sh' in lines[i]:
                del lines[i]

            # Remove confusing messages
            elif 'boot installation is' in lines[i]:
                # Can't remove - sole line inside if statement
                lines[i] = 'ui_print("");\n'
                i += 1

            elif 'set-secondary' in lines[i]:
                lines[i] = 'ui_print("");\n'
                i += 1

            else:
                i += 1

        fileio.write_lines(os.path.join(directory, updater_script), lines)

        # Create /tmp/dualboot.prop
        lines = fileio.all_lines(os.path.join(directory, 'dualboot.sh'))

        lines.append("echo 'ro.dualboot=0' > /tmp/dualboot.prop")

        fileio.write_lines(os.path.join(directory, 'dualboot.sh'), lines)
Esempio n. 6
0
    def patch(self, directory, file_info, bootimages=None):
        # The auto-updater in my ROM needs to know if the ROM has been patched
        lines = fileio.all_lines(os.path.join(directory, 'system/build.prop'))

        lines.append('ro.chenxiaolong.patched=%s\n' % file_info.partconfig.id)

        fileio.write_lines(os.path.join(directory, 'system/build.prop'), lines)
def auto_patch(directory, bootimg=None, device_check=True,
               partition_config=None):
    updater_script = 'META-INF/com/google/android/updater-script'

    lines = fileio.all_lines(updater_script, directory=directory)
    attempt_auto_patch(lines, bootimg=bootimg,
                       device_check=device_check,
                       partition_config=partition_config)
    fileio.write_lines(updater_script, lines, directory=directory)
Esempio n. 8
0
    def patch(self, directory, file_info, bootimages=None):
        lines = fileio.all_lines(os.path.join(directory, 'system/build.prop'))

        i = 0
        while i < len(lines):
            if 'dalvik.vm.dexopt-data-only' in lines[i]:
                del lines[i]

            else:
                i += 1

        fileio.write_lines(os.path.join(directory, 'system/build.prop'), lines)
Esempio n. 9
0
    def patch(self, directory, file_info, bootimages=None):
        lines = fileio.all_lines(os.path.join(
            directory, 'system/etc/init.qcom.audio.sh'))

        i = 0
        while i < len(lines):
            if 'snd_soc_msm_2x_Fusion3_auxpcm' in lines[i]:
                del lines[i]

            else:
                i += 1

        fileio.write_lines(os.path.join(
            directory, 'system/etc/init.qcom.audio.sh'), lines)
Esempio n. 10
0
    def patch(self, directory, file_info, bootimages=None):
        updater_script = 'META-INF/com/google/android/updater-script'
        lines = fileio.all_lines(os.path.join(directory, updater_script))

        i = 0
        while i < len(lines):
            if re.search('run_program.*/tmp/wipedata.sh', lines[i]):
                del lines[i]
                StandardPatcher.insert_format_data(i, lines)
                break

            i += 1

        fileio.write_lines(os.path.join(directory, updater_script), lines)
Esempio n. 11
0
    def patch(self, directory, file_info, bootimages=None):
        updater_script = 'META-INF/com/google/android/updater-script'
        lines = fileio.all_lines(os.path.join(directory, updater_script))

        i = 0
        while i < len(lines):
            if re.search('run_program.*/tmp/wipedata.sh', lines[i]):
                del lines[i]
                StandardPatcher.insert_format_data(i, lines)
                break

            i += 1

        fileio.write_lines(os.path.join(directory, updater_script), lines)
Esempio n. 12
0
    def patch(self, directory, file_info, bootimages=None):
        lines = fileio.all_lines(
            os.path.join(directory, 'system/etc/init.qcom.audio.sh'))

        i = 0
        while i < len(lines):
            if 'snd_soc_msm_2x_Fusion3_auxpcm' in lines[i]:
                del lines[i]

            else:
                i += 1

        fileio.write_lines(
            os.path.join(directory, 'system/etc/init.qcom.audio.sh'), lines)
Esempio n. 13
0
def dont_wipe_data(directory, bootimg = None, device_check = True,
                   partition_config = None):
  updater_script = 'META-INF/com/google/android/updater-script'
  lines = fileio.all_lines(updater_script, directory = directory)

  i = 0
  while i < len(lines):
    if re.search('run_program.*/tmp/wipedata.sh', lines[i]):
      del lines[i]
      autopatcher.insert_format_data(i, lines)
      break

    i += 1

  fileio.write_lines(updater_script, lines, directory = directory)
Esempio n. 14
0
    def qcom_audio_fix(directory, bootimg=None, device_check=True,
                       partition_config=None):
        lines = fileio.all_lines('system/etc/init.qcom.audio.sh',
                                 directory=directory)

        i = 0
        while i < len(lines):
            if 'snd_soc_msm_2x_Fusion3_auxpcm' in lines[i]:
                del lines[i]

            else:
                i += 1

        fileio.write_lines('system/etc/init.qcom.audio.sh', lines,
                           directory=directory)
Esempio n. 15
0
    def patch(self, directory, file_info, bootimages=None):
        updater_script = 'META-INF/com/google/android/updater-script'
        lines = fileio.all_lines(os.path.join(directory, updater_script))

        i = 0
        while i < len(lines):
            if re.search('getprop.*/system/build.prop', lines[i]):
                i += StandardPatcher.insert_mount_system(i, lines)
                i += StandardPatcher.insert_mount_cache(i, lines)
                i += StandardPatcher.insert_mount_data(i, lines)
                lines[i] = re.sub('/system', file_info.partconfig.target_system, lines[i])

            i += 1

        fileio.write_lines(os.path.join(directory, updater_script), lines)
Esempio n. 16
0
def fix_aroma(directory, bootimg = None, device_check = True,
              partition_config = None):
  updater_script = 'META-INF/com/google/android/updater-script'
  lines = fileio.all_lines(updater_script, directory = directory)

  i = 0
  while i < len(lines):
    if re.search('getprop.*/system/build.prop', lines[i]):
      i += autopatcher.insert_mount_system(i, lines)
      i += autopatcher.insert_mount_cache(i, lines)
      i += autopatcher.insert_mount_data(i, lines)
      lines[i] = re.sub('/system', partition_config.target_system, lines[i])

    i += 1

  fileio.write_lines(updater_script, lines, directory = directory)
Esempio n. 17
0
    def patch(self, directory, file_info, bootimages=None):
        lines = fileio.all_lines(os.path.join(directory, UPDATER_SCRIPT))

        StandardPatcher.insert_dual_boot_sh(lines)
        StandardPatcher.replace_mount_lines(file_info.device, lines)
        StandardPatcher.replace_unmount_lines(file_info.device, lines)
        StandardPatcher.replace_format_lines(file_info.device, lines)

        if bootimages:
            for img in bootimages:
                StandardPatcher.insert_write_kernel(img, lines)

        # Too many ROMs don't unmount partitions after installation
        StandardPatcher.insert_unmount_everything(len(lines), lines)

        # Remove device checks
        if not file_info.patchinfo.device_check:
            StandardPatcher.remove_device_checks(lines)

        fileio.write_lines(os.path.join(directory, UPDATER_SCRIPT), lines)
Esempio n. 18
0
    def patch(self, directory, file_info, bootimages=None):
        lines = fileio.all_lines(os.path.join(directory, UPDATER_SCRIPT))

        StandardPatcher.insert_dual_boot_sh(lines)
        StandardPatcher.replace_mount_lines(file_info.device, lines)
        StandardPatcher.replace_unmount_lines(file_info.device, lines)
        StandardPatcher.replace_format_lines(file_info.device, lines)

        if bootimages:
            for img in bootimages:
                StandardPatcher.insert_write_kernel(img, lines)

        # Too many ROMs don't unmount partitions after installation
        StandardPatcher.insert_unmount_everything(len(lines), lines)

        # Remove device checks
        if not file_info.patchinfo.device_check:
            StandardPatcher.remove_device_checks(lines)

        fileio.write_lines(os.path.join(directory, UPDATER_SCRIPT), lines)
Esempio n. 19
0
    def patch(self, directory, file_info, bootimages=None):
        aroma_config = 'META-INF/com/google/android/aroma-config'
        lines = fileio.all_lines(os.path.join(directory, aroma_config))

        i = 0
        while i < len(lines):
            if re.search('/system/build.prop', lines[i]):
                # Remove 'raw-' since aroma mounts the partitions directly
                target_dir = re.sub("raw-", "",
                                    file_info.partconfig.target_system)
                lines[i] = re.sub('/system', target_dir, lines[i])

            elif re.search(r"/sbin/mount.*/system", lines[i]):
                i += autopatcher.insert_line(
                    i + 1, re.sub('/system', '/cache', lines[i]), lines)
                i += autopatcher.insert_line(
                    i + 1, re.sub('/system', '/data', lines[i]), lines)

            i += 1

        fileio.write_lines(os.path.join(directory, aroma_config), lines)
Esempio n. 20
0
    def patch(self, directory, file_info, bootimages=None):
        updater_script = 'META-INF/com/google/android/updater-script'

        lines = fileio.all_lines(os.path.join(directory, updater_script))

        StandardPatcher.insert_dual_boot_sh(lines)
        StandardPatcher.replace_mount_lines(file_info.device, lines)
        StandardPatcher.replace_unmount_lines(file_info.device, lines)
        StandardPatcher.replace_format_lines(file_info.device, lines)
        StandardPatcher.insert_unmount_everything(len(lines), lines)

        # Insert set kernel line
        set_kernel_line = 'run_program("/tmp/dualboot.sh", "set-multi-kernel");\n'
        i = len(lines) - 1
        while i > 0:
            if 'Umounting Partitions' in lines[i]:
                lines.insert(i + 1, set_kernel_line)
                break

            i -= 1

        fileio.write_lines(os.path.join(directory, updater_script), lines)
Esempio n. 21
0
    def patch(self, directory, file_info, bootimages=None):
        updater_script = 'META-INF/com/google/android/updater-script'

        lines = fileio.all_lines(os.path.join(directory, updater_script))

        StandardPatcher.insert_dual_boot_sh(lines)
        StandardPatcher.replace_mount_lines(file_info.device, lines)
        StandardPatcher.replace_unmount_lines(file_info.device, lines)
        StandardPatcher.replace_format_lines(file_info.device, lines)
        StandardPatcher.insert_unmount_everything(len(lines), lines)

        # Insert set kernel line
        set_kernel_line = 'run_program("/tmp/dualboot.sh", "set-multi-kernel");\n'
        i = len(lines) - 1
        while i > 0:
            if 'Umounting Partitions' in lines[i]:
                lines.insert(i + 1, set_kernel_line)
                break

            i -= 1

        fileio.write_lines(os.path.join(directory, updater_script), lines)
Esempio n. 22
0
def insert_partition_info(directory, f, config, target_path_only=False):
    magic = '# PATCHER REPLACE ME - DO NOT REMOVE\n'
    lines = fileio.all_lines(f, directory=directory)

    i = 0
    while i < len(lines):
        if magic in lines[i]:
            del lines[i]

            if not target_path_only:
                i += insert_line(i, 'KERNEL_NAME=\"%s\"'
                                    % config.kernel, lines)

                i += insert_line(i, 'DEV_SYSTEM=\"%s\"'
                                    % config.dev_system, lines)
                i += insert_line(i, 'DEV_CACHE=\"%s\"'
                                    % config.dev_cache, lines)
                i += insert_line(i, 'DEV_DATA=\"%s\"'
                                    % config.dev_data, lines)

                i += insert_line(i, 'TARGET_SYSTEM_PARTITION=\"%s\"'
                                    % config.target_system_partition, lines)
                i += insert_line(i, 'TARGET_CACHE_PARTITION=\"%s\"'
                                    % config.target_cache_partition, lines)
                i += insert_line(i, 'TARGET_DATA_PARTITION=\"%s\"'
                                    % config.target_data_partition, lines)

            i += insert_line(i, 'TARGET_SYSTEM=\"%s\"'
                                % config.target_system, lines)
            i += insert_line(i, 'TARGET_CACHE=\"%s\"'
                                % config.target_cache, lines)
            i += insert_line(i, 'TARGET_DATA=\"%s\"'
                                % config.target_data, lines)

            break

        i += 1

    fileio.write_lines(f, lines, directory=directory)
    def patch(self, directory, file_info, bootimages=None):
        updater_script = 'META-INF/com/google/android/updater-script'
        lines = fileio.all_lines(os.path.join(directory, updater_script))

        i = 0
        while i < len(lines):
            if re.search('/tmp/mount.*/system', lines[i]):
                del lines[i]
                i += StandardPatcher.insert_mount_system(i, lines)

            elif re.search('/tmp/mount.*/cache', lines[i]):
                del lines[i]
                i += StandardPatcher.insert_mount_cache(i, lines)

            elif re.search('/tmp/mount.*/data', lines[i]):
                del lines[i]
                i += StandardPatcher.insert_mount_data(i, lines)

            else:
                i += 1

        fileio.write_lines(os.path.join(directory, updater_script), lines)
Esempio n. 24
0
def fix_aroma(directory, bootimg = None, device_check = True,
              partition_config = None):
  aroma_config = 'META-INF/com/google/android/aroma-config'
  lines = fileio.all_lines(aroma_config, directory = directory)

  i = 0
  while i < len(lines):
    if re.search('/system/build.prop', lines[i]):
      # Remove 'raw-' since aroma mounts the partitions directly
      target_dir = re.sub("raw-", "", partition_config.target_system)
      lines[i] = re.sub('/system', target_dir, lines[i])

    elif re.search(r"/sbin/mount.*/system", lines[i]):
      i += autopatcher.insert_line(i + 1, re.sub('/system', '/cache', lines[i]), lines)
      i += autopatcher.insert_line(i + 1, re.sub('/system', '/data', lines[i]), lines)

    elif '~welcome.title' in lines[i]:
      i += autopatcher.insert_line(i + 1, '"***IMPORTANT***: You MUST choose the stock kernel for dual booting to work. If you want to use a custom kernel, you can patch and flash it afterwards.\\n\\n" +', lines)

    i += 1

  fileio.write_lines(aroma_config, lines, directory = directory)
Esempio n. 25
0
def handle_bundled_mount(directory, bootimg = None, device_check = True,
                         partition_config = None):
  updater_script = 'META-INF/com/google/android/updater-script'
  lines = fileio.all_lines(updater_script, directory = directory)

  i = 0
  while i < len(lines):
    if re.search('/tmp/mount.*/system', lines[i]):
      del lines[i]
      i += autopatcher.insert_mount_system(i, lines)

    elif re.search('/tmp/mount.*/cache', lines[i]):
      del lines[i]
      i += autopatcher.insert_mount_cache(i, lines)

    elif re.search('/tmp/mount.*/data', lines[i]):
      del lines[i]
      i += autopatcher.insert_mount_data(i, lines)

    else:
      i += 1

  fileio.write_lines(updater_script, lines, directory = directory)
Esempio n. 26
0
    def patch_zip(self):
        if not OS.is_android():
            OS.ui.info('--- Please wait. This may take a while ---')

        tempdir = tempfile.mkdtemp()
        self.tempdirs.append(tempdir)

        OS.ui.set_task(self.tasks['EXTRACTING_ZIP'])

        OS.ui.details('Loading zip file ...')
        z = zipfile.ZipFile(self.file_info.filename, 'r')

        try:
            z.extract(UPDATER_SCRIPT, path=tempdir)
        except:
            OS.ui.failed('Failed to extract updater-script')
            return None

        z.close()

        OS.ui.clear()

        OS.ui.set_task(self.tasks['PATCHING_FILES'])

        lines = fileio.all_lines(os.path.join(tempdir, UPDATER_SCRIPT))

        i = 0
        i += autopatcher.insert_line(
            i, EXTRACT % (PERM_TOOL, '/tmp/' + PERM_TOOL), lines)
        i += autopatcher.insert_line(
            i, EXTRACT % ('dualboot.sh', '/tmp/dualboot.sh'), lines)
        i += autopatcher.insert_line(i, EXTRACT % ('setfacl', '/tmp/setfacl'),
                                     lines)
        i += autopatcher.insert_line(i,
                                     EXTRACT % ('setfattr', '/tmp/setfattr'),
                                     lines)
        i += autopatcher.insert_line(i, EXTRACT % ('getfacl', '/tmp/getfacl'),
                                     lines)
        i += autopatcher.insert_line(i,
                                     EXTRACT % ('getfattr', '/tmp/getfattr'),
                                     lines)
        i += autopatcher.insert_line(i,
                                     MAKE_EXECUTABLE % ('/tmp/' + PERM_TOOL),
                                     lines)
        i += autopatcher.insert_line(i, MAKE_EXECUTABLE % '/tmp/dualboot.sh',
                                     lines)
        i += autopatcher.insert_line(i, MAKE_EXECUTABLE % '/tmp/setfacl',
                                     lines)
        i += autopatcher.insert_line(i, MAKE_EXECUTABLE % '/tmp/setfattr',
                                     lines)
        i += autopatcher.insert_line(i, MAKE_EXECUTABLE % '/tmp/getfacl',
                                     lines)
        i += autopatcher.insert_line(i, MAKE_EXECUTABLE % '/tmp/getfattr',
                                     lines)
        i += autopatcher.insert_line(i, MOUNT % '/system', lines)
        i += autopatcher.insert_line(i, PERMS_BACKUP % '/system', lines)
        i += autopatcher.insert_line(i, UNMOUNT % '/system', lines)
        i += autopatcher.insert_line(i, MOUNT % '/cache', lines)
        i += autopatcher.insert_line(i, PERMS_BACKUP % '/cache', lines)
        i += autopatcher.insert_line(i, UNMOUNT % '/cache', lines)

        def insert_format_system(index, lines, mount):
            i = 0

            if mount:
                i += autopatcher.insert_line(index + i, MOUNT % '/system',
                                             lines)

            i += autopatcher.insert_line(index + i, FORMAT_SYSTEM, lines)

            if mount:
                i += autopatcher.insert_line(index + i, UNMOUNT % '/system',
                                             lines)

            return i

        def insert_format_cache(index, lines, mount):
            i = 0

            if mount:
                i += autopatcher.insert_line(index + i, MOUNT % '/cache',
                                             lines)

            i += autopatcher.insert_line(index + i, FORMAT_CACHE, lines)

            if mount:
                i += autopatcher.insert_line(index + i, UNMOUNT % '/cache',
                                             lines)

            return i

        psystem = config.get_partition(self.file_info.device, 'system')
        pcache = config.get_partition(self.file_info.device, 'cache')
        replaced_format_system = False
        replaced_format_cache = False

        i = 0
        while i < len(lines):
            if re.search(r"^\s*format\s*\(.*$", lines[i]):
                if 'system' in lines[i] or (psystem and psystem in lines[i]):
                    replaced_format_system = True
                    del lines[i]
                    i += insert_format_system(i, lines, True)

                elif 'cache' in lines[i] or (pcache and pcache in lines[i]):
                    replaced_format_cache = True
                    del lines[i]
                    i += insert_format_cache(i, lines, True)

                else:
                    i += 1

            elif re.search(r'delete_recursive\s*\([^\)]*"/system"', lines[i]):
                replaced_format_system = True
                del lines[i]
                i += insert_format_system(i, lines, False)

            elif re.search(r'delete_recursive\s*\([^\)]*"/cache"', lines[i]):
                replaced_format_cache = True
                del lines[i]
                i += insert_format_cache(i, lines, False)

            else:
                i += 1

        if not replaced_format_system and not replaced_format_cache:
            OS.ui.failed('The patcher could not find any /system or /cache'
                         ' formatting lines in the updater-script file.\n\n'
                         'If the file is a ROM, then something failed. If the'
                         ' file is not a ROM (eg. kernel or mod), it doesn\'t'
                         ' need to be patched.')
            return None

        i += autopatcher.insert_line(i, MOUNT % '/system', lines)
        i += autopatcher.insert_line(i, PERMS_RESTORE % '/system', lines)
        i += autopatcher.insert_line(i, UNMOUNT % '/system', lines)
        i += autopatcher.insert_line(i, MOUNT % '/cache', lines)
        i += autopatcher.insert_line(i, PERMS_RESTORE % '/cache', lines)
        i += autopatcher.insert_line(i, UNMOUNT % '/cache', lines)
        i += autopatcher.insert_line(
            i, 'run_program("/tmp/dualboot.sh", "set-multi-kernel");', lines)

        fileio.write_lines(os.path.join(tempdir, UPDATER_SCRIPT), lines)

        shutil.copy(os.path.join(OS.patchdir, 'dualboot.sh'), tempdir)
        autopatcher.insert_partition_info(os.path.join(tempdir, 'dualboot.sh'),
                                          self.file_info.partconfig)

        OS.ui.set_task(self.tasks['COMPRESSING_ZIP_FILE'])
        OS.ui.details('Opening input and output zip files ...')

        # We can't avoid recompression, unfortunately
        # Only show progress for this stage on Android, since it's, by far, the
        # most time consuming part of the process
        new_zip_file = tempfile.mkstemp()
        z_input = zipfile.ZipFile(self.file_info.filename, 'r')
        z_output = zipfile.ZipFile(new_zip_file[1], 'w', zipfile.ZIP_DEFLATED)

        # Five extra files
        progress_total = len(z_input.infolist()) + 6

        OS.ui.max_progress(progress_total)

        for i in z_input.infolist():
            if i.filename == UPDATER_SCRIPT:
                continue

            OS.ui.details('Adding file to zip: %s' % i.filename)
            OS.ui.progress()

            in_info = z_input.getinfo(i.filename)
            z_output.writestr(in_info, z_input.read(in_info))

        OS.ui.clear()

        z_input.close()

        OS.ui.details('Adding file to zip: ' + UPDATER_SCRIPT)
        OS.ui.progress()
        z_output.write(os.path.join(tempdir, UPDATER_SCRIPT),
                       arcname=UPDATER_SCRIPT)
        OS.ui.details('Adding file to zip: ' + 'dualboot.sh')
        OS.ui.progress()
        z_output.write(os.path.join(tempdir, 'dualboot.sh'),
                       arcname='dualboot.sh')

        for f in [PERM_TOOL, 'setfacl', 'setfattr', 'getfacl', 'getfattr']:
            OS.ui.details('Adding file to zip: ' + f)
            OS.ui.progress()
            z_output.write(os.path.join(OS.patchdir, f), arcname=f)

        OS.ui.clear()

        z_output.close()

        os.close(new_zip_file[0])
        return new_zip_file[1]
Esempio n. 27
0
    def patch_zip(self):
        if not OS.is_android():
            OS.ui.info('--- Please wait. This may take a while ---')

        tempdir = tempfile.mkdtemp()
        self.tempdirs.append(tempdir)

        OS.ui.set_task(self.tasks['EXTRACTING_ZIP'])

        OS.ui.details('Loading zip file ...')
        z = zipfile.ZipFile(self.file_info.filename, 'r')

        try:
            z.extract(UPDATER_SCRIPT, path=tempdir)
        except:
            OS.ui.failed('Failed to extract updater-script')
            return None

        z.close()

        OS.ui.clear()

        OS.ui.set_task(self.tasks['PATCHING_FILES'])

        lines = fileio.all_lines(os.path.join(tempdir, UPDATER_SCRIPT))

        i = 0
        i += autopatcher.insert_line(
            i, EXTRACT % (PERM_TOOL, '/tmp/' + PERM_TOOL), lines)
        i += autopatcher.insert_line(
            i, EXTRACT % ('dualboot.sh', '/tmp/dualboot.sh'), lines)
        i += autopatcher.insert_line(
            i, EXTRACT % ('setfacl', '/tmp/setfacl'), lines)
        i += autopatcher.insert_line(
            i, EXTRACT % ('setfattr', '/tmp/setfattr'), lines)
        i += autopatcher.insert_line(
            i, EXTRACT % ('getfacl', '/tmp/getfacl'), lines)
        i += autopatcher.insert_line(
            i, EXTRACT % ('getfattr', '/tmp/getfattr'), lines)
        i += autopatcher.insert_line(
            i, MAKE_EXECUTABLE % ('/tmp/' + PERM_TOOL), lines)
        i += autopatcher.insert_line(
            i, MAKE_EXECUTABLE % '/tmp/dualboot.sh', lines)
        i += autopatcher.insert_line(
            i, MAKE_EXECUTABLE % '/tmp/setfacl', lines)
        i += autopatcher.insert_line(
            i, MAKE_EXECUTABLE % '/tmp/setfattr', lines)
        i += autopatcher.insert_line(
            i, MAKE_EXECUTABLE % '/tmp/getfacl', lines)
        i += autopatcher.insert_line(
            i, MAKE_EXECUTABLE % '/tmp/getfattr', lines)
        i += autopatcher.insert_line(
            i, MOUNT % '/system', lines)
        i += autopatcher.insert_line(
            i, PERMS_BACKUP % '/system', lines)
        i += autopatcher.insert_line(
            i, UNMOUNT % '/system', lines)
        i += autopatcher.insert_line(
            i, MOUNT % '/cache', lines)
        i += autopatcher.insert_line(
            i, PERMS_BACKUP % '/cache', lines)
        i += autopatcher.insert_line(
            i, UNMOUNT % '/cache', lines)

        def insert_format_system(index, lines, mount):
            i = 0

            if mount:
                i += autopatcher.insert_line(
                    index + i, MOUNT % '/system', lines)

            i += autopatcher.insert_line(index + i, FORMAT_SYSTEM, lines)

            if mount:
                i += autopatcher.insert_line(
                    index + i, UNMOUNT % '/system', lines)

            return i

        def insert_format_cache(index, lines, mount):
            i = 0

            if mount:
                i += autopatcher.insert_line(
                    index + i, MOUNT % '/cache', lines)

            i += autopatcher.insert_line(index + i, FORMAT_CACHE, lines)

            if mount:
                i += autopatcher.insert_line(
                    index + i, UNMOUNT % '/cache', lines)

            return i

        psystem = config.get_partition(self.file_info.device, 'system')
        pcache = config.get_partition(self.file_info.device, 'cache')
        replaced_format_system = False
        replaced_format_cache = False

        i = 0
        while i < len(lines):
            if re.search(r"^\s*format\s*\(.*$", lines[i]):
                if 'system' in lines[i] or (psystem and psystem in lines[i]):
                    replaced_format_system = True
                    del lines[i]
                    i += insert_format_system(i, lines, True)

                elif 'cache' in lines[i] or (pcache and pcache in lines[i]):
                    replaced_format_cache = True
                    del lines[i]
                    i += insert_format_cache(i, lines, True)

                else:
                    i += 1

            elif re.search(r'delete_recursive\s*\([^\)]*"/system"', lines[i]):
                replaced_format_system = True
                del lines[i]
                i += insert_format_system(i, lines, False)

            elif re.search(r'delete_recursive\s*\([^\)]*"/cache"', lines[i]):
                replaced_format_cache = True
                del lines[i]
                i += insert_format_cache(i, lines, False)

            else:
                i += 1

        if not replaced_format_system and not replaced_format_cache:
            OS.ui.failed('The patcher could not find any /system or /cache'
                         ' formatting lines in the updater-script file.\n\n'
                         'If the file is a ROM, then something failed. If the'
                         ' file is not a ROM (eg. kernel or mod), it doesn\'t'
                         ' need to be patched.')
            return None

        i += autopatcher.insert_line(
            i, MOUNT % '/system', lines)
        i += autopatcher.insert_line(
            i, PERMS_RESTORE % '/system', lines)
        i += autopatcher.insert_line(
            i, UNMOUNT % '/system', lines)
        i += autopatcher.insert_line(
            i, MOUNT % '/cache', lines)
        i += autopatcher.insert_line(
            i, PERMS_RESTORE % '/cache', lines)
        i += autopatcher.insert_line(
            i, UNMOUNT % '/cache', lines)
        i += autopatcher.insert_line(
            i, 'run_program("/tmp/dualboot.sh", "set-multi-kernel");', lines)

        fileio.write_lines(os.path.join(tempdir, UPDATER_SCRIPT), lines)

        shutil.copy(os.path.join(OS.patchdir, 'dualboot.sh'), tempdir)
        autopatcher.insert_partition_info(
            os.path.join(tempdir, 'dualboot.sh'),
            self.file_info.partconfig)

        OS.ui.set_task(self.tasks['COMPRESSING_ZIP_FILE'])
        OS.ui.details('Opening input and output zip files ...')

        # We can't avoid recompression, unfortunately
        # Only show progress for this stage on Android, since it's, by far, the
        # most time consuming part of the process
        new_zip_file = tempfile.mkstemp()
        z_input = zipfile.ZipFile(self.file_info.filename, 'r')
        z_output = zipfile.ZipFile(new_zip_file[1], 'w', zipfile.ZIP_DEFLATED)

        # Five extra files
        progress_total = len(z_input.infolist()) + 6

        OS.ui.max_progress(progress_total)

        for i in z_input.infolist():
            if i.filename == UPDATER_SCRIPT:
                continue

            OS.ui.details('Adding file to zip: %s' % i.filename)
            OS.ui.progress()

            in_info = z_input.getinfo(i.filename)
            z_output.writestr(in_info, z_input.read(in_info))

        OS.ui.clear()

        z_input.close()

        OS.ui.details('Adding file to zip: ' + UPDATER_SCRIPT)
        OS.ui.progress()
        z_output.write(os.path.join(tempdir, UPDATER_SCRIPT),
                       arcname=UPDATER_SCRIPT)
        OS.ui.details('Adding file to zip: ' + 'dualboot.sh')
        OS.ui.progress()
        z_output.write(os.path.join(tempdir, 'dualboot.sh'),
                       arcname='dualboot.sh')

        for f in [PERM_TOOL, 'setfacl', 'setfattr', 'getfacl', 'getfattr']:
            OS.ui.details('Adding file to zip: ' + f)
            OS.ui.progress()
            z_output.write(os.path.join(OS.patchdir, f), arcname=f)

        OS.ui.clear()

        z_output.close()

        os.close(new_zip_file[0])
        return new_zip_file[1]