@@ -307,6 +307,7 @@ Undocumented system binaries are all bundled and executable:
|
|||||||
* `ip` (`link monitor neigh rule`);
|
* `ip` (`link monitor neigh rule`);
|
||||||
* `ndc` (`ipfwd` since API 23, `nat` since API 28);
|
* `ndc` (`ipfwd` since API 23, `nat` since API 28);
|
||||||
* `iptables`, `ip6tables` (with correct version corresponding to API level, `-nvx -L <chain>`);
|
* `iptables`, `ip6tables` (with correct version corresponding to API level, `-nvx -L <chain>`);
|
||||||
|
* `sh`;
|
||||||
* `su`.
|
* `su`.
|
||||||
|
|
||||||
If some of these are unavailable, you can alternatively install a recent version (v1.28.1 or higher) of Busybox.
|
If some of these are unavailable, you can alternatively install a recent version (v1.28.1 or higher) of Busybox.
|
||||||
|
|||||||
@@ -19,14 +19,12 @@ import java.io.FileOutputStream
|
|||||||
import java.io.InterruptedIOException
|
import java.io.InterruptedIOException
|
||||||
import java.util.concurrent.Executor
|
import java.util.concurrent.Executor
|
||||||
|
|
||||||
val SHELL = System.getenv("SHELL") ?: "sh"
|
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
class Dump(val path: String, val cacheDir: File = app.deviceStorage.codeCacheDir) : RootCommandNoResult {
|
class Dump(val path: String, val cacheDir: File = app.deviceStorage.codeCacheDir) : RootCommandNoResult {
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
override suspend fun execute() = withContext(Dispatchers.IO) {
|
override suspend fun execute() = withContext(Dispatchers.IO) {
|
||||||
FileOutputStream(path, true).use { out ->
|
FileOutputStream(path, true).use { out ->
|
||||||
val process = ProcessBuilder(SHELL).redirectErrorStream(true).start()
|
val process = ProcessBuilder("sh").redirectErrorStream(true).start()
|
||||||
process.outputStream.bufferedWriter().use { commands ->
|
process.outputStream.bufferedWriter().use { commands ->
|
||||||
// https://android.googlesource.com/platform/external/iptables/+/android-7.0.0_r1/iptables/Android.mk#34
|
// https://android.googlesource.com/platform/external/iptables/+/android-7.0.0_r1/iptables/Android.mk#34
|
||||||
val iptablesSave = if (Build.VERSION.SDK_INT < 24) File(cacheDir, "iptables-save").absolutePath.also {
|
val iptablesSave = if (Build.VERSION.SDK_INT < 24) File(cacheDir, "iptables-save").absolutePath.also {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ object RoutingCommands {
|
|||||||
class Clean : RootCommandOneWay {
|
class Clean : RootCommandOneWay {
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
override suspend fun execute() = withContext(Dispatchers.IO) {
|
override suspend fun execute() = withContext(Dispatchers.IO) {
|
||||||
val process = ProcessBuilder(SHELL).redirectErrorStream(true).start()
|
val process = ProcessBuilder("sh").redirectErrorStream(true).start()
|
||||||
process.outputStream.bufferedWriter().use(Routing.Companion::appendCleanCommands)
|
process.outputStream.bufferedWriter().use(Routing.Companion::appendCleanCommands)
|
||||||
when (val code = process.waitFor()) {
|
when (val code = process.waitFor()) {
|
||||||
0 -> { }
|
0 -> { }
|
||||||
@@ -48,7 +48,6 @@ object RoutingCommands {
|
|||||||
class Process(val command: List<String>, private val redirect: Boolean = false) : RootCommand<ProcessResult> {
|
class Process(val command: List<String>, private val redirect: Boolean = false) : RootCommand<ProcessResult> {
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
override suspend fun execute() = withContext(Dispatchers.IO) {
|
override suspend fun execute() = withContext(Dispatchers.IO) {
|
||||||
val command = if (command[0] == "sh") listOf(SHELL) + command.drop(1) else command
|
|
||||||
val process = ProcessBuilder(command).redirectErrorStream(redirect).start()
|
val process = ProcessBuilder(command).redirectErrorStream(redirect).start()
|
||||||
coroutineScope {
|
coroutineScope {
|
||||||
val output = async { process.inputStream.bufferedReader().readText() }
|
val output = async { process.inputStream.bufferedReader().readText() }
|
||||||
|
|||||||
Reference in New Issue
Block a user