├── .gitignore
├── AndroidFile
├── blacklist.txt
├── config.ini
├── log.txt
├── module_path
├── scheduled_tasks
│ └── create_crond.sh
└── whitelist.txt
├── CMakeLists.txt
├── META-INF
└── com
│ └── google
│ └── android
│ ├── update-binary
│ └── updater-script
├── README.md
├── RegularlyClean.c
├── clear.sh
├── customize.sh
├── data
└── crond_data
├── init.sh
├── module.prop
├── service.sh
├── state.sh
├── uninstall.sh
├── update.json
├── update.md
└── utils.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | /cmake-build-android
2 | /cmake-build-debug
3 | /.idea
--------------------------------------------------------------------------------
/AndroidFile/blacklist.txt:
--------------------------------------------------------------------------------
1 | #如果使用*通配符 记得把重要路径文件/文件夹写到白名单
2 | #使用通配符类似/*请改成/&*
3 | #只有规则最后的/*才需要改成/&*
4 | #改动示例:
5 | /data/media/0/test/* -> /data/media/0/test/&*
6 | /test/*/file/* -> /data/*/file/&*
7 | #文件示例: 本模块的.bak文件
8 | /data/media/0/Android/RegularlyClean/*.bak
9 | /data/media/0/Android/RegularlyClean/*/*.bak
10 |
11 | #文件夹示例:
12 | /data/media/0/ramdump/
13 |
14 | #如果文件删除不了,不到万不得已才使用[ /data/media/0/"文件\文件夹" ]
15 |
16 | #下面你可以自定义了!
17 | /storage/emulated/0/Download/.common
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/AndroidFile/config.ini:
--------------------------------------------------------------------------------
1 | # 定时每多少分钟运行一次 (必填: 数字1到60)
2 | # 示例 (意思时每隔10分钟执行一次)
3 | # minute=10
4 | minute=10
5 |
6 | # 模块运行范围
7 | # 注意: 这里没有24点,只有0到23点,不要填错咯!
8 | # 示例 (意思时在7-23点间运行)
9 | # what_time=7-23
10 | what_time=7-23
11 |
12 | # 定时每隔几天运行一次
13 | # 只可以填一个数字。(范围限制:1-31)
14 | # 示例 (意思是每隔三天执行一次)
15 | # what_day=3
16 | what_day=
17 |
18 | # 面具/KSU端控制功能。
19 | # 可以在管理器端控制模块是否运行。
20 | manager_control=y
21 |
22 | # APP监测功能。
23 | # 打开此功能后,当你打开指定APP就会触发清理。
24 | # 默认包名为MT管理器,打开MT管理器即可自动清理文件,主打眼不见心不烦。
25 |
26 | # 是否开启APP监测功能。
27 | clear_mod=y
28 |
29 | # 处于目标APP中只清理一次。
30 | clear_only_once=n
31 |
32 | # 监测APP的包名,每行一个写在"号内部。
33 | # 请不要动"号!
34 | clear="
35 | bin.mt.plus
36 | "
37 |
38 | # 大文件跳过模式 (安全模式)
39 | # 防止设置黑名单路径时删除可能的个人文件。
40 | bigfile_auto_skip=n
41 |
42 | # 当文件超过这个大小时会自动跳过清理,单位是MB。
43 | bigfile_mb=20
44 |
45 | # C 程序 Debug 模式。
46 | # 正常情况不需要开启。
47 | c_debug=n
48 |
49 | # 调试功能。
50 | # 一般情况不需要调整。
51 |
52 | # C 程序积极性。
53 | # 每次循环间隔时间(秒)。
54 | c_while=5
55 |
56 | # 在目标APP内延长的清理间隔(秒)。
57 | c_clear_sleep=120
--------------------------------------------------------------------------------
/AndroidFile/log.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HChenX/RegularlyClean/bde4fece67b0332ab863a18cf21562c1e78d1a6d/AndroidFile/log.txt
--------------------------------------------------------------------------------
/AndroidFile/module_path:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HChenX/RegularlyClean/bde4fece67b0332ab863a18cf21562c1e78d1a6d/AndroidFile/module_path
--------------------------------------------------------------------------------
/AndroidFile/scheduled_tasks/create_crond.sh:
--------------------------------------------------------------------------------
1 | path=${0%/*}
2 | path=$(dirname "$path")
3 | {
4 | [[ -f $path/module_path ]] && {
5 | module_path=$(cat $path/module_path)
6 | }
7 | } || {
8 | echo "-[!]: 未安装主模块!"
9 | exit 1
10 | }
11 | MODDIR=$module_path
12 | . $module_path/utils.sh
13 | config=$path/config.ini
14 |
15 | chmod -R 0777 $path
16 | chmod -R 0777 $module_path
17 |
18 | [[ ! -d $crondPath ]] && mkdir -p $crondPath
19 | {
20 | [[ -f $config ]] && {
21 | {
22 | . "$config" && {
23 | echo "- [i]: 文件读取成功"
24 | }
25 | } || {
26 | echo "- [!]: 文件读取异常,请审查(config.ini)文件内容!" && exit 1
27 | }
28 | }
29 | } || {
30 | echo "- [!]: 缺少$config文件" && exit 1
31 | }
32 |
33 | main() {
34 | case $bigfile_auto_skip in
35 | y | n) echo "- [i]: 填写正确 | bigfile_auto_skip=$bigfile_auto_skip" ;;
36 | *) echo "- [!]: 填写错误 | bigfile_auto_skip=$bigfile_auto_skip | 请填写y或n" && exit 1 ;;
37 | esac
38 | [[ $bigfile_auto_skip == y ]] && {
39 | {
40 | [[ $bigfile_mb -gt 0 ]] && {
41 | echo "- [i]: 填写正确 | bigfile_mb=$bigfile_mb"
42 | }
43 | } || {
44 | echo "- [!]: 填写错误 | bigfile_mb=$bigfile_mb | 请大于0" && exit 1
45 | }
46 | }
47 | case $clear_mod in
48 | y | n) echo "- [i]: 填写正确 | clear_mod=$clear_mod" ;;
49 | *) echo "- [!]: 填写错误 | clear_mod=$clear_mod | 请填写y或n" && exit 1 ;;
50 | esac
51 | open_value
52 | }
53 | open_value() {
54 | minute_mod() {
55 | {
56 | [[ $minute != "" ]] && {
57 | case $minute in
58 | [0-9]*) {
59 | [[ $minute -ge 1 ]] && [[ $minute -le 60 ]] && {
60 | echo "- [i]: 填写正确 | minute=$minute"
61 | }
62 | } || {
63 | echo "- [!]: 填写错误 | minute=$minute | 请重新填写" && exit 1
64 | } ;;
65 | esac
66 | minute="*/$minute"
67 | }
68 | } || {
69 | minute="*"
70 | }
71 | }
72 | time_mod() {
73 | {
74 | [[ $what_time != "" ]] && {
75 | {
76 | {
77 | ! echo "$what_time" | grep -q "-" && {
78 | what_time="*/$what_time"
79 | }
80 | } || {
81 | time_1=$(echo "$what_time" | awk -F "-" '{print $1}')
82 | time_2=$(echo "$what_time" | awk -F "-" '{print $2}')
83 | {
84 | [[ -z $time_1 ]] || [[ -z $time_2 ]] && {
85 | echo "- [!]: 填写错误 | what_time=$what_time" && exit 1
86 | }
87 | } || {
88 | {
89 | ! echo "$time_1" | grep -q "[0-9]"
90 | } || {
91 | ! echo "$time_2" | grep -q "[0-9]"
92 | } && {
93 | echo "- [!]: 填写错误 | what_time=$what_time | 填写数字" && exit 1
94 | }
95 | } || {
96 | {
97 | [[ ${#time_1} -ge 3 ]]
98 | } || {
99 | [[ ${#time_2} -ge 3 ]]
100 | } && {
101 | echo "- [!]: 填写错误 | what_time=$what_time | 不要超过3个字符" && exit 1
102 | }
103 | } || {
104 | {
105 | [[ $time_1 == "$time_2" ]]
106 | } && {
107 | echo "- [!]: 填写错误 | what_time=$what_time | 时间不能相同" && exit 1
108 | }
109 | } || {
110 | {
111 | [[ $time_1 -ge 24 ]]
112 | } || {
113 | [[ $time_2 -ge 24 ]]
114 | } && {
115 | echo "- [!]: 填写错误 | what_time=$what_time | 时间不能大于或等于24点 这里的24点是0点" && exit 1
116 | }
117 | } || {
118 | echo "- [i]: 填写正确 | what_time=$what_time"
119 | }
120 | }
121 | }
122 | }
123 | } || {
124 | what_time="*"
125 | }
126 | }
127 | day_mod() {
128 | {
129 | [[ $what_day != "" ]] && {
130 | {
131 | {
132 | [[ -z $what_day ]]
133 | } && {
134 | echo "- [!]: 填写错误 | what_day=$what_day | 格式: 数字1-31" && exit 1
135 | }
136 | } || {
137 | {
138 | ! echo "$what_day" | grep -q "[0-9]"
139 | } && {
140 | echo "- [!]: 填写错误 | what_day=$what_day | 请填写数字!" && exit 1
141 | }
142 | } || {
143 | {
144 | [[ $what_day -gt 31 ]] || [[ $what_day -lt 1 ]]
145 | } && {
146 | echo "- [!]: 填写错误 | what_day=$what_day | 范围限制:1-31" && exit 1
147 | }
148 | } || {
149 | echo "- [i]: 填写正确 | what_day=$what_day" && what_day="*/$what_day"
150 | }
151 | }
152 | } || {
153 | what_day="*"
154 | }
155 | }
156 | set_cron() {
157 | crond_rule="$minute $what_time $what_day * *"
158 | echo -n "$crond_rule" >"$module_path"/data/crond_data
159 | }
160 | kill_pid() {
161 | crond_pid="$(pgrep -f 'RegularlyClean' | grep -v $$)"
162 | [[ -n $crond_pid ]] && {
163 | for i in $crond_pid; do
164 | echo "- [i]: 杀死模块进程 | pid: $i"
165 | kill -9 "$i"
166 | done
167 | }
168 | }
169 | cron_on() {
170 | echo "$crond_rule $module_path/clear.sh" >$crondFile && crond -c "$crondPath"
171 | mPid="$(pgrep -f 'regularly.d' | grep -v $$)"
172 | {
173 | [[ $mPid == "" ]] && {
174 | echo "- [!]: 定时启动失败,运行失败" && exit 1
175 | }
176 | } || {
177 | echo "- [i]: 定时启动 | pid: $mPid" && logClear "成功修改配置,已经重新运行"
178 | {
179 | [[ -f $module_path/clear.sh ]] && {
180 | sh "$module_path"/clear.sh >/dev/null
181 | "$module_path"/RegularlyClean &
182 | echo "- [i]: 现在可以退出进程了"
183 | exit 0
184 | }
185 | } || {
186 | kill -9 "$mPid" && echo "- [!]: 模块脚本缺失!" && echo "- [!]: 已终止定时!" && logd "- [!]: 模块脚本缺失!" && logd "- [!]: 已终止定时!"
187 | }
188 | }
189 | }
190 | minute_mod
191 | time_mod
192 | day_mod
193 | set_cron
194 | kill_pid
195 | cron_on
196 | }
197 | main
198 |
--------------------------------------------------------------------------------
/AndroidFile/whitelist.txt:
--------------------------------------------------------------------------------
1 | #为了防止手残 可以把不被删除的文件或者文件夹输入进来
2 | #下面是例子 一行一个
3 |
4 | # 本模块文件
5 | /data/media/0/Android/RegularlyClean/*.txt
6 | /data/media/0/Android/RegularlyClean/*.ini
7 | /data/media/0/Android/RegularlyClean/*/*.sh
8 | /data/media/0/Android/RegularlyClean/module_path
9 |
10 | # 重要目录和文件
11 | /*/
12 | /data/
13 | /data/*/
14 | /data/adb/*
15 | /data/adb/*/*
16 | /data/media/0/
17 | /data/media/0/Download/
18 | /data/media/0/Android/
19 | /data/media/0/Android/data/
20 | /data/media/0/Android/media/
21 | /data/media/0/Android/obb/
22 | /data/media/0/DCIM/
23 | /data/media/0/MIUI/
24 | /data/media/0/Movies/
25 | /data/media/0/Music/
26 | /data/media/0/Pictures/
27 |
28 | /storage/
29 | /storage/emulated/0/
30 | /storage/emulated/0/Download/
31 | /storage/emulated/0/Android/
32 | /storage/emulated/0/Android/data/
33 | /storage/emulated/0/Android/media/
34 | /storage/emulated/0/Android/obb/
35 | /storage/emulated/0/DCIM/
36 | /storage/emulated/0/MIUI/
37 | /storage/emulated/0/Movies/
38 | /storage/emulated/0/Music/
39 | /storage/emulated/0/Pictures/
40 |
41 | /sdcard/
42 | /sdcard/Download/
43 | /sdcard/Android/
44 | /sdcard/Android/data/
45 | /sdcard/Android/media/
46 | /sdcard/Android/obb/
47 | /sdcard/DCIM/
48 | /sdcard/MIUI/
49 | /sdcard/Movies/
50 | /sdcard/Music/
51 | /sdcard/Pictures/
52 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.27)
2 | project(RegularlyClean C)
3 |
4 | set(CMAKE_C_STANDARD 23)
5 |
6 | add_executable(RegularlyClean
7 | RegularlyClean.c
8 | )
9 |
--------------------------------------------------------------------------------
/META-INF/com/google/android/update-binary:
--------------------------------------------------------------------------------
1 | #!/sbin/sh
2 |
3 | #################
4 | # Initialization
5 | #################
6 |
7 | umask 022
8 |
9 | # echo before loading util_functions
10 | ui_print() { echo "$1"; }
11 |
12 | require_new_magisk() {
13 | ui_print "*******************************"
14 | ui_print " Please install Magisk v20.4+! "
15 | ui_print "*******************************"
16 | exit 1
17 | }
18 |
19 | #########################
20 | # Load util_functions.sh
21 | #########################
22 |
23 | OUTFD=$2
24 | ZIPFILE=$3
25 |
26 | mount /data 2>/dev/null
27 |
28 | [ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk
29 | . /data/adb/magisk/util_functions.sh
30 | [ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk
31 |
32 | install_module
33 | exit 0
34 |
--------------------------------------------------------------------------------
/META-INF/com/google/android/updater-script:
--------------------------------------------------------------------------------
1 | #MAGISK
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
RegularlyClean
3 |
4 | 
5 | 
6 | 
7 | [](https://github.com/HChenX/RegularlyClean/releases)
8 | [](https://github.com/HChenX/RegularlyClean/releases)
9 | 
10 | 
11 | 
12 |
13 | [//]: # (
English | 简体中文
)
14 |
是一个可以定时自动清理垃圾文件的模块!
15 |
16 |
17 | # ✨模块介绍
18 |
19 | - 使用 crond 进行定时的自动垃圾文件清理模块。
20 | - 拥有超自由的自定义功能,随你所想!
21 | - 使用 c 语言高效代码实现部分功能。
22 |
23 | # 💡模块说明
24 |
25 | - 首先最重要的是模块基于:[Petit-Abba](https://github.com/Petit-Abba)
26 | 的 [black_and_white_list](https://github.com/Petit-Abba/black_and_white_list) 模块。
27 | - 本模块是基于其模块的超深度自定义拓展完善而来。
28 | - 于原模块区别如下:
29 |
30 | * 比如:
31 | * 1.支持自动安全模式,`/*`将会自动被忽略,需要替换成`/&*`使用,避免手滑勿清。
32 | * 2.支持大文件跳过,比如扫描到大于“20(可自定义)”MB的文件会被自动忽略,防止可能的勿清个人文件。(可选)
33 | * 3.支持在ROOT管理器直接控制模块是否运行,禁用模块停止运行、反之恢复。(可选)
34 | * 4.支持在自定义APP界面自动触发清理,比如进入MT自动清理一遍,主打眼不见心不烦。(可选)
35 | * 5.完全支持MAGISK和KSU等ROOT管理器。
36 | * 6.超强自定义清理时间定制。
37 | * 7.等更多精彩等你发掘···
38 |
39 | # 🙏致谢名单
40 |
41 | - 本模块代码参考了如下项目,对此表示由衷的感谢:
42 |
43 | | 项目名称 | 项目链接 |
44 | |:--------------------:|:--------------------------------------------------------------------------:|
45 | | black_and_white_list | [black_and_white_list](https://github.com/Petit-Abba/black_and_white_list) |
46 | | 翻译提供 | 提供者 |
47 | | 简体中文 | 焕晨HChen |
48 |
49 | # 📢项目声明
50 |
51 | - 任何对本项目的使用必须注明作者,抄袭是不可接受的!
52 |
53 | # 🌏免责声明
54 |
55 | - 使用本模块即代表愿意承担一切后果。
56 | - 任何由本项目衍生出的项目本项目不承担任何责任。
57 |
58 | # 🎉结尾
59 |
60 | - 感谢您愿意使用本模块!Enjoy your day! ♥️
61 |
--------------------------------------------------------------------------------
/RegularlyClean.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #define MAX_MEMORY 1024
10 |
11 | static char FILE_PATH[50] = "/data/media/0/Android/RegularlyClean/";
12 | char mMsg[200];
13 | char **appArray = NULL;
14 | char *modulePath = NULL;
15 | bool isDebug = false;
16 |
17 | void logVa(char *msg, ...);
18 |
19 | void logStr(char *msg);
20 |
21 | void logDebug(char *msg);
22 |
23 | void logDebugVa(char *msg, ...);
24 |
25 | void logWrite();
26 |
27 | bool killPid(char **pidArray);
28 |
29 | char **config(char *check);
30 |
31 | char *onlyReadOne(char **valueArray);
32 |
33 | char *vaPrintf(char *msg, va_list vaList);
34 |
35 | void reportErrorExit(char *log, char *msg) { // 报告错误并退出
36 | perror(msg);
37 | if (log != NULL) {
38 | logStr(log);
39 | }
40 | exit(EXIT_FAILURE);
41 | }
42 |
43 | char *getTime() { // 获取当前时间
44 | int TIME_PATH = 30; // 目测最少需要的字符数
45 | time_t curr_time;
46 | struct tm *local_time;
47 | char mTime[TIME_PATH];
48 | curr_time = time(NULL);
49 | local_time = localtime(&curr_time);
50 | strftime(mTime, TIME_PATH, "%g/%m/%d %H:%M", local_time);
51 | return strdup(mTime);
52 | }
53 |
54 | long getVagueTime() {
55 | long vagueTime;
56 | time_t curr_time;
57 | vagueTime = time(&curr_time);
58 | return vagueTime;
59 | }
60 |
61 | char *joint(char *value) {
62 | char result[MAX_MEMORY];
63 | strcpy(result, FILE_PATH);
64 | return strcat(result, value);
65 | }
66 |
67 | char *removeLinefeed(char *value) { // 移除换行符
68 | size_t len = strlen(value);
69 | if (len > 0 && value[len - 1] == '\n') {
70 | value[len - 1] = '\0';
71 | }
72 | return value;
73 | }
74 |
75 | char *removeLastPath(char *value, char remove) { // 移除路径最后的字段
76 | size_t len = strlen(value);
77 | for (int i = (int) len - 1; i >= 0; i--) {
78 | if (value[i] == remove) {
79 | value[i] = '\0';
80 | break;
81 | }
82 | }
83 | return value;
84 | }
85 |
86 | bool findCharAtEnd(char *value, char need) {
87 | size_t len = strlen(value);
88 | for (int i = (int) len - 1; i >= 0; i--) {
89 | if (value[i] == need) {
90 | return true;
91 | }
92 | }
93 | return false;
94 | }
95 |
96 | int stringLen(char *value) {
97 | size_t len = strlen(value);
98 | return (int) len;
99 | }
100 |
101 | void vaLog(char *msg, va_list vaList) {
102 | char *result = vaPrintf(msg, vaList);
103 | strcpy(mMsg, "");
104 | strcpy(mMsg, result);
105 | free(result);
106 | result = NULL;
107 | logWrite();
108 | }
109 |
110 | void logDebug(char *msg) {
111 | if (isDebug) {
112 | logStr(msg);
113 | }
114 | }
115 |
116 | void logDebugVa(char *msg, ...) {
117 | if (isDebug) {
118 | va_list vaList;
119 | va_start(vaList, msg);
120 | vaLog(msg, vaList);
121 | va_end(vaList);
122 | }
123 | }
124 |
125 | void logStr(char *msg) {
126 | strcpy(mMsg, "");
127 | strcpy(mMsg, msg);
128 | logWrite();
129 | }
130 |
131 | void logVa(char *msg, ...) {
132 | va_list vaList;
133 | va_start(vaList, msg);
134 | // vprintf(msg, vaList);
135 | vaLog(msg, vaList);
136 | va_end(vaList);
137 | }
138 |
139 | void logWrite() {
140 | FILE *fp;
141 | char *nowTime = getTime();
142 | fp = fopen(joint("log.txt"), "a");
143 | if (fp != NULL) {
144 | fseek(fp, 0, SEEK_END);
145 | fprintf(fp, "[%s] | %s\n", nowTime, mMsg);
146 | fclose(fp);
147 | } else {
148 | perror("Unable to write to logs");
149 | free(nowTime);
150 | nowTime = NULL;
151 | exit(EXIT_FAILURE);
152 | }
153 | strcpy(mMsg, "");
154 | free(nowTime);
155 | nowTime = NULL;
156 | }
157 |
158 | char *getModePath() { // 获取模块目录
159 | char *path = (char *) malloc(MAX_MEMORY);
160 | if (path == NULL) {
161 | reportErrorExit("[E] --开辟内存时失败>>>getModePath()", "malloc");
162 | return NULL;
163 | }
164 |
165 | ssize_t len = readlink("/proc/self/exe", path, MAX_MEMORY - 1);
166 | if (len == -1) {
167 | free(path);
168 | path = NULL;
169 | reportErrorExit("[E] --获取模块目录失败>>>/proc/self/exe", "readlink");
170 | return NULL;
171 | }
172 |
173 | // path[len] = '\0'; // 添加字符串结束符
174 | path = removeLastPath(path, '/');
175 | return path;
176 | }
177 |
178 | char *vaPrintf(char *msg, va_list vaList) { // 格式化字符串
179 | int size = vsnprintf(NULL, 0, msg, vaList);
180 | if (size < 0) {
181 | logDebug("[E] --格式化字符串时失败>>>vaPrintf()");
182 | reportErrorExit(NULL, "vaPrintf");
183 | return NULL;
184 | }
185 | char *result = (char *) malloc((size + 1) * sizeof(char));
186 | if (result == NULL) {
187 | logDebug("[E] --开辟内存时失败>>>vaPrintf()");
188 | reportErrorExit(NULL, "vaPrintf");
189 | return NULL;
190 | }
191 | vsnprintf(result, size + 1, msg, vaList);
192 | return result;
193 | }
194 |
195 | FILE *createShell(char *command, ...) { // 创建 Shell
196 | FILE *fp;
197 | va_list vaList;
198 | va_start(vaList, command);
199 | char *mCommand = vaPrintf(command, vaList);
200 | va_end(vaList);
201 | fp = popen(mCommand, "r");
202 | if (fp == NULL) {
203 | free(mCommand);
204 | mCommand = NULL;
205 | reportErrorExit("[E] --执行Shell命令时失败,程序退出>>>createShell()",
206 | "createShell");
207 | return NULL;
208 | }
209 | free(mCommand);
210 | mCommand = NULL;
211 | return fp;
212 | }
213 |
214 | char **findPid(char *find) { // 查找 PID
215 | FILE *fp;
216 | char read[10];
217 | int count = 0;
218 | char **pidArray = (char **) malloc(20 * sizeof(char *));
219 | if (pidArray == NULL) {
220 | logDebug("[E] --开辟内存时失败>>>findPid()");
221 | reportErrorExit(NULL, "findPid");
222 | return NULL;
223 | }
224 | fp = createShell("pgrep -f '%s' | grep -v $$", find);
225 | while (fgets(read, sizeof(read), fp) != NULL) {
226 | char *result = removeLinefeed(read);
227 | pidArray[count] = strdup(result);
228 | if (pidArray[count] == NULL) {
229 | logDebugVa("[E] --写入数据时失败,数据: %s>>>findPid()", result);
230 | break;
231 | // reportErrorExit(NULL, "findPid");
232 | }
233 | count = count + 1;
234 | }
235 | pidArray[count] = NULL;
236 | pclose(fp);
237 | return pidArray;
238 | }
239 |
240 | bool killPid(char **pidArray) { // 杀死指定 PID
241 | bool result = false;
242 | for (int i = 0; pidArray[i] != NULL; i++) {
243 | pid_t pid = (pid_t) strtol(pidArray[i], NULL, 10);
244 | free(pidArray[i]);
245 | pidArray[i] = NULL;
246 | if (kill(pid, 0) == 0) {
247 | if (kill(pid, SIGTERM) == 0) {
248 | logVa("[Stop] --成功终止定时进程:%d", pid);
249 | result = true;
250 | } else {
251 | logVa("[W] --不存在指定进程:%d", pid);
252 | result = false;
253 | break;
254 | }
255 | }
256 | }
257 | free(pidArray);
258 | pidArray = NULL;
259 | return result;
260 | }
261 |
262 | void changeSed(char *path) {
263 | FILE *fp;
264 | fp = createShell(
265 | "sed -i \"/^description=/c description=CROND: [定时进程已经终止,等待恢复中···]\" \"%s/module.prop\"",
266 | path);
267 | fflush(fp);
268 | pclose(fp);
269 | }
270 |
271 | void runSh(char *path, char *value) {
272 | FILE *fp;
273 | fp = createShell("su -c \"sh %s/%s &>/dev/null\"", path, value);
274 | fflush(fp);
275 | pclose(fp);
276 | }
277 |
278 | void runModuleSh(char *value) {
279 | if (modulePath == NULL) {
280 | modulePath = getModePath();
281 | }
282 | runSh(modulePath, value);
283 | }
284 |
285 | bool foregroundApp(char *pkg) {
286 | FILE *fp;
287 | fp = createShell("su -c \"dumpsys window | grep \"%s\" | grep \"mFocusedApp\"\"", pkg);
288 | int have = getc(fp);
289 | pclose(fp);
290 | if (have == EOF) {
291 | return false;
292 | } else {
293 | return true;
294 | }
295 | }
296 |
297 | char **config(char *check) { // 读取配置
298 | char *path = joint("config.ini");
299 | char read[MAX_MEMORY];
300 | char *name = NULL;
301 | char *value = NULL;
302 | int count = 0;
303 | bool keep = false;
304 | char ch = '#';
305 | FILE *fp;
306 | fp = fopen(path, "r");
307 | if (fp == NULL) {
308 | reportErrorExit("[W] --读取配置文件失败", "config");
309 | }
310 | char **valueArray = (char **) malloc(20 * sizeof(char *));
311 | if (valueArray == NULL) {
312 | fclose(fp);
313 | logDebug("[E] --开辟内存时失败>>>config()");
314 | reportErrorExit(NULL, "config");
315 | return NULL;
316 | }
317 | while (fgets(read, MAX_MEMORY, fp) != NULL) {
318 | strcpy(read, removeLinefeed(read));
319 | if (strcmp(read, "") == 0) continue;
320 | logDebugVa("[D] --读取配置文件: %s", read);
321 | char *result = strchr(read, ch);
322 | free(name);
323 | free(value);
324 | name = NULL;
325 | value = NULL;
326 | if (result == NULL) {
327 | char *token = strtok(read, "=");
328 | if (token != NULL || keep) {
329 | if (token != NULL) name = strdup(token);
330 | token = strtok(NULL, "=");
331 | if (token != NULL || keep) {
332 | // printf("read: %s token: %s\n", read, token);
333 | if (token != NULL && keep) {
334 | reportErrorExit("[E] --读取clear配置错误", "clear_error");
335 | break;
336 | }
337 | if (keep) {
338 | value = strdup(read);
339 | if (findCharAtEnd(value, '"')) {
340 | if (stringLen(value) == 1) {
341 | keep = false;
342 | continue;
343 | }
344 | value = removeLastPath(value, '"');
345 | valueArray[count] = strdup(value);
346 | count = count + 1;
347 | keep = false;
348 | continue;
349 | } else if (strcmp(value, "\"") == 0) {
350 | keep = false;
351 | continue;
352 | }
353 | } else value = strdup(token);
354 | if (strcmp(value, "\"") == 0 && strcmp(name, check) == 0) {
355 | keep = true;
356 | continue;
357 | } else {
358 | if (keep) {
359 | valueArray[count] = strdup(read);
360 | count = count + 1;
361 | continue;
362 | } else {
363 | if (strcmp(name, check) == 0) {
364 | valueArray[0] = strdup(value);
365 | count = 1;
366 | break;
367 | }
368 | }
369 | }
370 | }
371 | }
372 | } else {
373 | continue;
374 | }
375 | }
376 | valueArray[count] = NULL;
377 | fclose(fp);
378 | return valueArray;
379 | }
380 |
381 | bool checkState(char *value) {
382 | return strcmp(onlyReadOne(config(value)), "y") == 0;
383 | }
384 |
385 | char *onlyReadOne(char **valueArray) {
386 | int len = 0;
387 | for (int i = 0; valueArray[i] != NULL; ++i) {
388 | len = len + 1;
389 | }
390 | if (len > 1) {
391 | for (int i = 0; i < len; ++i) {
392 | free(valueArray[i]);
393 | valueArray[i] = NULL;
394 | }
395 | free(valueArray);
396 | valueArray = NULL;
397 | return "n";
398 | }
399 | char *read = valueArray[0];
400 | if (read == NULL) {
401 | read = "n";
402 | }
403 | free(valueArray[0]);
404 | valueArray[0] = NULL;
405 | free(valueArray);
406 | valueArray = NULL;
407 | return read;
408 | }
409 |
410 | int charToInt(char *value) {
411 | char *result = onlyReadOne(config(value));
412 | char *endptr;
413 | long num = strtol(result, &endptr, 10);
414 | if (*endptr != '\0') {
415 | logVa("[W] --转化字符串为数字失败,未转化部分:%s", endptr);
416 | return -1;
417 | } else {
418 | logDebugVa("[D] --to long: %ld", num);
419 | }
420 | return (int) num;
421 | }
422 |
423 | _Noreturn void whenWhile(bool foregroundClear, bool clearOnce,
424 | bool stateCheck, int sleepTime, int clearSleep) {
425 | bool lastState = true;
426 | bool shouldSleep = false;
427 | bool isForeground = false;
428 | bool isCleared = false;
429 | bool isKilled = false;
430 | long lastTime = 0;
431 | while (true) {
432 | if (!isKilled) {
433 | if (foregroundClear) {
434 | if (shouldSleep) {
435 | long nowTime = getVagueTime();
436 | if ((nowTime - lastTime) > clearSleep) {
437 | shouldSleep = false;
438 | }
439 | } else {
440 | for (int i = 0; appArray[i] != NULL; i++) {
441 | char *app = appArray[i];
442 | if (strcmp(app, "") != 0) {
443 | isForeground = foregroundApp(app);
444 | logDebugVa("[D] --foregroundApp: %s, isForeground: %d", app, isForeground);
445 | if (isForeground) {
446 | logVa("[I] --应用: %s 进入前台,触发清理", app);
447 | break;
448 | }
449 | }
450 | }
451 | if (isForeground) {
452 | if (clearOnce) {
453 | if (!isCleared) {
454 | runModuleSh("clear.sh");
455 | isCleared = true;
456 | }
457 | } else {
458 | runModuleSh("clear.sh");
459 | logDebugVa("[D] --isClear");
460 | }
461 | logDebugVa("[D] --clearOnce: %d, isCleared: %d", clearOnce, isCleared);
462 | lastTime = getVagueTime();
463 | shouldSleep = true;
464 | } else {
465 | if (clearOnce) isCleared = false;
466 | // shouldSleep = false;
467 | }
468 | }
469 | }
470 | }
471 | if (stateCheck) {
472 | char file[MAX_MEMORY];
473 | if (modulePath == NULL) {
474 | modulePath = getModePath();
475 | }
476 | snprintf(file, MAX_MEMORY, "%s/disable", modulePath);
477 | if (access(file, 0) == 0 && lastState) {
478 | logDebugVa("[D] --findFile: %s, lastState: %d, isKilled: %d", file, lastState, isKilled);
479 | char **pids = findPid("regularly.d");
480 | if (!killPid(pids)) {
481 | logStr("[E] --停止模块定时进程失败");
482 | } else {
483 | changeSed(modulePath);
484 | lastState = false;
485 | isKilled = true;
486 | }
487 | } else if (access(file, 0) != 0 && !lastState) {
488 | logDebugVa("[D] --fileRemove: %s, lastState: %d, isKilled: %d", file, lastState, isKilled);
489 | runModuleSh("state.sh");
490 | logStr("[Run] --成功重启进程");
491 | lastState = true;
492 | isKilled = false;
493 | }
494 | }
495 | sleep(sleepTime);
496 | }
497 | }
498 |
499 | void cleanup() {
500 | if (appArray != NULL) {
501 | for (int i = 0; appArray[i] != NULL; i++) {
502 | free(appArray[i]);
503 | appArray[i] = NULL;
504 | }
505 | free(appArray);
506 | appArray = NULL;
507 | }
508 | if (modulePath != NULL) {
509 | free(modulePath);
510 | modulePath = NULL;
511 | }
512 | // printf("clear\n");
513 | }
514 |
515 | int main() {
516 | atexit(cleanup);
517 | modulePath = getModePath();
518 | isDebug = checkState("c_debug");
519 | bool autoClear = checkState("clear_mod");
520 | bool clearOnce = checkState("clear_only_once");
521 | bool stateCheck = checkState("manager_control");
522 | int sleepTime = charToInt("c_while");
523 | int clearSleep = charToInt("c_clear_sleep");
524 | if (sleepTime == -1) sleepTime = 5;
525 | if (clearSleep == -1) clearSleep = 120;
526 | appArray = config("clear");
527 | logDebugVa("[D] --modulePath: %s, isDebug: %d, autoClear: %d, "
528 | "clearOnce: %d, stateCheck: %d, sleepTime: %d, clearSleep: %d", modulePath, isDebug,
529 | autoClear, clearOnce, stateCheck, sleepTime, clearSleep);
530 | for (int i = 0; appArray[i] != NULL; i++) {
531 | if (strcmp(appArray[i], "") == 0) continue;
532 | logDebugVa("[D] --app_map: %s", appArray[i]);
533 | }
534 | whenWhile(autoClear, clearOnce, stateCheck, sleepTime, clearSleep);
535 | }
536 |
--------------------------------------------------------------------------------
/clear.sh:
--------------------------------------------------------------------------------
1 | #全局变量
2 | MODDIR=${0%/*}
3 |
4 | # 跳过白名单次数判断
5 | print_pd_white_list() {
6 | white_file="$MODDIR/data/whitelist/$(echo "$1" | sed 's/\///g').ini"
7 | {
8 | [[ ! -e "$white_file" ]] && {
9 | echo "1" >"$white_file"
10 | logd "[skip] -[$(cat "$white_file")]- $2"
11 | }
12 | } || {
13 | # 小于3次则打印
14 | white_files="$(cat "$white_file")"
15 | [[ "$white_files" -lt "3" ]] && {
16 | echo "$((white_files + 1))" >"$white_file"
17 | logd "[skip] -[$(cat "$white_file")]- $2"
18 | }
19 | }
20 | }
21 |
22 | # 白名单列表通配符拓展
23 | whitelist_wildcard_list() {
24 | local IFS=$'\n'
25 | for wh in $(grep -v '#' <"$White_List"); do
26 | [[ -n "$wh" ]] && {
27 | echo "$wh"
28 | }
29 | done
30 | }
31 |
32 | pathCache=""
33 | isSkip=false
34 | addCache() {
35 | {
36 | [[ $pathCache == "" ]] && {
37 | pathCache=$1
38 | }
39 | } || {
40 | pathCache="$pathCache\n$1"
41 | }
42 | }
43 |
44 | doFindBigFile() {
45 | duFind=$(du -k -d 0 $1 2>/dev/null)
46 | for f in $duFind; do
47 | big=$(echo $f | cut -f1)
48 | path=$(echo $f | cut -f2)
49 | {
50 | [[ -f $path ]] && {
51 | {
52 | [[ $big -gt $skip ]] && {
53 | logd "[big] --跳过:$path"
54 | isSkip=true
55 | }
56 | } || {
57 | addCache $path
58 | }
59 | }
60 | } || {
61 | {
62 | [[ $big -gt $skip ]] && {
63 | for t in $path; do
64 | {
65 | [[ -f $t ]] && {
66 | size=$(du -k $t | cut -f1 2>/dev/null)
67 | {
68 | [[ $size -gt $skip ]] && {
69 | logd "[big] --跳过:$t"
70 | isSkip=true
71 | }
72 | } || {
73 | addCache $path
74 | }
75 | }
76 | } || {
77 | doFindBigFile "$t/*"
78 | }
79 | done
80 | }
81 | } || {
82 | addCache $path
83 | }
84 | }
85 | done
86 | }
87 |
88 | # 黑名单列表通配符拓展
89 | blacklist_wildcard_list() {
90 | local IFS=$'\n'
91 | grep -v '#' <"$Black_List" | while read -r bl; do
92 | [[ -n "$bl" ]] && {
93 | [[ "${bl: -2}" == "/*" ]] && {
94 | logd "[W] --检测到/*,请替换成/&*"
95 | logd "[skip] --跳过:$bl"
96 | continue
97 | }
98 | #把/&*替换成/*
99 | [[ "${bl: -3}" == "/&*" ]] && {
100 | bl=${bl//\/&\*/\/\*}
101 | }
102 | {
103 | [[ $skip != -1 ]] && {
104 | isSkip=false
105 | lastBl=""
106 | lastBl=$bl
107 | {
108 | {
109 | [[ ${bl: -1} == "/" ]] && {
110 | bl="$bl*"
111 | }
112 | }
113 | } || {
114 | [[ ${bl: -1} != "*" ]] && {
115 | {
116 | {
117 | [[ -d $(echo $bl) ]] && {
118 | bl="$bl/*"
119 | }
120 | }
121 | } || {
122 | {
123 | {
124 | [[ -f $(echo $bl) ]] && {
125 | size=$(du -k $bl | cut -f1 2>/dev/null)
126 | {
127 | {
128 | [[ $size -gt $skip ]] && {
129 | logd "[big] --跳过:$t"
130 | continue
131 | }
132 | } || {
133 | echo $bl
134 | continue
135 | }
136 | }
137 | }
138 | } || {
139 | # logd "[W] --异常路径,可能文件不存在:$bl"
140 | continue
141 | }
142 | }
143 | }
144 | }
145 | }
146 | doFindBigFile "$bl"
147 | {
148 | {
149 | [[ $isSkip == "false" ]] && {
150 | echo $lastBl
151 | }
152 | }
153 | } || {
154 | echo $pathCache
155 | pathCache=""
156 | }
157 | # [[ $big != "" ]] && [[ -d $bl ]] && {
158 | # {
159 | # [[ "${bl: -1}" == "/" ]] && {
160 | # bl="$bl*"
161 | # }
162 | # } || {
163 | # [[ "${bl: -1}" != "*" ]] && {
164 | # bl="$bl/*"
165 | # }
166 | # }
167 | # }
168 | }
169 | } || {
170 | for i in $bl; do
171 | echo "$i"
172 | done
173 | }
174 | }
175 | done
176 | }
177 |
178 | #主程序
179 | main_for() {
180 | # 重新定义字段分隔符 忽略空格和制表符
181 | local IFS=$'\n'
182 | # 因为重新定义字段分隔符 所以只需要for 不再需要while read
183 | for i in $(echo "$Black_List_Expand" | grep -v -F '*'); do
184 | # 文件夹
185 | [[ -d "$i" ]] && {
186 | #跳过指定目录,防止危险
187 | case $i in
188 | *'/.') continue ;;
189 | *'/./') continue ;;
190 | *'/..') continue ;;
191 | *'/../') continue ;;
192 | esac
193 | echo "$White_List_Expand" | grep -qw "$i" && {
194 | print_pd_white_list "$i" "白名单DIR: $i"
195 | continue
196 | }
197 | rm -rf "$i" && {
198 | let DIR++
199 | logd "[rm] --黑名单DIR: $i"
200 | echo "$DIR" >"$tmp_date"/dir
201 | }
202 | }
203 | # 文件
204 | [[ -f "$i" ]] && {
205 | echo "$White_List_Expand" | grep -qw "$i" && {
206 | print_pd_white_list "$i" "白名单FILE: $i"
207 | continue
208 | }
209 | rm -rf "$i" && {
210 | let FILE++
211 | logd "[rm] --黑名单FILE: $i"
212 | echo "$FILE" >"$tmp_date"/file
213 | }
214 | }
215 | done
216 | }
217 |
218 | . "$MODDIR"/utils.sh
219 | {
220 | [[ -f $config ]] && {
221 | . "$config" || {
222 | logd "- [!]: 文件读取异常,请审查(config.ini)文件内容!" && exit 1
223 | }
224 | }
225 | } || {
226 | logd "- [!]: 缺少$config文件" && exit 1
227 | }
228 |
229 | Black_List="$path/blacklist.txt"
230 | White_List="$path/whitelist.txt"
231 | {
232 | [[ $bigfile_auto_skip == y ]] && {
233 | skip="$bigfile_mb"
234 | skip=$(expr $skip \* 1024)
235 | }
236 | } || {
237 | skip=-1
238 | }
239 |
240 | Screen_status="$(dumpsys window policy | grep 'mInputRestricted' | cut -d= -f2)"
241 | {
242 | [[ "$Screen_status" != "true" ]] && {
243 | logd "[状态]: [亮屏] 执行"
244 | [[ ! -d $MODDIR/data/whitelist ]] && mkdir -p "$MODDIR"/data/whitelist
245 | [[ ! -d $MODDIR/data/date ]] && mkdir -p "$MODDIR"/data/date
246 | tmp_date="$MODDIR/data/date/$(date '+%Y%m%d')"
247 | dateFile=$(ls $MODDIR/data/date)
248 | [[ ! -d "$tmp_date" ]] && {
249 | rm -rf "$MODDIR"/data/date &>/dev/null
250 | mkdir -p "$tmp_date"
251 | echo "0" >"$tmp_date"/file
252 | echo "0" >"$tmp_date"/dir
253 | [[ $dateFile != "" ]] && {
254 | logNewDay
255 | }
256 | }
257 | FILE="$(cat "$tmp_date"/file)"
258 | DIR="$(cat "$tmp_date"/dir)"
259 | White_List_Expand="$(whitelist_wildcard_list)"
260 | Black_List_Expand="$(blacklist_wildcard_list)"
261 | main_for
262 |
263 | FILE="$(cat "$tmp_date"/file)"
264 | DIR="$(cat "$tmp_date"/dir)"
265 | sed -i "/^description=/c description=CROND: [ 今日已清除: $FILE个黑名单文件 | $DIR个黑名单文件夹 ]" "$MODDIR/module.prop"
266 | }
267 | } || {
268 | logd "[状态]: [息屏] 不执行"
269 | }
270 |
--------------------------------------------------------------------------------
/customize.sh:
--------------------------------------------------------------------------------
1 | outPut() {
2 | echo "$@"
3 | sleep 0.05
4 | }
5 |
6 | path="/data/media/0/Android/RegularlyClean"
7 | path_old="/data/media/0/Android/RegularlyClean_old"
8 |
9 | [[ -d $path ]] && {
10 | outPut "杀死正在运行的crond进程···"
11 | crond_pid="$(pgrep -f 'RegularlyClean' | grep -v $$)"
12 | [[ -n "$crond_pid" ]] && {
13 | for kill_pid in $crond_pid; do
14 | kill -9 "$kill_pid" && outPut "杀死crond进程: $kill_pid"
15 | done
16 | }
17 | outPut "备份历史文件···"
18 | rm -rf "$path_old" && mkdir -p "$path_old"
19 | cp -rf $path/* "$path_old"
20 | chmod -R 0777 $path_old
21 | rm -rf "$path"
22 | outPut "历史文件路径:$path_old"
23 | outPut "更新模块会导致原规则和配置被还原!!"
24 | outPut "被还原配置包括: "
25 | outPut "blacklist.txt, whitelist.txt, config.ini"
26 | outPut "劳烦从备份文件复制到规则和配置文件内!!"
27 | }
28 |
29 | mkdir -p $path
30 | cp -arf "$MODPATH"/AndroidFile/* $path/
31 | rm -rf "$MODPATH"/AndroidFile/
32 | outPut "安装完成!"
33 |
--------------------------------------------------------------------------------
/data/crond_data:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HChenX/RegularlyClean/bde4fece67b0332ab863a18cf21562c1e78d1a6d/data/crond_data
--------------------------------------------------------------------------------
/init.sh:
--------------------------------------------------------------------------------
1 | MODDIR=${0%/*}
2 |
3 | . "$MODDIR"/utils.sh
4 |
5 | logd "初始化完成!"
6 |
7 | {
8 | [[ -f $crondFile ]] && {
9 | crond -c $crondPath
10 | }
11 | } || {
12 | echo "*/10 7-23 * * * $MODDIR/data/clear.sh" >$crondFile
13 | echo -n "*/10 7-23 * * *" >$MODDIR/data/crond_data
14 | crond -c $crondPath
15 | }
16 |
17 | {
18 | [[ $(pgrep -f 'regularly.d' | grep -v $$) != "" ]] && {
19 | device
20 | logd "开始运行了!"
21 | logd "------------------------------------------------------------"
22 | }
23 | } || {
24 | device
25 | logd "运行失败!"
26 | exit 1
27 | }
28 |
--------------------------------------------------------------------------------
/module.prop:
--------------------------------------------------------------------------------
1 | id=RegularlyClean
2 | name=定时清理
3 | version=v6.0.0
4 | versionCode=2024051901
5 | author=焕晨HChen
6 | description=CROND: [ 等待刷新.. ]
7 | updateJson=https://raw.githubusercontent.com/HChenX/RegularlyClean/master/update.json
--------------------------------------------------------------------------------
/service.sh:
--------------------------------------------------------------------------------
1 | MODDIR=${0%/*}
2 |
3 | wait_login() {
4 | while [ "$(getprop sys.boot_completed)" != "1" ]; do
5 | sleep 1
6 | done
7 |
8 | while [ ! -d "/sdcard/Android" ]; do
9 | sleep 1
10 | done
11 | }
12 | wait_login
13 |
14 | . "$MODDIR"/utils.sh
15 | chmod -R 0777 "$MODDIR"
16 | chmod -R 0777 "$path"
17 | echo -n "$MODDIR" >"$path"/module_path
18 | logClear "开机启动成功!"
19 | killAll
20 | sh "$MODDIR"/init.sh
21 | "$MODDIR"/RegularlyClean &
--------------------------------------------------------------------------------
/state.sh:
--------------------------------------------------------------------------------
1 | #全局变量
2 | MODDIR=${0%/*}
3 |
4 | . "$MODDIR"/utils.sh
5 |
6 | killCrond
7 | {
8 | [[ $(du -k "$MODDIR"/data/crond_data | cut -f1) -ne 0 ]] && {
9 | time=$(cat "$MODDIR"/data/crond_data)
10 | echo -n "$time $MODDIR/clear.sh" >"$crondFile"
11 | crond -c "$crondPath"
12 | sed -i "/^description=/c description=CROND: [定时进程已恢复运行,请等待开始清理···]" "$MODDIR/module.prop"
13 | }
14 | } || {
15 | su -c "sh $path/scheduled_tasks/create_crond.sh &>/dev/null"
16 | }
17 |
--------------------------------------------------------------------------------
/uninstall.sh:
--------------------------------------------------------------------------------
1 | rm -rf /data/media/0/Android/RegularlyClean
2 | rm -rf /data/media/0/Android/RegularlyClean_old
--------------------------------------------------------------------------------
/update.json:
--------------------------------------------------------------------------------
1 | {
2 | "versionCode": 2024051901,
3 | "version": "v6.0.0",
4 | "zipUrl": "https://github.com/HChenX/RegularlyClean/releases/download/v.6.0.0/RegularlyClean.zip",
5 | "changelog": "https://raw.githubusercontent.com/HChenX/RegularlyClean/master/update.md"
6 | }
--------------------------------------------------------------------------------
/update.md:
--------------------------------------------------------------------------------
1 | ## 更新日志:
2 |
3 | ### 版本号:定时清理 v.6.0.0
4 |
5 | - 修复备份文件无法删除的问题。
6 | - 修复安全模式存在保护漏洞的问题。
7 | - 完善注释讲解,辅助填写正确的规则。
8 | - 优化代码逻辑,修复代码漏洞。
9 |
10 | ## Update:
11 |
12 | ### Version: RegularlyClean v.6.0.0
13 |
14 | - Fix the issue of backup files being unable to be deleted.
15 | - Fix the issue of security mode with protection vulnerabilities.
16 | - Improve annotation explanations and assist in filling out correct rules.
17 | - Optimize code logic and fix code vulnerabilities.
18 |
19 | ### Author by @焕晨HChen
20 |
--------------------------------------------------------------------------------
/utils.sh:
--------------------------------------------------------------------------------
1 | path="/data/media/0/Android/RegularlyClean"
2 | logFile="$path"/log.txt
3 | config="$path"/config.ini
4 | crondPath="$MODDIR"/data/regularly.d
5 | crondFile="$MODDIR"/data/regularly.d/root
6 |
7 | {
8 | [[ -f "/data/adb/ksu/bin/busybox" ]] && {
9 | alias crond="/data/adb/ksu/bin/busybox crond"
10 | }
11 | } || {
12 | {
13 | [[ -f "/data/adb/ap/bin/busybox" ]] && {
14 | alias crond="/data/adb/ap/bin/busybox crond"
15 | }
16 | } || {
17 | alias crond="\$( magisk --path )/.magisk/busybox/crond"
18 | }
19 | }
20 |
21 | logd() {
22 | echo "[$(date '+%g/%m/%d %H:%M')] | $1" >>$logFile
23 | }
24 |
25 | logClear() {
26 | echo "[$(date '+%g/%m/%d %H:%M')] | $1" >$logFile
27 | }
28 |
29 | logNewDay() {
30 | logClear "是新的一天!: [$(date +'%m/%d') 重置记录]"
31 | }
32 |
33 | killCrond() {
34 | pid="$(pgrep -f 'regularly.d' | grep -v $$)"
35 | [[ -n $pid ]] && {
36 | for kill_pid in $pid; do
37 | kill -9 "$kill_pid"
38 | done
39 | }
40 | }
41 |
42 | killAll() {
43 | pid="$(pgrep -f 'RegularlyClean' | grep -v $$)"
44 | [[ -n $pid ]] && {
45 | for kill_pid in $pid; do
46 | kill -9 "$kill_pid"
47 | done
48 | }
49 | }
50 |
51 | device() {
52 | logd "品牌: $(getprop ro.product.brand)"
53 | logd "型号: $(getprop ro.product.model)"
54 | logd "代号: $(getprop ro.product.device)"
55 | logd "安卓: $(getprop ro.build.version.release)"
56 | }
57 |
--------------------------------------------------------------------------------