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
aa8b2310
Commit
aa8b2310
authored
May 07, 2020
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Modernize resetprop with fancy C++
parent
c113f854
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
128 additions
and
133 deletions
+128
-133
resetprop.hpp
native/jni/include/resetprop.hpp
+3
-2
_resetprop.hpp
native/jni/resetprop/_resetprop.hpp
+33
-41
persist_properties.cpp
native/jni/resetprop/persist_properties.cpp
+46
-30
resetprop.cpp
native/jni/resetprop/resetprop.cpp
+46
-60
No files found.
native/jni/include/resetprop.hpp
View file @
aa8b2310
...
...
@@ -3,9 +3,10 @@
#include <string>
#include <functional>
int
prop_exist
(
const
char
*
name
);
bool
prop_exist
(
const
char
*
name
);
int
setprop
(
const
char
*
name
,
const
char
*
value
,
bool
trigger
=
true
);
std
::
string
getprop
(
const
char
*
name
,
bool
persist
=
false
);
void
getprop
(
void
(
*
callback
)(
const
char
*
,
const
char
*
,
void
*
),
void
*
cookie
,
bool
persist
=
false
);
void
getprops
(
void
(
*
callback
)(
const
char
*
,
const
char
*
,
void
*
),
void
*
cookie
=
nullptr
,
bool
persist
=
false
);
int
delprop
(
const
char
*
name
,
bool
persist
=
false
);
void
load_prop_file
(
const
char
*
filename
,
bool
trigger
=
true
);
native/jni/resetprop/_resetprop.hpp
View file @
aa8b2310
#pragma once
#include <string>
#include <map>
#include <logging.hpp>
#include <system_properties.h>
struct
prop_t
{
char
*
name
;
char
value
[
PROP_VALUE_MAX
];
prop_t
()
:
name
(
nullptr
)
{}
explicit
prop_t
(
const
char
*
name
)
{
this
->
name
=
strdup
(
name
);
value
[
0
]
=
'\0'
;
}
prop_t
(
const
char
*
name
,
const
char
*
value
)
{
this
->
name
=
strdup
(
name
);
strcpy
(
this
->
value
,
value
);
}
prop_t
(
prop_t
&&
prop
)
:
name
(
nullptr
)
{
operator
=
(
std
::
move
(
prop
));
}
bool
operator
<
(
const
prop_t
&
prop
)
const
{
return
strcmp
(
name
,
prop
.
name
)
<
0
;
}
prop_t
&
operator
=
(
prop_t
&&
prop
)
{
if
(
this
!=
&
prop
)
{
free
(
name
);
name
=
prop
.
name
;
strcpy
(
value
,
prop
.
value
);
prop
.
name
=
nullptr
;
}
return
*
this
;
};
~
prop_t
()
{
free
(
name
);
}
#define PERSISTENT_PROPERTY_DIR "/data/property"
struct
prop_cb
{
virtual
void
exec
(
const
char
*
name
,
const
char
*
value
)
=
0
;
};
struct
read_cb_t
{
void
(
*
cb
)(
const
char
*
,
const
char
*
,
void
*
);
void
*
arg
;
explicit
read_cb_t
(
void
(
*
cb
)(
const
char
*
,
const
char
*
,
void
*
)
=
nullptr
,
void
*
arg
=
nullptr
)
:
cb
(
cb
),
arg
(
arg
)
{}
void
exec
(
const
char
*
name
,
const
char
*
value
)
{
cb
(
name
,
value
,
arg
);
template
<
class
T
>
struct
prop_cb_impl
:
public
prop_cb
{
typedef
void
(
*
callback_type
)(
const
char
*
,
const
char
*
,
T
&
);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdangling-field" // Dangling field is expected
prop_cb_impl
(
T
&
arg
,
callback_type
fn
)
:
arg
(
arg
),
fn
(
fn
)
{}
#pragma GCC diagnostic pop
void
exec
(
const
char
*
name
,
const
char
*
value
)
override
{
fn
(
name
,
value
,
arg
);
}
private
:
T
&
arg
;
callback_type
fn
;
};
#define PERSISTENT_PROPERTY_DIR "/data/property"
extern
bool
use_pb
;
using
prop_list
=
std
::
map
<
std
::
string_view
,
std
::
string
>
;
struct
prop_collector
:
prop_cb_impl
<
prop_list
>
{
prop_collector
(
prop_list
&
list
)
:
prop_cb_impl
<
prop_list
>
(
list
,
[](
auto
name
,
auto
val
,
auto
list
){
list
.
emplace
(
name
,
val
);
})
{}
};
template
<
class
T
,
class
Func
>
prop_cb_impl
<
T
>
make_prop_cb
(
T
&
arg
,
Func
f
)
{
return
prop_cb_impl
<
T
>
(
arg
,
f
);
}
std
::
string
persist_getprop
(
const
char
*
name
);
void
persist_getprop
(
read_cb_t
*
read
_cb
);
void
persist_getprop
s
(
prop_cb
*
prop
_cb
);
bool
persist_deleteprop
(
const
char
*
name
);
void
collect_props
(
const
char
*
name
,
const
char
*
value
,
void
*
v_plist
);
void
persist_cleanup
(
);
native/jni/resetprop/persist_properties.cpp
View file @
aa8b2310
...
...
@@ -88,8 +88,22 @@ const pb_field_t PersistentProperties_fields[2] = {
* End of auto generated code
* ***************************/
#ifdef APPLET_STUB_MAIN
struct
{
void
push_back
(...){};
}
allocs
;
void
persist_cleanup
(){}
#else
static
thread_local
vector
<
void
*>
allocs
;
void
persist_cleanup
()
{
std
::
for_each
(
allocs
.
begin
(),
allocs
.
end
(),
[](
auto
p
){
free
(
p
);
});
allocs
.
clear
();
}
#endif
static
bool
name_decode
(
pb_istream_t
*
stream
,
const
pb_field_t
*
field
,
void
**
arg
)
{
auto
name
=
new
pb_byte_t
[
stream
->
bytes_left
+
1
];
auto
name
=
(
pb_byte_t
*
)
malloc
(
stream
->
bytes_left
+
1
);
allocs
.
push_back
(
name
);
/* Record all mallocs to cleanup */
name
[
stream
->
bytes_left
]
=
'\0'
;
if
(
!
pb_read
(
stream
,
name
,
stream
->
bytes_left
))
return
false
;
...
...
@@ -107,8 +121,7 @@ static bool prop_decode(pb_istream_t *stream, const pb_field_t *field, void **ar
prop
.
name
.
funcs
.
decode
=
name_decode
;
if
(
!
pb_decode
(
stream
,
PersistentProperties_PersistentPropertyRecord_fields
,
&
prop
))
return
false
;
((
read_cb_t
*
)
*
arg
)
->
exec
((
const
char
*
)
prop
.
name
.
arg
,
prop
.
value
);
delete
[]
(
pb_byte_t
*
)
prop
.
name
.
arg
;
reinterpret_cast
<
prop_cb
*>
(
*
arg
)
->
exec
((
const
char
*
)
prop
.
name
.
arg
,
prop
.
value
);
return
true
;
}
...
...
@@ -116,12 +129,12 @@ static bool prop_encode(pb_ostream_t *stream, const pb_field_t *field, void * co
PersistentProperties_PersistentPropertyRecord
prop
=
{};
prop
.
name
.
funcs
.
encode
=
name_encode
;
prop
.
has_value
=
true
;
auto
&
prop_list
=
*
(
vector
<
prop_t
>
*
)
*
arg
;
for
(
auto
&
p
:
prop_
list
)
{
auto
&
list
=
*
(
prop_list
*
)
*
arg
;
for
(
auto
&
p
:
list
)
{
if
(
!
pb_encode_tag_for_field
(
stream
,
field
))
return
false
;
prop
.
name
.
arg
=
p
.
name
;
strcpy
(
prop
.
value
,
p
.
value
);
prop
.
name
.
arg
=
(
void
*
)
p
.
first
.
data
()
;
strcpy
(
prop
.
value
,
p
.
second
.
data
()
);
if
(
!
pb_encode_submessage
(
stream
,
PersistentProperties_PersistentPropertyRecord_fields
,
&
prop
))
return
false
;
}
...
...
@@ -144,17 +157,11 @@ static pb_ostream_t create_ostream(const char *filename) {
return
o
;
}
static
void
pb_getprop_cb
(
const
char
*
name
,
const
char
*
value
,
void
*
v
)
{
struct
prop_t
*
prop
=
static_cast
<
prop_t
*>
(
v
);
if
(
prop
->
name
&&
strcmp
(
name
,
prop
->
name
)
==
0
)
strcpy
(
prop
->
value
,
value
);
}
static
void
pb_getprop
(
read_cb_t
*
read_cb
)
{
static
void
pb_getprop
(
prop_cb
*
prop_cb
)
{
LOGD
(
"resetprop: decode with protobuf ["
PERSISTENT_PROPERTY_DIR
"/persistent_properties]
\n
"
);
PersistentProperties
props
=
{};
props
.
properties
.
funcs
.
decode
=
prop_decode
;
props
.
properties
.
arg
=
read
_cb
;
props
.
properties
.
arg
=
prop
_cb
;
pb_byte_t
*
buf
;
size_t
size
;
mmap_ro
(
PERSISTENT_PROPERTY_DIR
"/persistent_properties"
,
buf
,
size
);
...
...
@@ -175,9 +182,9 @@ static bool file_getprop(const char *name, char *value) {
return
value
[
0
]
!=
'\0'
;
}
void
persist_getprop
(
read_cb_t
*
read
_cb
)
{
void
persist_getprop
s
(
prop_cb
*
prop
_cb
)
{
if
(
use_pb
)
{
pb_getprop
(
read
_cb
);
pb_getprop
(
prop
_cb
);
}
else
{
DIR
*
dir
=
opendir
(
PERSISTENT_PROPERTY_DIR
);
struct
dirent
*
entry
;
...
...
@@ -186,16 +193,25 @@ void persist_getprop(read_cb_t *read_cb) {
continue
;
char
value
[
PROP_VALUE_MAX
];
if
(
file_getprop
(
entry
->
d_name
,
value
))
read
_cb
->
exec
(
entry
->
d_name
,
value
);
prop
_cb
->
exec
(
entry
->
d_name
,
value
);
}
}
}
string
persist_getprop
(
const
char
*
name
)
{
prop_t
prop
(
name
);
if
(
use_pb
)
{
read_cb_t
read_cb
(
pb_getprop_cb
,
&
prop
);
pb_getprop
(
&
read_cb
);
run_finally
f
([]{
persist_cleanup
();
});
struct
{
const
char
*
name
;
char
value
[
PROP_VALUE_MAX
];
}
prop
;
prop
.
name
=
name
;
prop
.
value
[
0
]
=
'\0'
;
auto
reader
=
make_prop_cb
(
prop
,
[](
auto
name
,
auto
value
,
auto
prop
)
{
if
(
strcmp
(
name
,
prop
.
name
)
==
0
)
strcpy
(
prop
.
value
,
value
);
});
pb_getprop
(
&
reader
);
if
(
prop
.
value
[
0
])
return
prop
.
value
;
}
else
{
...
...
@@ -209,19 +225,20 @@ string persist_getprop(const char *name) {
bool
persist_deleteprop
(
const
char
*
name
)
{
if
(
use_pb
)
{
vector
<
prop_t
>
prop_list
;
read_cb_t
read_cb
(
collect_props
,
&
prop_list
);
persist_getprop
(
&
read_cb
);
for
(
auto
it
=
prop_list
.
begin
();
it
!=
prop_list
.
end
();
++
it
)
{
if
(
strcmp
(
it
->
name
,
name
)
==
0
)
{
prop_list
.
erase
(
it
);
run_finally
f
([]{
persist_cleanup
();
});
prop_list
list
;
prop_collector
collector
(
list
);
persist_getprops
(
&
collector
);
for
(
auto
it
=
list
.
begin
();
it
!=
list
.
end
();
++
it
)
{
if
(
it
->
first
==
name
)
{
list
.
erase
(
it
);
// Dump the props back
PersistentProperties
props
=
PersistentProperties_init_zero
;
pb_ostream_t
ostream
=
create_ostream
(
PERSISTENT_PROPERTY_DIR
"/persistent_properties.tmp"
);
props
.
properties
.
funcs
.
encode
=
prop_encode
;
props
.
properties
.
arg
=
&
prop_
list
;
props
.
properties
.
arg
=
&
list
;
LOGD
(
"resetprop: encode with protobuf ["
PERSISTENT_PROPERTY_DIR
"/persistent_properties.tmp]
\n
"
);
if
(
!
pb_encode
(
&
ostream
,
PersistentProperties_fields
,
&
props
))
...
...
@@ -233,7 +250,6 @@ bool persist_deleteprop(const char *name) {
return
true
;
}
}
return
false
;
}
else
{
char
path
[
PATH_MAX
];
...
...
native/jni/resetprop/resetprop.cpp
View file @
aa8b2310
...
...
@@ -7,7 +7,7 @@
#include <dirent.h>
#include <sys/types.h>
#include <vector>
#include <
algorithm
>
#include <
map
>
#include <logging.hpp>
#include <resetprop.hpp>
...
...
@@ -55,48 +55,34 @@ illegal:
[[
noreturn
]]
static
void
usage
(
char
*
arg0
)
{
fprintf
(
stderr
,
NAME_WITH_VER
(
resetprop
)
" - System Props Modification Tool
\n\n
"
"Usage: %s [flags] [options...]
\n
"
"
\n
"
"Options:
\n
"
" -h, --help show this message
\n
"
" (no arguments) print all properties
\n
"
" NAME get property
\n
"
" NAME VALUE set property entry NAME with VALUE
\n
"
" --file FILE load props from FILE
\n
"
" --delete NAME delete property
\n
"
"
\n
"
"Flags:
\n
"
" -v print verbose output to stderr
\n
"
" -n set properties without init triggers
\n
"
" only affects setprop
\n
"
" -p access actual persist storage
\n
"
" only affects getprop and delprop
\n
"
"
\n
"
,
arg0
);
NAME_WITH_VER
(
resetprop
)
R"EOF(" - System Props Modification Tool
Usage: %s [flags] [options...]
Options:
-h, --help show this message
(no arguments) print all properties
NAME get property
NAME VALUE set property entry NAME with VALUE
--file FILE load props from FILE
--delete NAME delete property
Flags:
-v print verbose output to stderr
-n set properties without going through init
affects setprop and prop file loading
-p also access props directly from persist storage
affects getprop and delprop
)EOF"
,
arg0
);
exit
(
1
);
}
static
void
read_props
(
const
prop_info
*
pi
,
void
*
read_
cb
)
{
static
void
read_props
(
const
prop_info
*
pi
,
void
*
cb
)
{
__system_property_read_callback
(
pi
,
[](
auto
cb
,
auto
name
,
auto
value
,
auto
)
{
((
read_cb_t
*
)
cb
)
->
exec
(
name
,
value
);
},
read_cb
);
}
void
collect_props
(
const
char
*
name
,
const
char
*
value
,
void
*
v_plist
)
{
auto
prop_list
=
static_cast
<
vector
<
prop_t
>
*>
(
v_plist
);
prop_list
->
emplace_back
(
name
,
value
);
}
static
void
collect_unique_props
(
const
char
*
name
,
const
char
*
value
,
void
*
v_plist
)
{
auto
&
prop_list
=
*
static_cast
<
vector
<
prop_t
>
*>
(
v_plist
);
for
(
auto
&
prop
:
prop_list
)
{
if
(
strcmp
(
name
,
prop
.
name
)
==
0
)
return
;
}
collect_props
(
name
,
value
,
v_plist
);
reinterpret_cast
<
prop_cb
*>
(
cb
)
->
exec
(
name
,
value
);
},
cb
);
}
static
int
init_resetprop
()
{
...
...
@@ -109,11 +95,9 @@ static int init_resetprop() {
}
static
void
print_props
(
bool
persist
)
{
vector
<
prop_t
>
prop_list
;
getprop
(
collect_props
,
&
prop_list
,
persist
);
sort
(
prop_list
.
begin
(),
prop_list
.
end
());
for
(
auto
&
prop
:
prop_list
)
printf
(
"[%s]: [%s]
\n
"
,
prop
.
name
,
prop
.
value
);
getprops
([](
auto
name
,
auto
value
,
auto
)
{
printf
(
"[%s]: [%s]
\n
"
,
name
,
value
);
},
nullptr
,
persist
);
}
/* **************************************************
...
...
@@ -122,8 +106,8 @@ static void print_props(bool persist) {
#define ENSURE_INIT(ret) if (init_resetprop()) return ret
int
prop_exist
(
const
char
*
name
)
{
ENSURE_INIT
(
0
);
bool
prop_exist
(
const
char
*
name
)
{
ENSURE_INIT
(
false
);
return
__system_property_find
(
name
)
!=
nullptr
;
}
...
...
@@ -137,29 +121,31 @@ string getprop(const char *name, bool persist) {
if
(
persist
&&
strncmp
(
name
,
"persist."
,
8
)
==
0
)
{
auto
value
=
persist_getprop
(
name
);
if
(
value
.
empty
())
LOGD
(
"resetprop: prop [%s] does not exist
\n
"
,
name
)
;
goto
not_found
;
return
value
;
}
not_found
:
LOGD
(
"resetprop: prop [%s] does not exist
\n
"
,
name
);
return
string
();
}
else
{
char
value
[
PROP_VALUE_MAX
];
read_cb_t
read_cb
;
read_cb
.
cb
=
[](
auto
,
auto
value
,
auto
dst
)
->
void
{
strcpy
((
char
*
)
dst
,
value
);
};
read_cb
.
arg
=
value
;
read_props
(
pi
,
&
read_cb
);
LOGD
(
"resetprop: getprop [%s]: [%s]
\n
"
,
name
,
value
);
return
value
;
char
buf
[
PROP_VALUE_MAX
];
auto
reader
=
make_prop_cb
(
buf
,
[](
auto
,
auto
value
,
auto
buf
)
{
strcpy
(
buf
,
value
);
});
read_props
(
pi
,
&
reader
);
LOGD
(
"resetprop: getprop [%s]: [%s]
\n
"
,
name
,
buf
);
return
buf
;
}
}
void
getprop
(
void
(
*
callback
)(
const
char
*
,
const
char
*
,
void
*
),
void
*
cookie
,
bool
persist
)
{
void
getprop
s
(
void
(
*
callback
)(
const
char
*
,
const
char
*
,
void
*
),
void
*
cookie
,
bool
persist
)
{
ENSURE_INIT
();
read_cb_t
read_cb
(
callback
,
cookie
);
__system_property_foreach
(
read_props
,
&
read_cb
);
if
(
persist
)
{
read_cb
.
cb
=
collect_unique_props
;
persist_getprop
(
&
read_cb
);
}
prop_list
list
;
prop_collector
collector
(
list
);
__system_property_foreach
(
read_props
,
&
collector
);
if
(
persist
)
persist_getprops
(
&
collector
);
for
(
auto
&
[
key
,
val
]
:
list
)
callback
(
key
.
data
(),
val
.
data
(),
cookie
);
persist_cleanup
();
}
int
setprop
(
const
char
*
name
,
const
char
*
value
,
bool
trigger
)
{
...
...
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