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
e3df62d8
Commit
e3df62d8
authored
Aug 20, 2017
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor several utility functions
parent
19131258
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
117 additions
and
129 deletions
+117
-129
bootstages.c
jni/daemon/bootstages.c
+27
-29
log_monitor.c
jni/daemon/log_monitor.c
+2
-4
utils.h
jni/include/utils.h
+2
-5
vector.h
jni/include/vector.h
+1
-1
proc_monitor.c
jni/magiskhide/proc_monitor.c
+2
-4
img.c
jni/utils/img.c
+9
-14
misc.c
jni/utils/misc.c
+74
-72
No files found.
jni/daemon/bootstages.c
View file @
e3df62d8
...
...
@@ -136,8 +136,7 @@ static void exec_common_script(const char* stage) {
if
(
access
(
buf2
,
X_OK
)
==
-
1
)
continue
;
LOGI
(
"%s.d: exec [%s]
\n
"
,
stage
,
entry
->
d_name
);
char
*
const
command
[]
=
{
"sh"
,
buf2
,
NULL
};
int
pid
=
run_command2
(
0
,
NULL
,
bb_setenv
,
command
);
int
pid
=
exec_command
(
0
,
NULL
,
bb_setenv
,
"sh"
,
buf2
,
NULL
);
if
(
pid
!=
-
1
)
waitpid
(
pid
,
NULL
,
0
);
}
...
...
@@ -154,8 +153,7 @@ static void exec_module_script(const char* stage) {
if
(
access
(
buf2
,
F_OK
)
==
-
1
||
access
(
buf
,
F_OK
)
==
0
)
continue
;
LOGI
(
"%s: exec [%s.sh]
\n
"
,
module
,
stage
);
char
*
const
command
[]
=
{
"sh"
,
buf2
,
NULL
};
int
pid
=
run_command2
(
0
,
NULL
,
bb_setenv
,
command
);
int
pid
=
exec_command
(
0
,
NULL
,
bb_setenv
,
"sh"
,
buf2
,
NULL
);
if
(
pid
!=
-
1
)
waitpid
(
pid
,
NULL
,
0
);
}
...
...
@@ -402,8 +400,7 @@ static void mount_mirrors() {
static
void
link_busybox
()
{
mkdir_p
(
BBPATH
,
0755
);
char
*
const
command
[]
=
{
MIRRDIR
"/bin/busybox"
,
"--install"
,
"-s"
,
BBPATH
,
NULL
};
run_command
(
command
);
exec_command_sync
(
MIRRDIR
"/bin/busybox"
,
"--install"
,
"-s"
,
BBPATH
,
NULL
);
symlink
(
MIRRDIR
"/bin/busybox"
,
BBPATH
"/busybox"
);
}
...
...
@@ -442,7 +439,7 @@ static int prepare_img() {
snprintf
(
buf
,
PATH_MAX
,
"%s/%s/remove"
,
MOUNTPOINT
,
entry
->
d_name
);
if
(
access
(
buf
,
F_OK
)
==
0
)
{
snprintf
(
buf
,
PATH_MAX
,
"%s/%s"
,
MOUNTPOINT
,
entry
->
d_name
);
rm_rf
(
buf
);
exec_command_sync
(
BBPATH
"/rm"
,
"-rf"
,
buf
,
NULL
);
continue
;
}
snprintf
(
buf
,
PATH_MAX
,
"%s/%s/disable"
,
MOUNTPOINT
,
entry
->
d_name
);
...
...
@@ -520,8 +517,7 @@ void post_fs_data(int client) {
#ifdef MAGISK_DEBUG
// Start debug logs in new process
debug_log_fd
=
xopen
(
DEBUG_LOG
,
O_WRONLY
|
O_CREAT
|
O_CLOEXEC
|
O_TRUNC
,
0644
);
char
*
const
command
[]
=
{
"logcat"
,
"-v"
,
"brief"
,
NULL
};
debug_log_pid
=
run_command2
(
0
,
&
debug_log_fd
,
NULL
,
command
);
debug_log_pid
=
exec_command
(
0
,
&
debug_log_fd
,
NULL
,
"logcat"
,
"-v"
,
"brief"
,
NULL
);
close
(
debug_log_fd
);
#endif
...
...
@@ -531,20 +527,25 @@ void post_fs_data(int client) {
if
(
buf
==
NULL
)
buf
=
xmalloc
(
PATH_MAX
);
if
(
buf2
==
NULL
)
buf2
=
xmalloc
(
PATH_MAX
);
// Cache support
if
(
access
(
"/cache/data_bin"
,
F_OK
)
==
0
)
{
rm_rf
(
DATABIN
);
rename
(
"/cache/data_bin"
,
DATABIN
);
// Magisk binaries
char
*
bin_path
=
NULL
;
if
(
access
(
"/cache/data_bin"
,
F_OK
)
==
0
)
bin_path
=
"/cache/data_bin"
;
else
if
(
access
(
"/data/local/tmp/magisk_inject"
,
F_OK
)
==
0
)
bin_path
=
"/data/local/tmp/magisk_inject"
;
if
(
bin_path
)
{
exec_command_sync
(
"rm"
,
"-rf"
,
DATABIN
,
NULL
);
exec_command_sync
(
"cp"
,
"-r"
,
bin_path
,
DATABIN
,
NULL
);
exec_command_sync
(
"rm"
,
"-rf"
,
bin_path
,
NULL
);
exec_command_sync
(
"chmod"
,
"-R"
,
"755"
,
bin_path
,
NULL
);
}
// Magisk Manual Injector support
if
(
access
(
"/data/local/tmp/magisk_inject"
,
F_OK
)
==
0
)
{
rm_rf
(
DATABIN
);
rename
(
"/data/local/tmp/magisk_inject"
,
DATABIN
);
}
// Lazy.... use shell blob to match files
exec_command_sync
(
"sh"
,
"-c"
,
"mv /data/magisk/stock_boot* /data"
,
NULL
);
// Lazy.... use shell blob
system
(
"mv /data/magisk/stock_boot* /data;"
);
// Link busybox
mount_mirrors
();
link_busybox
();
// Merge images
if
(
merge_img
(
"/cache/magisk.img"
,
MAINIMG
))
{
...
...
@@ -556,15 +557,12 @@ void post_fs_data(int client) {
goto
unblock
;
}
// Link busybox
mount_mirrors
();
link_busybox
();
// uninstaller
if
(
access
(
UNINSTALLER
,
F_OK
)
==
0
)
{
close
(
open
(
UNBLOCKFILE
,
O_RDONLY
|
O_CREAT
));
bb_setenv
();
system
(
"(BOOTMODE=true sh "
UNINSTALLER
") &"
);
setenv
(
"BOOTMODE"
,
"true"
,
1
);
exec_command
(
0
,
NULL
,
NULL
,
"sh"
,
UNINSTALLER
,
NULL
);
return
;
}
...
...
@@ -704,11 +702,11 @@ core_only:
if
(
access
(
MANAGERAPK
,
F_OK
)
==
0
)
{
while
(
1
)
{
sleep
(
5
);
char
*
const
command
[]
=
{
"app_process"
,
"/system/bin"
,
"com.android.commands.pm.Pm"
,
"install"
,
"-r"
,
MANAGERAPK
,
NULL
};
int
apk_res
=
-
1
,
pid
;
pid
=
run_command2
(
1
,
&
apk_res
,
pm_setenv
,
command
);
pid
=
exec_command
(
1
,
&
apk_res
,
pm_setenv
,
"app_process"
,
"/system/bin"
,
"com.android.commands.pm.Pm"
,
"install"
,
"-r"
,
MANAGERAPK
,
NULL
);
if
(
pid
!=
-
1
)
{
waitpid
(
pid
,
NULL
,
0
);
fdgets
(
buf
,
PATH_MAX
,
apk_res
);
...
...
jni/daemon/log_monitor.c
View file @
e3df62d8
...
...
@@ -26,13 +26,11 @@ static void *logger_thread(void *args) {
while
(
1
)
{
// Start logcat
char
*
const
command
[]
=
{
"logcat"
,
"-s"
,
"Magisk"
,
"-v"
,
"thread"
,
NULL
};
log_pid
=
run_command2
(
0
,
&
log_fd
,
NULL
,
command
);
log_pid
=
exec_command
(
0
,
&
log_fd
,
NULL
,
"logcat"
,
"-s"
,
"Magisk"
,
"-v"
,
"thread"
,
NULL
);
if
(
log_pid
>
0
)
waitpid
(
log_pid
,
NULL
,
0
);
// For some reason it went here, clear buffer and restart
char
*
const
restart
[]
=
{
"logcat"
,
"-c"
,
NULL
};
run_command
(
restart
);
exec_command_sync
(
"logcat"
,
"-c"
,
NULL
);
}
// Should never be here, but well...
...
...
jni/include/utils.h
View file @
e3df62d8
...
...
@@ -75,21 +75,18 @@ unsigned get_radio_uid();
int
check_data
();
int
file_to_vector
(
const
char
*
filename
,
struct
vector
*
v
);
int
vector_to_file
(
const
char
*
filename
,
struct
vector
*
v
);
int
isNum
(
const
char
*
s
);
ssize_t
fdgets
(
char
*
buf
,
size_t
size
,
int
fd
);
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
setup_sighandlers
(
void
(
*
handler
)(
int
));
int
run_command
(
char
*
const
argv
[]
);
int
run_command2
(
int
err
,
int
*
fd
,
void
(
*
cb
)(
void
),
char
*
const
argv
[]
);
int
exec_command
(
int
err
,
int
*
fd
,
void
(
*
cb
)(
void
),
const
char
*
argv0
,
...
);
int
exec_command_sync
(
char
*
const
argv0
,
...
);
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
);
void
rm_rf
(
const
char
*
target
);
void
fclone_attr
(
const
int
sourcefd
,
const
int
targetfd
);
void
clone_attr
(
const
char
*
source
,
const
char
*
target
);
void
get_client_cred
(
int
fd
,
struct
ucred
*
cred
);
...
...
jni/include/vector.h
View file @
e3df62d8
...
...
@@ -32,4 +32,4 @@ struct vector *vec_dup(struct vector *v);
e = v ? (v)->data[(v)->size - 1] : NULL; \
for (size_t _ = (v)->size; v && _ > 0; --_, e = (v)->data[_ - 1])
#endif
\ No newline at end of file
#endif
jni/magiskhide/proc_monitor.c
View file @
e3df62d8
...
...
@@ -181,13 +181,11 @@ void proc_monitor() {
while
(
1
)
{
// Clear previous logcat buffer
char
*
const
restart
[]
=
{
"logcat"
,
"-b"
,
"events"
,
"-c"
,
NULL
};
run_command
(
restart
);
exec_command_sync
(
"logcat"
,
"-b"
,
"events"
,
"-c"
,
NULL
);
// Monitor am_proc_start
char
*
const
command
[]
=
{
"logcat"
,
"-b"
,
"events"
,
"-v"
,
"raw"
,
"-s"
,
"am_proc_start"
,
NULL
};
log_fd
=
-
1
;
log_pid
=
run_command2
(
0
,
&
log_fd
,
NULL
,
command
);
log_pid
=
exec_command
(
0
,
&
log_fd
,
NULL
,
"logcat"
,
"-b"
,
"events"
,
"-v"
,
"raw"
,
"-s"
,
"am_proc_start"
,
NULL
);
if
(
log_pid
<
0
)
continue
;
if
(
kill
(
log_pid
,
0
))
continue
;
...
...
jni/utils/img.c
View file @
e3df62d8
...
...
@@ -14,8 +14,7 @@ static int e2fsck(const char *img) {
// Check and repair ext4 image
char
buffer
[
128
];
int
pid
,
fd
=
-
1
;
char
*
const
command
[]
=
{
"e2fsck"
,
"-yf"
,
(
char
*
)
img
,
NULL
};
pid
=
run_command2
(
1
,
&
fd
,
NULL
,
command
);
pid
=
exec_command
(
1
,
&
fd
,
NULL
,
"e2fsck"
,
"-yf"
,
img
,
NULL
);
if
(
pid
<
0
)
return
1
;
while
(
fdgets
(
buffer
,
sizeof
(
buffer
),
fd
))
...
...
@@ -56,19 +55,17 @@ int create_img(const char *img, int size) {
char
file_contexts
[]
=
"/magisk(/.*)? u:object_r:system_file:s0
\n
"
;
// If not root, attempt to create in current diretory
char
*
filename
=
getuid
()
==
UID_ROOT
?
"/dev/file_contexts_image"
:
"file_contexts_image"
;
int
pid
,
status
,
fd
=
xopen
(
filename
,
O_WRONLY
|
O_CREAT
|
O_TRUNC
,
0644
);
int
ret
,
fd
=
xopen
(
filename
,
O_WRONLY
|
O_CREAT
|
O_TRUNC
,
0644
);
xwrite
(
fd
,
file_contexts
,
sizeof
(
file_contexts
));
close
(
fd
);
char
buffer
[
16
];
snprintf
(
buffer
,
sizeof
(
buffer
),
"%dM"
,
size
);
char
*
const
command
[]
=
{
"make_ext4fs"
,
"-l"
,
buffer
,
"-a"
,
"/magisk"
,
"-S"
,
filename
,
(
char
*
)
img
,
NULL
};
pid
=
run_command2
(
0
,
NULL
,
NULL
,
command
);
if
(
pid
<
0
)
ret
=
exec_command_sync
(
"make_ext4fs"
,
"-l"
,
buffer
,
"-a"
,
"/magisk"
,
"-S"
,
filename
,
img
,
NULL
);
if
(
ret
<
0
)
return
1
;
waitpid
(
pid
,
&
status
,
0
);
unlink
(
filename
);
return
WEXITSTATUS
(
status
)
;
return
ret
;
}
int
get_img_size
(
const
char
*
img
,
int
*
used
,
int
*
total
)
{
...
...
@@ -76,8 +73,7 @@ int get_img_size(const char *img, int *used, int *total) {
return
1
;
char
buffer
[
PATH_MAX
];
int
pid
,
fd
=
-
1
,
status
=
1
;
char
*
const
command
[]
=
{
"e2fsck"
,
"-n"
,
(
char
*
)
img
,
NULL
};
pid
=
run_command2
(
1
,
&
fd
,
NULL
,
command
);
pid
=
exec_command
(
1
,
&
fd
,
NULL
,
"e2fsck"
,
"-n"
,
img
,
NULL
);
if
(
pid
<
0
)
return
1
;
while
(
fdgets
(
buffer
,
sizeof
(
buffer
),
fd
))
{
...
...
@@ -109,8 +105,7 @@ int resize_img(const char *img, int size) {
char
buffer
[
128
];
int
pid
,
status
,
fd
=
-
1
;
snprintf
(
buffer
,
sizeof
(
buffer
),
"%dM"
,
size
);
char
*
const
command
[]
=
{
"resize2fs"
,
(
char
*
)
img
,
buffer
,
NULL
};
pid
=
run_command2
(
1
,
&
fd
,
NULL
,
command
);
pid
=
exec_command
(
1
,
&
fd
,
NULL
,
"resize2fs"
,
img
,
buffer
,
NULL
);
if
(
pid
<
0
)
return
1
;
while
(
fdgets
(
buffer
,
sizeof
(
buffer
),
fd
))
...
...
@@ -188,14 +183,14 @@ int merge_img(const char *source, const char *target) {
snprintf
(
buffer
,
sizeof
(
buffer
),
"%s/%s"
,
TARGET_TMP
,
entry
->
d_name
);
if
(
access
(
buffer
,
F_OK
)
==
0
)
{
LOGI
(
"Upgrade module: %s
\n
"
,
entry
->
d_name
);
rm_rf
(
buffer
);
exec_command_sync
(
BBPATH
"/rm"
,
"-rf"
,
buffer
,
NULL
);
}
else
{
LOGI
(
"New module: %s
\n
"
,
entry
->
d_name
);
}
}
}
closedir
(
dir
);
c
lone_dir
(
SOURCE_TMP
,
TARGET_TMP
);
c
p_afc
(
SOURCE_TMP
,
TARGET_TMP
);
// Unmount all loop devices
umount_image
(
SOURCE_TMP
,
s_loop
);
...
...
jni/utils/misc.c
View file @
e3df62d8
...
...
@@ -5,6 +5,7 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
...
...
@@ -97,7 +98,7 @@ int vector_to_file(const char *filename, struct vector *v) {
}
/* Check if the string only contains digits */
int
isN
um
(
const
char
*
s
)
{
static
int
is_n
um
(
const
char
*
s
)
{
int
len
=
strlen
(
s
);
for
(
int
i
=
0
;
i
<
len
;
++
i
)
if
(
s
[
i
]
<
'0'
||
s
[
i
]
>
'9'
)
...
...
@@ -129,7 +130,7 @@ void ps(void (*func)(int)) {
while
((
entry
=
xreaddir
(
dir
)))
{
if
(
entry
->
d_type
==
DT_DIR
)
{
if
(
is
N
um
(
entry
->
d_name
))
if
(
is
_n
um
(
entry
->
d_name
))
func
(
atoi
(
entry
->
d_name
));
}
}
...
...
@@ -219,22 +220,13 @@ void setup_sighandlers(void (*handler)(int)) {
}
}
int
run_command
(
char
*
const
argv
[])
{
int
pid
=
run_command2
(
0
,
NULL
,
NULL
,
argv
);
if
(
pid
!=
-
1
)
waitpid
(
pid
,
NULL
,
0
);
else
return
1
;
return
0
;
}
/*
fd == NULL -> Ignore output
*fd < 0 -> Open pipe and set *fd to the read end
*fd >= 0 -> STDOUT (or STDERR) will be redirected to *fd
*cb -> A callback function which runs after fork
*/
int
run_command2
(
int
err
,
int
*
fd
,
void
(
*
cb
)(
void
),
char
*
const
argv
[]
)
{
static
int
v_exec_command
(
int
err
,
int
*
fd
,
void
(
*
cb
)(
void
),
const
char
*
argv0
,
va_list
argv
)
{
int
pipefd
[
2
],
writeEnd
=
-
1
;
if
(
fd
)
{
...
...
@@ -257,6 +249,9 @@ int run_command2(int err, int *fd, void (*cb)(void), char *const argv[]) {
return
pid
;
}
// Don't affect the daemon if anything wrong happens
err_handler
=
do_nothing
;
if
(
cb
)
cb
();
if
(
fd
)
{
...
...
@@ -264,11 +259,39 @@ int run_command2(int err, int *fd, void (*cb)(void), char *const argv[]) {
if
(
err
)
xdup2
(
writeEnd
,
STDERR_FILENO
);
}
execvp
(
argv
[
0
],
argv
);
PLOGE
(
"execv"
);
// Collect va_list into vector
struct
vector
v
;
vec_init
(
&
v
);
vec_push_back
(
&
v
,
(
void
*
)
argv0
);
for
(
void
*
arg
=
va_arg
(
argv
,
void
*
);
arg
;
arg
=
va_arg
(
argv
,
void
*
))
vec_push_back
(
&
v
,
arg
);
vec_push_back
(
&
v
,
NULL
);
execvp
(
argv0
,
(
char
**
)
vec_entry
(
&
v
));
PLOGE
(
"execvp"
);
return
-
1
;
}
int
exec_command_sync
(
char
*
const
argv0
,
...)
{
va_list
argv
;
va_start
(
argv
,
argv0
);
int
pid
,
status
;
pid
=
v_exec_command
(
0
,
NULL
,
NULL
,
argv0
,
argv
);
va_end
(
argv
);
if
(
pid
<
0
)
return
pid
;
waitpid
(
pid
,
&
status
,
0
);
return
WEXITSTATUS
(
status
);
}
int
exec_command
(
int
err
,
int
*
fd
,
void
(
*
cb
)(
void
),
const
char
*
argv0
,
...)
{
va_list
argv
;
va_start
(
argv
,
argv0
);
int
pid
=
v_exec_command
(
err
,
fd
,
cb
,
argv0
,
argv
);
va_end
(
argv
);
return
pid
;
}
int
mkdir_p
(
const
char
*
pathname
,
mode_t
mode
)
{
char
*
path
=
strdup
(
pathname
),
*
p
;
errno
=
0
;
...
...
@@ -304,78 +327,57 @@ 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
);
fclone_attr
(
sfd
,
tfd
);
close
(
sfd
);
close
(
tfd
);
}
else
if
(
S_ISLNK
(
buf
.
st_mode
))
{
char
buffer
[
PATH_MAX
];
xreadlink
(
source
,
buffer
,
sizeof
(
buffer
));
xsymlink
(
buffer
,
target
);
lchown
(
target
,
buf
.
st_uid
,
buf
.
st_gid
);
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
;
if
(
S_ISDIR
(
buf
.
st_mode
)
)
{
DIR
*
dir
;
struct
dirent
*
entry
;
char
*
s_path
,
*
t_path
;
if
(
!
(
dir
=
xopendir
(
source
)))
return
1
;
if
(
!
(
dir
=
xopendir
(
source
)))
return
1
;
s_path
=
xmalloc
(
PATH_MAX
);
t_path
=
xmalloc
(
PATH_MAX
);
s_path
=
xmalloc
(
PATH_MAX
);
t_path
=
xmalloc
(
PATH_MAX
);
mkdir_p
(
target
,
0755
);
clone_attr
(
source
,
target
);
mkdir_p
(
target
,
0755
);
clone_attr
(
source
,
target
);
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
:
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
);
cp_afc
(
s_path
,
t_path
);
break
;
}
free
(
s_path
);
free
(
t_path
);
closedir
(
dir
);
}
else
{
unlink
(
target
);
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
);
fclone_attr
(
sfd
,
tfd
);
close
(
sfd
);
close
(
tfd
);
}
else
if
(
S_ISLNK
(
buf
.
st_mode
))
{
char
buffer
[
PATH_MAX
];
xreadlink
(
source
,
buffer
,
sizeof
(
buffer
));
xsymlink
(
buffer
,
target
);
clone_attr
(
source
,
target
);
}
else
{
return
1
;
}
}
free
(
s_path
);
free
(
t_path
);
closedir
(
dir
);
return
0
;
}
void
rm_rf
(
const
char
*
target
)
{
if
(
access
(
target
,
F_OK
)
==
-
1
)
return
;
// Use external rm command, saves a lot of headache and issues
char
*
const
command
[]
=
{
"rm"
,
"-rf"
,
(
char
*
)
target
,
NULL
};
run_command
(
command
);
}
void
clone_attr
(
const
char
*
source
,
const
char
*
target
)
{
int
sourcefd
,
targetfd
;
sourcefd
=
xopen
(
source
,
O_RDONLY
);
...
...
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