Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
6933bcf7
Commit
6933bcf7
authored
Jul 17, 2017
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge shells
parent
2ea046cd
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
189 additions
and
256 deletions
+189
-256
FlashActivity.java
app/src/main/java/com/topjohnwu/magisk/FlashActivity.java
+1
-1
MagiskFragment.java
app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java
+51
-88
MagiskLogFragment.java
...src/main/java/com/topjohnwu/magisk/MagiskLogFragment.java
+3
-3
MagiskManager.java
app/src/main/java/com/topjohnwu/magisk/MagiskManager.java
+28
-13
SettingsActivity.java
app/src/main/java/com/topjohnwu/magisk/SettingsActivity.java
+4
-4
SplashActivity.java
app/src/main/java/com/topjohnwu/magisk/SplashActivity.java
+4
-4
ModulesAdapter.java
...in/java/com/topjohnwu/magisk/adapters/ModulesAdapter.java
+1
-1
FlashZip.java
app/src/main/java/com/topjohnwu/magisk/asyncs/FlashZip.java
+3
-3
GetBootBlocks.java
.../main/java/com/topjohnwu/magisk/asyncs/GetBootBlocks.java
+0
-29
LoadModules.java
...rc/main/java/com/topjohnwu/magisk/asyncs/LoadModules.java
+2
-2
MagiskHide.java
...src/main/java/com/topjohnwu/magisk/asyncs/MagiskHide.java
+1
-1
Logger.java
app/src/main/java/com/topjohnwu/magisk/utils/Logger.java
+4
-4
Shell.java
app/src/main/java/com/topjohnwu/magisk/utils/Shell.java
+84
-95
StreamGobbler.java
...c/main/java/com/topjohnwu/magisk/utils/StreamGobbler.java
+3
-8
No files found.
app/src/main/java/com/topjohnwu/magisk/FlashActivity.java
View file @
6933bcf7
...
...
@@ -35,7 +35,7 @@ public class FlashActivity extends Activity {
@OnClick
(
R
.
id
.
reboot
)
public
void
reboot
()
{
Shell
.
get
Root
Shell
(
this
).
su_raw
(
"reboot"
);
Shell
.
getShell
(
this
).
su_raw
(
"reboot"
);
}
@Override
...
...
app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java
View file @
6933bcf7
This diff is collapsed.
Click to expand it.
app/src/main/java/com/topjohnwu/magisk/MagiskLogFragment.java
View file @
6933bcf7
...
...
@@ -142,7 +142,7 @@ public class MagiskLogFragment extends Fragment {
mode
=
(
int
)
params
[
0
];
switch
(
mode
)
{
case
0
:
List
<
String
>
logList
=
Utils
.
readFile
(
magiskManager
.
rootS
hell
,
MAGISK_LOG
);
List
<
String
>
logList
=
Utils
.
readFile
(
magiskManager
.
s
hell
,
MAGISK_LOG
);
if
(
Utils
.
isValidShellResponse
(
logList
))
{
StringBuilder
llog
=
new
StringBuilder
(
15
*
10
*
1024
);
...
...
@@ -154,7 +154,7 @@ public class MagiskLogFragment extends Fragment {
return
""
;
case
1
:
magiskManager
.
rootS
hell
.
su_raw
(
"echo > "
+
MAGISK_LOG
);
magiskManager
.
s
hell
.
su_raw
(
"echo > "
+
MAGISK_LOG
);
SnackbarMaker
.
make
(
txtLog
,
R
.
string
.
logs_cleared
,
Snackbar
.
LENGTH_SHORT
).
show
();
return
""
;
...
...
@@ -184,7 +184,7 @@ public class MagiskLogFragment extends Fragment {
return
false
;
}
List
<
String
>
in
=
Utils
.
readFile
(
magiskManager
.
rootS
hell
,
MAGISK_LOG
);
List
<
String
>
in
=
Utils
.
readFile
(
magiskManager
.
s
hell
,
MAGISK_LOG
);
if
(
Utils
.
isValidShellResponse
(
in
))
{
try
(
FileWriter
out
=
new
FileWriter
(
targetFile
))
{
...
...
app/src/main/java/com/topjohnwu/magisk/MagiskManager.java
View file @
6933bcf7
...
...
@@ -38,7 +38,6 @@ public class MagiskManager extends Application {
public
static
final
String
NOTIFICATION_CHANNEL
=
"magisk_update_notice"
;
// Events
public
final
CallbackEvent
<
Void
>
blockDetectionDone
=
new
CallbackEvent
<>();
public
final
CallbackEvent
<
Void
>
magiskHideDone
=
new
CallbackEvent
<>();
public
final
CallbackEvent
<
Void
>
reloadMainActivity
=
new
CallbackEvent
<>();
public
final
CallbackEvent
<
Void
>
moduleLoadDone
=
new
CallbackEvent
<>();
...
...
@@ -88,7 +87,7 @@ public class MagiskManager extends Application {
// Global resources
public
SharedPreferences
prefs
;
public
SuDatabaseHelper
suDB
;
public
Shell
rootS
hell
;
public
Shell
s
hell
;
private
static
Handler
mHandler
=
new
Handler
();
...
...
@@ -97,7 +96,7 @@ public class MagiskManager extends Application {
super
.
onCreate
();
new
File
(
getApplicationInfo
().
dataDir
).
mkdirs
();
/* Create the app data directory */
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
this
);
rootShell
=
Shell
.
getRoo
tShell
();
shell
=
Shell
.
ge
tShell
();
}
public
void
toast
(
String
msg
,
int
duration
)
{
...
...
@@ -121,11 +120,12 @@ public class MagiskManager extends Application {
updateNotification
=
prefs
.
getBoolean
(
"notification"
,
true
);
initSU
();
updateMagiskInfo
();
updateBlockInfo
();
// Initialize busybox
File
busybox
=
new
File
(
getApplicationInfo
().
dataDir
+
"/busybox/busybox"
);
if
(!
busybox
.
exists
()
||
!
TextUtils
.
equals
(
prefs
.
getString
(
"busybox_version"
,
""
),
BUSYBOX_VERSION
))
{
busybox
.
getParentFile
().
mkdirs
();
rootS
hell
.
su_raw
(
s
hell
.
su_raw
(
"cp -f "
+
new
File
(
getApplicationInfo
().
nativeLibraryDir
,
"libbusybox.so"
)
+
" "
+
busybox
,
"chmod -R 755 "
+
busybox
.
getParent
(),
busybox
+
" --install -s "
+
busybox
.
getParent
()
...
...
@@ -137,7 +137,7 @@ public class MagiskManager extends Application {
.
putBoolean
(
"magiskhide"
,
magiskHide
)
.
putBoolean
(
"notification"
,
updateNotification
)
.
putBoolean
(
"hosts"
,
new
File
(
"/magisk/.core/hosts"
).
exists
())
.
putBoolean
(
"disable"
,
Utils
.
itemExist
(
rootS
hell
,
MAGISK_DISABLE_FILE
))
.
putBoolean
(
"disable"
,
Utils
.
itemExist
(
s
hell
,
MAGISK_DISABLE_FILE
))
.
putBoolean
(
"su_reauth"
,
suReauth
)
.
putString
(
"su_request_timeout"
,
String
.
valueOf
(
suRequestTimeout
))
.
putString
(
"su_auto_response"
,
String
.
valueOf
(
suResponseType
))
...
...
@@ -148,7 +148,7 @@ public class MagiskManager extends Application {
.
putString
(
"busybox_version"
,
BUSYBOX_VERSION
)
.
apply
();
// Add busybox to PATH
rootS
hell
.
su_raw
(
"PATH=$PATH:"
+
busybox
.
getParent
());
s
hell
.
su_raw
(
"PATH=$PATH:"
+
busybox
.
getParent
());
// Create notification channel on Android O
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
...
...
@@ -170,7 +170,7 @@ public class MagiskManager extends Application {
public
void
initSU
()
{
initSUConfig
();
List
<
String
>
ret
=
S
hell
.
sh
(
"su -v"
);
List
<
String
>
ret
=
s
hell
.
sh
(
"su -v"
);
if
(
Utils
.
isValidShellResponse
(
ret
))
{
suVersion
=
ret
.
get
(
0
);
isSuClient
=
suVersion
.
toUpperCase
().
contains
(
"MAGISK"
);
...
...
@@ -184,9 +184,9 @@ public class MagiskManager extends Application {
public
void
updateMagiskInfo
()
{
List
<
String
>
ret
;
ret
=
S
hell
.
sh
(
"magisk -v"
);
ret
=
s
hell
.
sh
(
"magisk -v"
);
if
(!
Utils
.
isValidShellResponse
(
ret
))
{
ret
=
S
hell
.
sh
(
"getprop magisk.version"
);
ret
=
s
hell
.
sh
(
"getprop magisk.version"
);
if
(
Utils
.
isValidShellResponse
(
ret
))
{
try
{
magiskVersionString
=
ret
.
get
(
0
);
...
...
@@ -195,24 +195,39 @@ public class MagiskManager extends Application {
}
}
else
{
magiskVersionString
=
ret
.
get
(
0
).
split
(
":"
)[
0
];
ret
=
S
hell
.
sh
(
"magisk -V"
);
ret
=
s
hell
.
sh
(
"magisk -V"
);
try
{
magiskVersionCode
=
Integer
.
parseInt
(
ret
.
get
(
0
));
}
catch
(
NumberFormatException
ignored
)
{}
}
ret
=
S
hell
.
sh
(
"getprop "
+
DISABLE_INDICATION_PROP
);
ret
=
s
hell
.
sh
(
"getprop "
+
DISABLE_INDICATION_PROP
);
try
{
disabled
=
Utils
.
isValidShellResponse
(
ret
)
&&
Integer
.
parseInt
(
ret
.
get
(
0
))
!=
0
;
}
catch
(
NumberFormatException
e
)
{
disabled
=
false
;
}
ret
=
S
hell
.
sh
(
"getprop "
+
MAGISKHIDE_PROP
);
ret
=
s
hell
.
sh
(
"getprop "
+
MAGISKHIDE_PROP
);
try
{
magiskHide
=
!
Utils
.
isValidShellResponse
(
ret
)
||
Integer
.
parseInt
(
ret
.
get
(
0
))
!=
0
;
}
catch
(
NumberFormatException
e
)
{
magiskHide
=
true
;
}
}
public
void
updateBlockInfo
()
{
List
<
String
>
res
=
shell
.
su
(
"for BLOCK in boot_a BOOT_A kern-a KERN-A android_boot ANDROID_BOOT kernel KERNEL boot BOOT lnx LNX; do"
,
"BOOTIMAGE=`ls /dev/block/by-name/$BLOCK || ls /dev/block/platform/*/by-name/$BLOCK || ls /dev/block/platform/*/*/by-name/$BLOCK` 2>/dev/null"
,
"[ ! -z \"$BOOTIMAGE\" ] && break"
,
"done"
,
"[ ! -z \"$BOOTIMAGE\" -a -L \"$BOOTIMAGE\" ] && BOOTIMAGE=`readlink $BOOTIMAGE`"
,
"echo \"$BOOTIMAGE\""
);
if
(
Utils
.
isValidShellResponse
(
res
))
{
bootBlock
=
res
.
get
(
0
);
}
else
{
blockList
=
shell
.
su
(
"ls -d /dev/block/mmc* /dev/block/sd* 2>/dev/null"
);
}
}
}
app/src/main/java/com/topjohnwu/magisk/SettingsActivity.java
View file @
6933bcf7
...
...
@@ -149,9 +149,9 @@ public class SettingsActivity extends Activity {
case
"disable"
:
enabled
=
prefs
.
getBoolean
(
"disable"
,
false
);
if
(
enabled
)
{
Utils
.
createFile
(
magiskManager
.
rootS
hell
,
MagiskManager
.
MAGISK_DISABLE_FILE
);
Utils
.
createFile
(
magiskManager
.
s
hell
,
MagiskManager
.
MAGISK_DISABLE_FILE
);
}
else
{
Utils
.
removeItem
(
magiskManager
.
rootS
hell
,
MagiskManager
.
MAGISK_DISABLE_FILE
);
Utils
.
removeItem
(
magiskManager
.
s
hell
,
MagiskManager
.
MAGISK_DISABLE_FILE
);
}
Toast
.
makeText
(
getActivity
(),
R
.
string
.
settings_reboot_toast
,
Toast
.
LENGTH_LONG
).
show
();
break
;
...
...
@@ -175,11 +175,11 @@ public class SettingsActivity extends Activity {
case
"hosts"
:
enabled
=
prefs
.
getBoolean
(
"hosts"
,
false
);
if
(
enabled
)
{
magiskManager
.
rootS
hell
.
su_raw
(
magiskManager
.
s
hell
.
su_raw
(
"cp -af /system/etc/hosts /magisk/.core/hosts"
,
"mount -o bind /magisk/.core/hosts /system/etc/hosts"
);
}
else
{
magiskManager
.
rootS
hell
.
su_raw
(
magiskManager
.
s
hell
.
su_raw
(
"umount -l /system/etc/hosts"
,
"rm -f /magisk/.core/hosts"
);
}
...
...
app/src/main/java/com/topjohnwu/magisk/SplashActivity.java
View file @
6933bcf7
...
...
@@ -8,7 +8,6 @@ import android.content.Intent;
import
android.os.Bundle
;
import
android.text.TextUtils
;
import
com.topjohnwu.magisk.asyncs.GetBootBlocks
;
import
com.topjohnwu.magisk.asyncs.LoadApps
;
import
com.topjohnwu.magisk.asyncs.LoadModules
;
import
com.topjohnwu.magisk.asyncs.LoadRepos
;
...
...
@@ -25,12 +24,13 @@ public class SplashActivity extends Activity{
super
.
onCreate
(
savedInstanceState
);
// Init the info and configs and root sh
ell
// Init the info and configs and root sh
getApplicationContext
().
init
();
// Now fire all async tasks
new
GetBootBlocks
(
this
).
exec
();
new
LoadModules
(
this
).
setCallBack
(()
->
new
LoadRepos
(
this
).
exec
()).
exec
();
new
LoadModules
(
this
)
.
setCallBack
(()
->
new
LoadRepos
(
this
).
exec
())
.
exec
();
new
LoadApps
(
this
).
exec
();
if
(
Utils
.
checkNetworkStatus
(
this
))
{
...
...
app/src/main/java/com/topjohnwu/magisk/adapters/ModulesAdapter.java
View file @
6933bcf7
...
...
@@ -38,7 +38,7 @@ public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHold
@Override
public
void
onBindViewHolder
(
final
ViewHolder
holder
,
int
position
)
{
Context
context
=
holder
.
itemView
.
getContext
();
Shell
rootShell
=
Shell
.
get
Root
Shell
(
context
);
Shell
rootShell
=
Shell
.
getShell
(
context
);
final
Module
module
=
mList
.
get
(
position
);
String
version
=
module
.
getVersion
();
...
...
app/src/main/java/com/topjohnwu/magisk/asyncs/FlashZip.java
View file @
6933bcf7
...
...
@@ -63,7 +63,7 @@ public class FlashZip extends ParallelTask<Void, String, Integer> {
private
boolean
unzipAndCheck
()
throws
Exception
{
ZipUtils
.
unzip
(
mCachedFile
,
mCachedFile
.
getParentFile
(),
"META-INF/com/google/android"
);
List
<
String
>
ret
=
Utils
.
readFile
(
magiskManager
.
rootS
hell
,
mCheckFile
.
getPath
());
List
<
String
>
ret
=
Utils
.
readFile
(
magiskManager
.
s
hell
,
mCheckFile
.
getPath
());
return
Utils
.
isValidShellResponse
(
ret
)
&&
ret
.
get
(
0
).
contains
(
"#MAGISK"
);
}
...
...
@@ -84,7 +84,7 @@ public class FlashZip extends ParallelTask<Void, String, Integer> {
copyToCache
();
if
(!
unzipAndCheck
())
return
0
;
mList
.
add
(
magiskManager
.
getString
(
R
.
string
.
zip_install_progress_msg
,
mFilename
));
magiskManager
.
rootS
hell
.
su
(
mList
,
magiskManager
.
s
hell
.
su
(
mList
,
"BOOTMODE=true sh "
+
mScriptFile
+
" dummy 1 "
+
mCachedFile
+
" && echo 'Success!' || echo 'Failed!'"
);
...
...
@@ -99,7 +99,7 @@ public class FlashZip extends ParallelTask<Void, String, Integer> {
// -1 = error, manual install; 0 = invalid zip; 1 = success
@Override
protected
void
onPostExecute
(
Integer
result
)
{
magiskManager
.
rootS
hell
.
su_raw
(
magiskManager
.
s
hell
.
su_raw
(
"rm -rf "
+
mCachedFile
.
getParent
()
+
"/*"
,
"rm -rf "
+
MagiskManager
.
TMP_FOLDER_PATH
);
...
...
app/src/main/java/com/topjohnwu/magisk/asyncs/GetBootBlocks.java
deleted
100644 → 0
View file @
2ea046cd
package
com
.
topjohnwu
.
magisk
.
asyncs
;
import
android.app.Activity
;
import
com.topjohnwu.magisk.utils.Utils
;
public
class
GetBootBlocks
extends
ParallelTask
<
Void
,
Void
,
Void
>
{
public
GetBootBlocks
(
Activity
context
)
{
super
(
context
);
}
@Override
protected
Void
doInBackground
(
Void
...
params
)
{
magiskManager
.
blockList
=
magiskManager
.
rootShell
.
su
(
"find /dev/block -type b -maxdepth 1 | grep -v -E \"loop|ram|dm-0\""
);
if
(
magiskManager
.
bootBlock
==
null
)
{
magiskManager
.
bootBlock
=
Utils
.
detectBootImage
(
magiskManager
.
rootShell
);
}
return
null
;
}
@Override
protected
void
onPostExecute
(
Void
v
)
{
magiskManager
.
blockDetectionDone
.
trigger
();
super
.
onPostExecute
(
v
);
}
}
app/src/main/java/com/topjohnwu/magisk/asyncs/LoadModules.java
View file @
6933bcf7
...
...
@@ -21,10 +21,10 @@ public class LoadModules extends ParallelTask<Void, Void, Void> {
magiskManager
.
moduleMap
=
new
ValueSortedMap
<>();
for
(
String
path
:
Utils
.
getModList
(
magiskManager
.
rootS
hell
,
MagiskManager
.
MAGISK_PATH
))
{
for
(
String
path
:
Utils
.
getModList
(
magiskManager
.
s
hell
,
MagiskManager
.
MAGISK_PATH
))
{
Logger
.
dev
(
"LoadModules: Adding modules from "
+
path
);
try
{
Module
module
=
new
Module
(
magiskManager
.
rootS
hell
,
path
);
Module
module
=
new
Module
(
magiskManager
.
s
hell
,
path
);
magiskManager
.
moduleMap
.
put
(
module
.
getId
(),
module
);
}
catch
(
BaseModule
.
CacheModException
ignored
)
{}
}
...
...
app/src/main/java/com/topjohnwu/magisk/asyncs/MagiskHide.java
View file @
6933bcf7
...
...
@@ -15,7 +15,7 @@ public class MagiskHide extends ParallelTask<Object, Void, Void> {
@Override
protected
Void
doInBackground
(
Object
...
params
)
{
String
command
=
(
String
)
params
[
0
];
List
<
String
>
ret
=
magiskManager
.
rootS
hell
.
su
(
"magiskhide --"
+
command
);
List
<
String
>
ret
=
magiskManager
.
s
hell
.
su
(
"magiskhide --"
+
command
);
if
(
isList
)
{
magiskManager
.
magiskHideList
=
ret
;
}
...
...
app/src/main/java/com/topjohnwu/magisk/utils/Logger.java
View file @
6933bcf7
...
...
@@ -37,13 +37,13 @@ public class Logger {
dev
(
String
.
format
(
Locale
.
US
,
fmt
,
args
));
}
public
static
void
shell
(
boolean
root
,
String
line
)
{
public
static
void
shell
(
String
line
)
{
if
(
MagiskManager
.
shellLogging
)
{
Log
.
d
(
DEBUG_TAG
,
(
root
?
"MANAGERSU: "
:
"MANAGERSH: "
)
+
line
);
Log
.
d
(
DEBUG_TAG
,
"SHELL: "
+
line
);
}
}
public
static
void
shell
(
boolean
root
,
String
fmt
,
Object
...
args
)
{
shell
(
root
,
String
.
format
(
Locale
.
US
,
fmt
,
args
));
public
static
void
shell
(
String
fmt
,
Object
...
args
)
{
shell
(
String
.
format
(
Locale
.
US
,
fmt
,
args
));
}
}
app/src/main/java/com/topjohnwu/magisk/utils/Shell.java
View file @
6933bcf7
...
...
@@ -2,11 +2,12 @@ package com.topjohnwu.magisk.utils;
import
android.content.Context
;
import
java.io.BufferedReader
;
import
java.io.DataInputStream
;
import
java.io.DataOutputStream
;
import
java.io.IOException
;
import
java.io.InputStreamReader
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
/**
...
...
@@ -18,145 +19,133 @@ public class Shell {
// -1 = problematic/unknown issue; 0 = not rooted; 1 = properly rooted
public
static
int
rootStatus
;
private
final
Process
rootShell
;
private
final
DataOutputStream
root
STDIN
;
private
final
DataInputStream
root
STDOUT
;
private
final
Process
shellProcess
;
private
final
DataOutputStream
STDIN
;
private
final
DataInputStream
STDOUT
;
private
boolean
isValid
;
private
Shell
()
{
Process
process
;
rootStatus
=
1
;
Process
process
=
null
;
DataOutputStream
in
=
null
;
DataInputStream
out
=
null
;
try
{
process
=
Runtime
.
getRuntime
().
exec
(
"su"
);
in
=
new
DataOutputStream
(
process
.
getOutputStream
());
out
=
new
DataInputStream
(
process
.
getInputStream
());
}
catch
(
IOException
e
)
{
// No root
rootStatus
=
0
;
rootShell
=
null
;
rootSTDIN
=
null
;
rootSTDOUT
=
null
;
isValid
=
false
;
return
;
}
rootStatus
=
1
;
isValid
=
true
;
rootShell
=
process
;
rootSTDIN
=
new
DataOutputStream
(
rootShell
.
getOutputStream
());
rootSTDOUT
=
new
DataInputStream
(
rootShell
.
getInputStream
());
su_raw
(
"umask 022"
);
List
<
String
>
ret
=
su
(
"echo -BOC-"
,
"id"
);
if
(
ret
.
isEmpty
())
{
// Something wrong with root, not allowed?
rootStatus
=
-
1
;
return
;
}
for
(
String
line
:
ret
)
{
if
(
line
.
contains
(
"uid="
))
{
// id command is working, let's see if we are actually root
rootStatus
=
line
.
contains
(
"uid=0"
)
?
1
:
-
1
;
return
;
}
else
if
(!
line
.
contains
(
"-BOC-"
))
{
rootStatus
=
-
1
;
return
;
while
(
true
)
{
if
(
rootAccess
())
{
try
{
in
.
write
((
"id\n"
).
getBytes
(
"UTF-8"
));
in
.
flush
();
String
s
=
new
BufferedReader
(
new
InputStreamReader
(
out
)).
readLine
();
if
(
s
.
isEmpty
()
||
!
s
.
contains
(
"uid=0"
))
{
in
.
close
();
out
.
close
();
process
.
destroy
();
throw
new
IOException
();
}
}
catch
(
IOException
e
)
{
rootStatus
=
-
1
;
continue
;
}
break
;
}
else
{
// Try to gain non-root sh
try
{
process
=
Runtime
.
getRuntime
().
exec
(
"sh"
);
in
=
new
DataOutputStream
(
process
.
getOutputStream
());
out
=
new
DataInputStream
(
process
.
getInputStream
());
}
catch
(
IOException
e
)
{
// Nothing works....
shellProcess
=
null
;
STDIN
=
null
;
STDOUT
=
null
;
isValid
=
false
;
return
;
}
break
;
}
}
isValid
=
true
;
shellProcess
=
process
;
STDIN
=
in
;
STDOUT
=
out
;
sh_raw
(
"umask 022"
);
}
public
static
Shell
get
Root
Shell
()
{
public
static
Shell
getShell
()
{
return
new
Shell
();
}
public
static
Shell
get
Root
Shell
(
Context
context
)
{
return
Utils
.
getMagiskManager
(
context
).
rootS
hell
;
public
static
Shell
getShell
(
Context
context
)
{
return
Utils
.
getMagiskManager
(
context
).
s
hell
;
}
public
static
boolean
rootAccess
()
{
return
rootStatus
>
0
;
}
public
static
List
<
String
>
sh
(
String
...
commands
)
{
List
<
String
>
res
=
Collections
.
synchronizedList
(
new
ArrayList
<
String
>());
try
{
Process
process
=
Runtime
.
getRuntime
().
exec
(
"sh"
);
DataOutputStream
STDIN
=
new
DataOutputStream
(
process
.
getOutputStream
());
StreamGobbler
STDOUT
=
new
StreamGobbler
(
process
.
getInputStream
(),
res
);
STDOUT
.
start
();
try
{
for
(
String
write
:
commands
)
{
STDIN
.
write
((
write
+
"\n"
).
getBytes
(
"UTF-8"
));
STDIN
.
flush
();
Logger
.
shell
(
false
,
write
);
}
STDIN
.
write
(
"exit\n"
.
getBytes
(
"UTF-8"
));
STDIN
.
flush
();
}
catch
(
IOException
e
)
{
if
(!
e
.
getMessage
().
contains
(
"EPIPE"
))
{
throw
e
;
}
}
process
.
waitFor
();
try
{
STDIN
.
close
();
}
catch
(
IOException
e
)
{
// might be closed already
}
STDOUT
.
join
();
process
.
destroy
();
}
catch
(
IOException
|
InterruptedException
e
)
{
// shell probably not found
res
=
null
;
}
return
res
;
}
public
List
<
String
>
su
(
String
...
commands
)
{
if
(!
isValid
)
return
null
;
public
List
<
String
>
sh
(
String
...
commands
)
{
List
<
String
>
res
=
new
ArrayList
<>();
su
(
res
,
commands
);
if
(!
isValid
)
return
res
;
sh
(
res
,
commands
);
return
res
;
}
public
void
s
u
_raw
(
String
...
commands
)
{
public
void
s
h
_raw
(
String
...
commands
)
{
if
(!
isValid
)
return
;
synchronized
(
rootShell
)
{
synchronized
(
shellProcess
)
{
try
{
for
(
String
command
:
commands
)
{
root
STDIN
.
write
((
command
+
"\n"
).
getBytes
(
"UTF-8"
));
root
STDIN
.
flush
();
STDIN
.
write
((
command
+
"\n"
).
getBytes
(
"UTF-8"
));
STDIN
.
flush
();
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
rootShell
.
destroy
();
shellProcess
.
destroy
();
isValid
=
false
;
}
}
}
public
void
s
u
(
List
<
String
>
output
,
String
...
commands
)
{
public
void
s
h
(
List
<
String
>
output
,
String
...
commands
)
{
if
(!
isValid
)
return
;
try
{
rootShell
.
exitValue
();
shellProcess
.
exitValue
();
isValid
=
false
;
return
;
// The process is dead, return
}
catch
(
IllegalThreadStateException
ignored
)
{
// This should be the expected result
}
synchronized
(
rootShell
)
{
StreamGobbler
STDOUT
=
new
StreamGobbler
(
rootSTDOUT
,
output
,
true
);
STDOUT
.
start
();
s
u
_raw
(
commands
);
s
u_raw
(
"echo \'-root
-done-\'"
);
try
{
STDOUT
.
join
();
}
catch
(
InterruptedException
ignored
)
{}
synchronized
(
shellProcess
)
{
StreamGobbler
out
=
new
StreamGobbler
(
this
.
STDOUT
,
output
);
out
.
start
();
s
h
_raw
(
commands
);
s
h_raw
(
"echo \'-shell
-done-\'"
);
try
{
out
.
join
();
}
catch
(
InterruptedException
ignored
)
{}
}
}
public
List
<
String
>
su
(
String
...
commands
)
{
if
(!
rootAccess
())
return
sh
();
return
sh
(
commands
);
}
public
void
su_raw
(
String
...
commands
)
{
if
(!
rootAccess
())
return
;
sh_raw
(
commands
);
}
public
void
su
(
List
<
String
>
output
,
String
...
commands
)
{
if
(!
rootAccess
())
return
;
sh
(
output
,
commands
);
}
}
app/src/main/java/com/topjohnwu/magisk/utils/StreamGobbler.java
View file @
6933bcf7
...
...
@@ -21,7 +21,7 @@ public class StreamGobbler extends Thread {
/**
* <p>StreamGobbler constructor</p>
*
* <p>We use this class because sh
ell
STDOUT and STDERR should be read as quickly as
* <p>We use this class because sh STDOUT and STDERR should be read as quickly as
* possible to prevent a deadlock from occurring, or Process.waitFor() never
* returning (as the buffer is full, pausing the native process)</p>
*
...
...
@@ -38,21 +38,16 @@ public class StreamGobbler extends Thread {
writer
=
outputList
;
}
public
StreamGobbler
(
InputStream
inputStream
,
List
<
String
>
outputList
,
boolean
root
)
{
this
(
inputStream
,
outputList
);
isRoot
=
root
;
}
@Override
public
void
run
()
{
// keep reading the InputStream until it ends (or an error occurs)
try
{
String
line
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
if
(
TextUtils
.
equals
(
line
,
"-
root
-done-"
))
if
(
TextUtils
.
equals
(
line
,
"-
shell
-done-"
))
return
;
writer
.
add
(
line
);
Logger
.
shell
(
isRoot
,
line
);
Logger
.
shell
(
line
);
}
}
catch
(
IOException
e
)
{
// reader probably closed, expected exit condition
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment