Writes/refreshes the DedSec block inside bash.bashrc. - If menu auto-start is enabled, the menu runs automatically when Termux opens. - If disabled, the auto-start line is removed, but aliases remain so you can start it manually.
(current_language_path, current_style)
| 2043 | |
| 2044 | |
| 2045 | def _transfer_sha256(path): |
| 2046 | digest = hashlib.sha256() |
| 2047 | with open(path, "rb") as handle: |
| 2048 | while True: |
| 2049 | block = handle.read(8 * 1024 * 1024) |
| 2050 | if not block: |
| 2051 | break |
| 2052 | digest.update(block) |
| 2053 | return digest.hexdigest() |
| 2054 | |
| 2055 | |
| 2056 | def _transfer_collect_unzip_runtime(): |
| 2057 | unzip_path = shutil.which("unzip") |
| 2058 | if not unzip_path and shutil.which("pkg"): |
| 2059 | print("[+] Offline restore needs unzip. Trying to prepare it on this phone...") |
| 2060 | try: |
| 2061 | subprocess.run(["pkg", "install", "-y", "unzip"], timeout=240, check=False) |
| 2062 | except Exception: |
| 2063 | pass |
| 2064 | unzip_path = shutil.which("unzip") |
| 2065 | if not unzip_path or not os.path.isfile(unzip_path): |
| 2066 | return [] |
| 2067 | files = [("bin/unzip", unzip_path)] |
| 2068 | try: |
| 2069 | result = subprocess.run(["ldd", unzip_path], capture_output=True, text=True, timeout=20, check=False) |
| 2070 | seen = set() |
| 2071 | for candidate in re.findall(r"(/[^\s()]+\.so(?:\.[0-9]+)*)", (result.stdout or "") + "\n" + (result.stderr or "")): |
| 2072 | if candidate.startswith(TERMUX_TRANSFER_PREFIX + os.sep) and os.path.isfile(candidate): |
| 2073 | name = os.path.basename(candidate) |
| 2074 | if name not in seen: |
| 2075 | seen.add(name) |
| 2076 | files.append(("lib/" + name, candidate)) |
| 2077 | except Exception: |
| 2078 | pass |
| 2079 | return files |
| 2080 | |
| 2081 | |
| 2082 | def _transfer_b64_shell_block(label, path): |
| 2083 | data = base64.b64encode(open(path, "rb").read()).decode("ascii") |
| 2084 | wrapped = "\n".join(textwrap.wrap(data, 76)) |
| 2085 | quoted = shlex.quote(label) |
| 2086 | return f"""mkdir -p "$BOOT/$(dirname {quoted})"\ncat > "$BOOT/{label}.b64" <<'DEDSEC_TRANSFER_B64'\n{wrapped}\nDEDSEC_TRANSFER_B64\nbase64 -d "$BOOT/{label}.b64" > "$BOOT/{label}"\nrm -f "$BOOT/{label}.b64"\n""" |
| 2087 | |
| 2088 | |
| 2089 | def _transfer_install_script(archives, metadata): |
| 2090 | bootstrap_files = _transfer_collect_unzip_runtime() |
| 2091 | bootstrap = "".join(_transfer_b64_shell_block(label, path) for label, path in bootstrap_files) |
| 2092 | if any(label == "bin/unzip" for label, _path in bootstrap_files): |
| 2093 | bootstrap += 'chmod 700 "$BOOT/bin/unzip"\n' |
| 2094 | checks = [] |
| 2095 | for name in archives: |
| 2096 | path = os.path.join(TERMUX_TRANSFER_DIR, name) |
| 2097 | checks.append((_transfer_sha256(path), name, os.path.getsize(path))) |
| 2098 | verify_lines = "\n".join( |
| 2099 | f"verify_archive {shlex.quote(digest)} {shlex.quote(name)} {size}" |
| 2100 | for digest, name, size in checks |
| 2101 | ) |
| 2102 | source_arch = shlex.quote(str(metadata.get("source_arch") or "")) |
no test coverage detected