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
a31c1e80
Commit
a31c1e80
authored
May 03, 2017
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
post-fs-data mode done
parent
21891230
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
361 additions
and
48 deletions
+361
-48
bootstages.c
jni/daemon/bootstages.c
+208
-38
log_monitor.c
jni/daemon/log_monitor.c
+2
-4
magisk.h
jni/magisk.h
+12
-0
misc.c
jni/utils/misc.c
+109
-5
utils.h
jni/utils/utils.h
+6
-1
xwrap.c
jni/utils/xwrap.c
+24
-0
No files found.
jni/daemon/bootstages.c
View file @
a31c1e80
...
...
@@ -74,6 +74,111 @@ static char *mount_image(const char *img, const char *target) {
return
device
;
}
static
void
umount_image
(
const
char
*
target
,
const
char
*
device
)
{
xumount
(
target
);
int
fd
=
xopen
(
device
,
O_RDWR
);
ioctl
(
fd
,
LOOP_CLR_FD
);
close
(
fd
);
}
static
int
get_img_size
(
const
char
*
img
,
int
*
used
,
int
*
total
)
{
char
buffer
[
PATH_MAX
];
snprintf
(
buffer
,
sizeof
(
buffer
),
"e2fsck -n %s 2>/dev/null | tail -n 1"
,
img
);
char
*
const
command
[]
=
{
"sh"
,
"-c"
,
buffer
,
NULL
};
int
pid
,
fd
;
pid
=
run_command
(
&
fd
,
"/system/bin/sh"
,
command
);
fdgets
(
buffer
,
sizeof
(
buffer
),
fd
);
close
(
fd
);
if
(
pid
==
-
1
)
return
1
;
waitpid
(
pid
,
NULL
,
0
);
char
*
tok
;
tok
=
strtok
(
buffer
,
","
);
while
(
tok
!=
NULL
)
{
if
(
strstr
(
tok
,
"blocks"
))
break
;
tok
=
strtok
(
NULL
,
","
);
}
sscanf
(
tok
,
"%d/%d"
,
used
,
total
);
*
used
=
*
used
/
256
+
1
;
*
total
/=
256
;
return
0
;
}
#define round_size(a) ((((a) / 32) + 1) * 32)
static
int
resize_img
(
const
char
*
img
,
int
size
)
{
char
buffer
[
ARG_MAX
];
LOGI
(
"resize %s to %dM
\n
"
,
img
,
size
);
snprintf
(
buffer
,
sizeof
(
buffer
),
"e2fsck -yf %s && resize2fs %s %dM;"
,
img
,
img
,
size
);
return
system
(
buffer
);
}
static
int
merge_img
(
const
char
*
source
,
const
char
*
target
)
{
if
(
access
(
source
,
F_OK
)
==
-
1
)
return
0
;
if
(
access
(
target
,
F_OK
)
==
-
1
)
{
rename
(
source
,
target
);
return
0
;
}
// resize target to worst case
int
s_used
,
s_total
,
t_used
,
t_total
,
n_total
;
get_img_size
(
source
,
&
s_used
,
&
s_total
);
get_img_size
(
target
,
&
t_used
,
&
t_total
);
n_total
=
round_size
(
s_used
+
t_used
);
if
(
n_total
!=
t_total
&&
resize_img
(
target
,
n_total
))
return
1
;
xmkdir
(
"/cache/source"
,
0755
);
xmkdir
(
"/cache/target"
,
0755
);
char
*
s_loop
,
*
t_loop
;
s_loop
=
mount_image
(
source
,
"/cache/source"
);
if
(
s_loop
==
NULL
)
return
1
;
t_loop
=
mount_image
(
target
,
"/cache/target"
);
if
(
t_loop
==
NULL
)
return
1
;
DIR
*
dir
;
struct
dirent
*
entry
;
if
(
!
(
dir
=
xopendir
(
"/cache/source"
)))
return
1
;
while
((
entry
=
xreaddir
(
dir
)))
{
if
(
entry
->
d_type
==
DT_DIR
)
{
if
(
strcmp
(
entry
->
d_name
,
"."
)
==
0
||
strcmp
(
entry
->
d_name
,
".."
)
==
0
||
strcmp
(
entry
->
d_name
,
".core"
)
==
0
||
strcmp
(
entry
->
d_name
,
"lost+found"
)
==
0
)
continue
;
// Cleanup old module
snprintf
(
buf
,
PATH_MAX
,
"/cache/target/%s"
,
entry
->
d_name
);
if
(
access
(
buf
,
F_OK
)
==
0
)
{
LOGI
(
"merge module %s
\n
"
,
entry
->
d_name
);
rm_rf
(
buf
);
}
}
}
closedir
(
dir
);
clone_dir
(
"/cache/source"
,
"/cache/target"
);
// Unmount all loop devices
umount_image
(
"/cache/source"
,
s_loop
);
umount_image
(
"/cache/target"
,
t_loop
);
rmdir
(
"/cache/source"
);
rmdir
(
"/cache/target"
);
free
(
s_loop
);
free
(
t_loop
);
unlink
(
source
);
return
0
;
}
static
void
trim_img
(
const
char
*
img
)
{
int
used
,
total
,
new_size
;
get_img_size
(
img
,
&
used
,
&
total
);
new_size
=
round_size
(
used
);
if
(
new_size
<
total
)
resize_img
(
img
,
new_size
);
}
/***********
* Scripts *
***********/
...
...
@@ -81,7 +186,7 @@ static char *mount_image(const char *img, const char *target) {
void
exec_common_script
(
const
char
*
stage
)
{
DIR
*
dir
;
struct
dirent
*
entry
;
snprintf
(
buf
,
PATH_MAX
,
"
/magisk/.core/%s.d"
,
stage
);
snprintf
(
buf
,
PATH_MAX
,
"
%s/.core/%s.d"
,
MOUNTPOINT
,
stage
);
if
(
!
(
dir
=
opendir
(
buf
)))
return
;
...
...
@@ -105,7 +210,7 @@ void exec_common_script(const char* stage) {
void
exec_module_script
(
const
char
*
stage
)
{
char
*
module
;
vec_for_each
(
&
module_list
,
module
)
{
snprintf
(
buf
,
PATH_MAX
,
"
/magisk/%s/%s.sh"
,
module
,
stage
);
snprintf
(
buf
,
PATH_MAX
,
"
%s/%s/%s.sh"
,
MOUNTPOINT
,
module
,
stage
);
if
(
access
(
buf
,
F_OK
)
==
-
1
)
continue
;
LOGI
(
"%s: exec [%s.sh]
\n
"
,
module
,
stage
);
...
...
@@ -179,7 +284,7 @@ static void construct_tree(const char *module, const char *path, struct node_ent
struct
dirent
*
entry
;
struct
node_entry
*
node
;
snprintf
(
buf
,
PATH_MAX
,
"
/magisk/%s/%s"
,
module
,
path
);
snprintf
(
buf
,
PATH_MAX
,
"
%s/%s/%s"
,
MOUNTPOINT
,
module
,
path
);
if
(
!
(
dir
=
xopendir
(
buf
)))
return
;
...
...
@@ -202,14 +307,14 @@ static void construct_tree(const char *module, const char *path, struct node_ent
}
else
{
if
(
entry
->
d_type
==
DT_DIR
)
{
// Check if marked as replace
snprintf
(
buf
,
PATH_MAX
,
"/magisk/%s/%s/%s/.replace"
,
module
,
path
,
entry
->
d_name
);
if
(
access
(
buf
,
F_OK
)
==
0
)
{
snprintf
(
buf
2
,
PATH_MAX
,
"%s/%s/%s/%s/.replace"
,
MOUNTPOINT
,
module
,
path
,
entry
->
d_name
);
if
(
access
(
buf
2
,
F_OK
)
==
0
)
{
// Replace everything, mark as leaf
node
->
status
=
IS_MODULE
;
}
else
{
// Travel deeper
snprintf
(
buf
,
PATH_MAX
,
"%s/%s"
,
path
,
entry
->
d_name
);
char
*
new_path
=
strdup
(
buf
);
snprintf
(
buf
2
,
PATH_MAX
,
"%s/%s"
,
path
,
entry
->
d_name
);
char
*
new_path
=
strdup
(
buf
2
);
construct_tree
(
module
,
new_path
,
node
);
free
(
new_path
);
}
...
...
@@ -245,12 +350,12 @@ static void clone_skeleton(struct node_entry *node, const char *real_path) {
}
closedir
(
dir
);
snprintf
(
buf
,
PATH_MAX
,
"
/dev/magisk/dummy%s"
,
real_path
);
snprintf
(
buf
,
PATH_MAX
,
"
%s%s"
,
DUMMDIR
,
real_path
);
xmkdir_p
(
buf
,
0755
);
bind_mount
(
buf
,
real_path
);
vec_for_each
(
node
->
children
,
child
)
{
snprintf
(
buf
,
PATH_MAX
,
"
/dev/magisk/dummy%s/%s"
,
real_path
,
child
->
name
);
snprintf
(
buf
,
PATH_MAX
,
"
%s%s/%s"
,
DUMMDIR
,
real_path
,
child
->
name
);
if
(
child
->
type
==
DT_DIR
)
{
xmkdir
(
buf
,
0755
);
}
else
if
(
child
->
type
==
DT_REG
)
{
...
...
@@ -258,10 +363,10 @@ static void clone_skeleton(struct node_entry *node, const char *real_path) {
}
if
(
child
->
status
==
IS_MODULE
)
{
// Mount from module file to dummy file
snprintf
(
buf2
,
PATH_MAX
,
"
/magisk/%s%s/%s"
,
child
->
module
,
real_path
,
child
->
name
);
snprintf
(
buf2
,
PATH_MAX
,
"
%s/%s%s/%s"
,
MOUNTPOINT
,
child
->
module
,
real_path
,
child
->
name
);
}
else
if
(
child
->
status
==
IS_DUMMY
)
{
// Mount from mirror to dummy file
snprintf
(
buf2
,
PATH_MAX
,
"
/dev/magisk/mirror%s/%s"
,
real_path
,
child
->
name
);
snprintf
(
buf2
,
PATH_MAX
,
"
%s%s/%s"
,
MIRRDIR
,
real_path
,
child
->
name
);
}
else
if
(
child
->
status
==
IS_SKEL
)
{
// It's another skeleton, recursive call and end
char
*
s
=
get_full_path
(
child
);
...
...
@@ -287,8 +392,13 @@ static void magic_mount(struct node_entry *node) {
char
*
real_path
;
struct
node_entry
*
child
;
if
(
strcmp
(
node
->
name
,
"vendor"
)
==
0
&&
strcmp
(
node
->
parent
->
name
,
"/system"
)
==
0
)
if
(
strcmp
(
node
->
name
,
"vendor"
)
==
0
&&
strcmp
(
node
->
parent
->
name
,
"/system"
)
==
0
)
{
snprintf
(
buf
,
PATH_MAX
,
"%s/%s/system/vendor"
,
MOUNTPOINT
,
node
->
module
);
snprintf
(
buf2
,
PATH_MAX
,
"%s/%s/vendor"
,
MOUNTPOINT
,
node
->
module
);
unlink
(
buf2
);
symlink
(
buf
,
buf2
);
return
;
}
if
(
node
->
status
==
DO_NOTHING
)
{
vec_for_each
(
node
->
children
,
child
)
...
...
@@ -296,7 +406,7 @@ static void magic_mount(struct node_entry *node) {
}
else
{
real_path
=
get_full_path
(
node
);
if
(
node
->
status
==
IS_MODULE
)
{
snprintf
(
buf
,
PATH_MAX
,
"
/magisk/%s%s"
,
node
->
module
,
real_path
);
snprintf
(
buf
,
PATH_MAX
,
"
%s/%s%s"
,
MOUNTPOINT
,
node
->
module
,
real_path
);
bind_mount
(
buf
,
real_path
);
}
else
if
(
node
->
status
==
IS_SKEL
)
{
clone_skeleton
(
node
,
real_path
);
...
...
@@ -314,12 +424,23 @@ static void *start_magisk_hide(void *args) {
return
NULL
;
}
static
void
unblock_boot_process
()
{
close
(
open
(
UNBLOCKFILE
,
O_RDONLY
|
O_CREAT
));
pthread_exit
(
NULL
);
}
void
post_fs
(
int
client
)
{
// Error handler
err_handler
=
unblock_boot_process
;
LOGI
(
"** post-fs mode running
\n
"
);
// ack
write_int
(
client
,
0
);
close
(
client
);
// Uninstall or core only mode
if
(
access
(
UNINSTALLER
,
F_OK
)
==
0
||
access
(
DISABLEFILE
,
F_OK
)
==
0
)
goto
unblock
;
// TODO: Simple bind mounts
// Allocate buffer
...
...
@@ -331,32 +452,61 @@ unblock:
}
void
post_fs_data
(
int
client
)
{
// Error handler
err_handler
=
unblock_boot_process
;
// ack
write_int
(
client
,
0
);
close
(
client
);
if
(
!
check_data
())
goto
unblock
;
LOGI
(
"** post-fs-data mode running
\n
"
);
// uninstaller
if
(
access
(
UNINSTALLER
,
F_OK
)
==
0
)
{
close
(
open
(
UNBLOCKFILE
,
O_RDONLY
|
O_CREAT
));
char
*
const
command
[]
=
{
"sh"
,
UNBLOCKFILE
,
NULL
};
run_command
(
NULL
,
"/system/bin/sh"
,
command
);
return
;
}
// Allocate buffer
if
(
buf
==
NULL
)
buf
=
xmalloc
(
PATH_MAX
);
if
(
buf2
==
NULL
)
buf2
=
xmalloc
(
PATH_MAX
);
LOGI
(
"** post-fs-data mode running
\n
"
);
LOGI
(
"* Mounting magisk.img
\n
"
);
// Cache support
if
(
access
(
"/cache/data_bin"
,
F_OK
)
==
0
)
{
rm_rf
(
DATABIN
);
rename
(
"/cache/data_bin"
,
DATABIN
);
system
(
"mv /cache/stock_boot* /data"
);
// Lazy.... use bash glob....
}
// Merge images
if
(
merge_img
(
"/cache/magisk.img"
,
MAINIMG
))
goto
unblock
;
if
(
merge_img
(
"/data/magisk_merge.img"
,
MAINIMG
))
goto
unblock
;
LOGI
(
"* Mounting "
MAINIMG
"
\n
"
);
// Mounting magisk image
char
*
magiskimg
=
mount_image
(
"/data/magisk.img"
,
"/magisk"
);
free
(
magiskimg
);
char
*
magiskloop
=
mount_image
(
MAINIMG
,
MOUNTPOINT
);
if
(
magiskloop
==
NULL
)
goto
unblock
;
// Run common scripts
LOGI
(
"* Running post-fs-data.d scripts
\n
"
);
exec_common_script
(
"post-fs-data"
);
// Core only mode
if
(
access
(
DISABLEFILE
,
F_OK
)
==
0
)
goto
unblock
;
DIR
*
dir
;
struct
dirent
*
entry
;
char
*
module
;
struct
node_entry
*
sys_root
,
*
ven_root
=
NULL
,
*
child
;
if
(
!
(
dir
=
xopendir
(
"/magisk"
)))
if
(
!
(
dir
=
xopendir
(
MOUNTPOINT
)))
goto
unblock
;
// Create the system root entry
...
...
@@ -375,27 +525,35 @@ void post_fs_data(int client) {
strcmp
(
entry
->
d_name
,
".core"
)
==
0
||
strcmp
(
entry
->
d_name
,
"lost+found"
)
==
0
)
continue
;
snprintf
(
buf
,
PATH_MAX
,
"%s/%s"
,
MOUNTPOINT
,
entry
->
d_name
);
// Check whether remove
snprintf
(
buf2
,
PATH_MAX
,
"%s/remove"
,
buf
);
if
(
access
(
buf2
,
F_OK
)
==
0
)
{
rm_rf
(
buf
);
continue
;
}
// Check whether disable
snprintf
(
buf
,
PATH_MAX
,
"/magisk/%s/disable"
,
entry
->
d_name
);
if
(
access
(
buf
,
F_OK
)
==
0
)
snprintf
(
buf
2
,
PATH_MAX
,
"%s/disable"
,
buf
);
if
(
access
(
buf
2
,
F_OK
)
==
0
)
continue
;
// Add the module to list
module
=
strdup
(
entry
->
d_name
);
vec_push_back
(
&
module_list
,
module
);
// Read props
snprintf
(
buf
,
PATH_MAX
,
"/magisk/%s/system.prop"
,
module
);
if
(
access
(
buf
,
F_OK
)
==
0
)
{
snprintf
(
buf
2
,
PATH_MAX
,
"%s/system.prop"
,
buf
);
if
(
access
(
buf
2
,
F_OK
)
==
0
)
{
LOGI
(
"%s: loading [system.prop]
\n
"
,
module
);
read_prop_file
(
buf
,
0
);
read_prop_file
(
buf
2
,
0
);
}
// Check whether enable auto_mount
snprintf
(
buf
,
PATH_MAX
,
"/magisk/%s/auto_mount"
,
module
);
if
(
access
(
buf
,
F_OK
)
==
-
1
)
snprintf
(
buf
2
,
PATH_MAX
,
"%s/auto_mount"
,
buf
);
if
(
access
(
buf
2
,
F_OK
)
==
-
1
)
continue
;
// Double check whether the system folder exists
snprintf
(
buf
,
PATH_MAX
,
"/magisk/%s/system"
,
module
);
if
(
access
(
buf
,
F_OK
)
==
-
1
)
snprintf
(
buf
2
,
PATH_MAX
,
"%s/system"
,
buf
);
if
(
access
(
buf
2
,
F_OK
)
==
-
1
)
continue
;
// Construct structure
has_modules
=
1
;
LOGI
(
"%s: constructing magic mount structure
\n
"
,
module
);
...
...
@@ -405,10 +563,18 @@ void post_fs_data(int client) {
closedir
(
dir
);
// Trim image
umount_image
(
MOUNTPOINT
,
magiskloop
);
free
(
magiskloop
);
trim_img
(
MAINIMG
);
// Remount them back :)
magiskloop
=
mount_image
(
MAINIMG
,
MOUNTPOINT
);
free
(
magiskloop
);
if
(
has_modules
)
{
// Mount mirrors
LOGI
(
"* Mounting system/vendor mirrors"
);
char
block
[
256
];
int
seperate_vendor
=
0
;
struct
vector
mounts
;
vec_init
(
&
mounts
);
...
...
@@ -416,25 +582,29 @@ void post_fs_data(int client) {
char
*
line
;
vec_for_each
(
&
mounts
,
line
)
{
if
(
strstr
(
line
,
" /system "
))
{
sscanf
(
line
,
"%s"
,
block
);
xmkdir_p
(
"/dev/magisk/mirror/system"
,
0755
);
xmount
(
block
,
"/dev/magisk/mirror/system"
,
"ext4"
,
MS_RDONLY
,
NULL
);
LOGD
(
"mount: %s -> /dev/magisk/mirror/system
\n
"
,
block
);
sscanf
(
line
,
"%s"
,
buf
);
snprintf
(
buf2
,
PATH_MAX
,
"%s/system"
,
MIRRDIR
);
xmkdir_p
(
buf2
,
0755
);
xmount
(
buf
,
buf2
,
"ext4"
,
MS_RDONLY
,
NULL
);
LOGD
(
"mount: %s -> %s
\n
"
,
buf
,
buf2
);
continue
;
}
if
(
strstr
(
line
,
" /vendor "
))
{
seperate_vendor
=
1
;
sscanf
(
line
,
"%s"
,
block
);
xmkdir_p
(
"/dev/magisk/mirror/vendor"
,
0755
);
xmount
(
block
,
"/dev/magisk/mirror/vendor"
,
"ext4"
,
MS_RDONLY
,
NULL
);
LOGD
(
"mount: %s -> /dev/magisk/mirror/vendor
\n
"
,
block
);
sscanf
(
line
,
"%s"
,
buf
);
snprintf
(
buf2
,
PATH_MAX
,
"%s/vendor"
,
MIRRDIR
);
xmkdir_p
(
buf2
,
0755
);
xmount
(
buf
,
buf2
,
"ext4"
,
MS_RDONLY
,
NULL
);
LOGD
(
"mount: %s -> %s
\n
"
,
buf
,
buf2
);
continue
;
}
}
vec_deep_destroy
(
&
mounts
);
if
(
!
seperate_vendor
)
{
symlink
(
"/dev/magisk/mirror/system/vendor"
,
"/dev/magisk/mirror/vendor"
);
LOGD
(
"link: /dev/magisk/mirror/system/vendor -> /dev/magisk/mirror/vendor
\n
"
);
snprintf
(
buf
,
PATH_MAX
,
"%s/system/vendor"
,
MIRRDIR
);
snprintf
(
buf2
,
PATH_MAX
,
"%s/vendor"
,
MIRRDIR
);
symlink
(
buf
,
buf2
);
LOGD
(
"link: %s -> %s
\n
"
,
buf
,
buf2
);
}
// Magic!!
...
...
jni/daemon/log_monitor.c
View file @
a31c1e80
...
...
@@ -8,7 +8,6 @@
#include <stdio.h>
#include <limits.h>
#include <pthread.h>
#include <unistd.h>
#include "magisk.h"
#include "utils.h"
...
...
@@ -19,8 +18,8 @@ static void *logger_thread(void *args) {
err_handler
=
exit_thread
;
char
buffer
[
PATH_MAX
];
rename
(
"/cache/magisk.log"
,
"/cache/last_magisk.log"
);
FILE
*
logfile
=
xfopen
(
"/cache/magisk.log"
,
"w"
);
rename
(
LOGFILE
,
LASTLOG
);
FILE
*
logfile
=
xfopen
(
LOGFILE
,
"w"
);
// Disable buffering
setbuf
(
logfile
,
NULL
);
// Start logcat
...
...
@@ -30,7 +29,6 @@ static void *logger_thread(void *args) {
while
(
fdgets
(
buffer
,
sizeof
(
buffer
),
fd
))
{
fprintf
(
logfile
,
"%s"
,
buffer
);
}
close
(
fd
);
return
NULL
;
}
...
...
jni/magisk.h
View file @
a31c1e80
...
...
@@ -24,6 +24,18 @@
#define ARG_MAX 4096
#endif
#define LOGFILE "/cache/magisk.log"
#define LASTLOG "/cache/last_magisk.log"
#define UNBLOCKFILE "/dev/.magisk.unblock"
#define DISABLEFILE "/cache/.disable_magisk"
#define UNINSTALLER "/cache/magisk_uninstaller.sh"
#define MOUNTPOINT "/magisk"
#define MAINIMG "/data/magisk.img"
#define DATABIN "/data/magisk"
#define MAGISKTMP "/dev/magisk"
#define MIRRDIR MAGISKTMP "/mirror"
#define DUMMDIR MAGISKTMP "/dummy"
#define SELINUX_PATH "/sys/fs/selinux/"
#define SELINUX_ENFORCE SELINUX_PATH "enforce"
#define SELINUX_POLICY SELINUX_PATH "policy"
...
...
jni/utils/misc.c
View file @
a31c1e80
...
...
@@ -14,6 +14,8 @@
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <selinux/selinux.h>
#include "magisk.h"
#include "utils.h"
...
...
@@ -204,11 +206,6 @@ void unlock_blocks() {
closedir
(
dir
);
}
void
unblock_boot_process
()
{
int
fd
=
open
(
"/dev/.magisk.unblock"
,
O_RDONLY
|
O_CREAT
);
close
(
fd
);
}
void
setup_sighandlers
(
void
(
*
handler
)(
int
))
{
struct
sigaction
act
;
memset
(
&
act
,
0
,
sizeof
(
act
));
...
...
@@ -276,3 +273,110 @@ int bind_mount(const char *from, const char *to) {
int
open_new
(
const
char
*
filename
)
{
return
xopen
(
filename
,
O_WRONLY
|
O_CREAT
|
O_TRUNC
,
0644
);
}
// file/link -> file/link only!!
int
cp_afc
(
const
char
*
source
,
const
char
*
target
)
{
struct
stat
buf
;
xlstat
(
source
,
&
buf
);
unlink
(
target
);
char
*
con
;
if
(
S_ISREG
(
buf
.
st_mode
))
{
int
sfd
,
tfd
;
sfd
=
xopen
(
source
,
O_RDONLY
);
tfd
=
xopen
(
target
,
O_WRONLY
|
O_CREAT
|
O_TRUNC
);
xsendfile
(
tfd
,
sfd
,
NULL
,
buf
.
st_size
);
fchmod
(
tfd
,
buf
.
st_mode
&
0777
);
fchown
(
tfd
,
buf
.
st_uid
,
buf
.
st_gid
);
fgetfilecon
(
sfd
,
&
con
);
fsetfilecon
(
tfd
,
con
);
free
(
con
);
close
(
sfd
);
close
(
tfd
);
}
else
if
(
S_ISLNK
(
buf
.
st_mode
))
{
char
buffer
[
PATH_MAX
];
xreadlink
(
source
,
buffer
,
sizeof
(
buffer
));
xsymlink
(
buffer
,
target
);
lgetfilecon
(
source
,
&
con
);
lsetfilecon
(
target
,
con
);
free
(
con
);
}
else
{
return
1
;
}
return
0
;
}
int
clone_dir
(
const
char
*
source
,
const
char
*
target
)
{
DIR
*
dir
;
struct
dirent
*
entry
;
char
*
s_path
,
*
t_path
,
*
con
;
if
(
!
(
dir
=
xopendir
(
source
)))
return
1
;
s_path
=
xmalloc
(
PATH_MAX
);
t_path
=
xmalloc
(
PATH_MAX
);
struct
stat
buf
;
xstat
(
source
,
&
buf
);
mkdir_p
(
target
,
buf
.
st_mode
&
0777
);
xchmod
(
target
,
buf
.
st_mode
&
0777
);
lgetfilecon
(
source
,
&
con
);
lsetfilecon
(
target
,
con
);
free
(
con
);
while
((
entry
=
xreaddir
(
dir
)))
{
if
(
strcmp
(
entry
->
d_name
,
"."
)
==
0
||
strcmp
(
entry
->
d_name
,
".."
)
==
0
)
continue
;
snprintf
(
s_path
,
PATH_MAX
,
"%s/%s"
,
source
,
entry
->
d_name
);
snprintf
(
t_path
,
PATH_MAX
,
"%s/%s"
,
target
,
entry
->
d_name
);
switch
(
entry
->
d_type
)
{
case
DT_DIR
:
clone_dir
(
s_path
,
t_path
);
break
;
case
DT_REG
:
case
DT_LNK
:
cp_afc
(
s_path
,
t_path
);
break
;
}
}
free
(
s_path
);
free
(
t_path
);
closedir
(
dir
);
return
0
;
}
int
rm_rf
(
const
char
*
target
)
{
struct
stat
buf
;
xlstat
(
target
,
&
buf
);
char
*
next
;
if
(
S_ISDIR
(
buf
.
st_mode
))
{
DIR
*
dir
;
struct
dirent
*
entry
;
if
(
!
(
dir
=
xopendir
(
target
)))
return
1
;
next
=
xmalloc
(
PATH_MAX
);
while
((
entry
=
xreaddir
(
dir
)))
{
if
(
strcmp
(
entry
->
d_name
,
"."
)
==
0
||
strcmp
(
entry
->
d_name
,
".."
)
==
0
)
continue
;
snprintf
(
next
,
PATH_MAX
,
"%s/%s"
,
target
,
entry
->
d_name
);
switch
(
entry
->
d_type
)
{
case
DT_DIR
:
rm_rf
(
next
);
break
;
case
DT_REG
:
case
DT_LNK
:
unlink
(
next
);
break
;
}
}
free
(
next
);
closedir
(
dir
);
rmdir
(
target
);
}
else
if
(
S_ISREG
(
buf
.
st_mode
)
||
S_ISLNK
(
buf
.
st_mode
))
{
unlink
(
target
);
}
else
{
return
1
;
}
return
0
;
}
jni/utils/utils.h
View file @
a31c1e80
...
...
@@ -49,12 +49,15 @@ int xpthread_create(pthread_t *thread, const pthread_attr_t *attr,
void
*
(
*
start_routine
)
(
void
*
),
void
*
arg
);
int
xsocketpair
(
int
domain
,
int
type
,
int
protocol
,
int
sv
[
2
]);
int
xstat
(
const
char
*
pathname
,
struct
stat
*
buf
);
int
xlstat
(
const
char
*
pathname
,
struct
stat
*
buf
);
int
xdup2
(
int
oldfd
,
int
newfd
);
ssize_t
xreadlink
(
const
char
*
pathname
,
char
*
buf
,
size_t
bufsiz
);
int
xsymlink
(
const
char
*
target
,
const
char
*
linkpath
);
int
xmount
(
const
char
*
source
,
const
char
*
target
,
const
char
*
filesystemtype
,
unsigned
long
mountflags
,
const
void
*
data
);
int
xumount
(
const
char
*
target
);
int
xumount2
(
const
char
*
target
,
int
flags
);
int
xchmod
(
const
char
*
pathname
,
mode_t
mode
);
int
xrename
(
const
char
*
oldpath
,
const
char
*
newpath
);
int
xmkdir
(
const
char
*
pathname
,
mode_t
mode
);
...
...
@@ -77,11 +80,13 @@ void ps(void (*func)(int));
void
ps_filter_proc_name
(
const
char
*
filter
,
void
(
*
func
)(
int
));
int
create_links
(
const
char
*
bin
,
const
char
*
path
);
void
unlock_blocks
();
void
unblock_boot_process
();
void
setup_sighandlers
(
void
(
*
handler
)(
int
));
int
run_command
(
int
*
fd
,
const
char
*
path
,
char
*
const
argv
[]);
int
mkdir_p
(
const
char
*
pathname
,
mode_t
mode
);
int
bind_mount
(
const
char
*
from
,
const
char
*
to
);
int
open_new
(
const
char
*
filename
);
int
cp_afc
(
const
char
*
source
,
const
char
*
target
);
int
clone_dir
(
const
char
*
source
,
const
char
*
target
);
int
rm_rf
(
const
char
*
target
);
#endif
jni/utils/xwrap.c
View file @
a31c1e80
...
...
@@ -220,6 +220,14 @@ int xstat(const char *pathname, struct stat *buf) {
return
ret
;
}
int
xlstat
(
const
char
*
pathname
,
struct
stat
*
buf
)
{
int
ret
=
lstat
(
pathname
,
buf
);
if
(
ret
==
-
1
)
{
PLOGE
(
"lstat %s"
,
pathname
);
}
return
ret
;
}
int
xdup2
(
int
oldfd
,
int
newfd
)
{
int
ret
=
dup2
(
oldfd
,
newfd
);
if
(
ret
==
-
1
)
{
...
...
@@ -257,6 +265,22 @@ int xmount(const char *source, const char *target,
return
ret
;
}
int
xumount
(
const
char
*
target
)
{
int
ret
=
umount
(
target
);
if
(
ret
==
-
1
)
{
PLOGE
(
"umount %s"
,
target
);
}
return
ret
;
}
int
xumount2
(
const
char
*
target
,
int
flags
)
{
int
ret
=
umount2
(
target
,
flags
);
if
(
ret
==
-
1
)
{
PLOGE
(
"umount2 %s"
,
target
);
}
return
ret
;
}
int
xchmod
(
const
char
*
pathname
,
mode_t
mode
)
{
int
ret
=
chmod
(
pathname
,
mode
);
if
(
ret
==
-
1
)
{
...
...
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