1 #!/bin/sh /etc/rc.common
2 # Copyright 2023 MOSSDeF, Stan Grishin (stangri@melmac.ca)
3 # shellcheck disable=SC1091,SC2015,SC2016,SC3037,SC3043,SC3045,SC3057,SC3060
5 # shellcheck disable=SC2034
7 # shellcheck disable=SC2034
11 if type extra_command
1>/dev
/null
2>&1; then
12 extra_command
'allow' 'Allows domain in current block-list and config'
13 extra_command
'check' 'Checks if specified domain is found in current block-list'
14 extra_command
'dl' 'Force-downloads all enabled block-list'
15 extra_command
'killcache' 'Delete all cached files'
16 extra_command
'pause' 'Pauses AdBlocking for specified number of seconds (default: 60)'
17 extra_command
'sizes' 'Displays the file-sizes of enabled block-lists'
18 extra_command
'version' 'Show version information'
20 # shellcheck disable=SC2034
21 EXTRA_COMMANDS
='allow check dl killcache pause sizes status_service version'
22 # shellcheck disable=SC2034
23 EXTRA_HELP
=' allow Allows domain(s) in current block-list and config
24 check Checks if specified domain is found in current block-list
25 dl Force-downloads all enabled block-list
26 pause Pauses AdBlocking for specified number of seconds (default: 60)
27 sizes Displays the file-sizes of enabled block-lists'
30 readonly PKG_VERSION
='dev-test'
31 readonly packageName
='adblock-fast'
32 readonly serviceName
="$packageName $PKG_VERSION"
33 readonly packageConfigFile
="/etc/config/${packageName}"
34 readonly dnsmasqAddnhostsFile
="/var/run/${packageName}/dnsmasq.addnhosts"
35 readonly dnsmasqAddnhostsCache
="/var/run/${packageName}/dnsmasq.addnhosts.cache"
36 readonly dnsmasqAddnhostsGzip
="${packageName}.dnsmasq.addnhosts.gz"
37 readonly dnsmasqAddnhostsFilter
='s|^|127.0.0.1 |;s|$||'
38 readonly dnsmasqAddnhostsFilterIPv6
='s|^|:: |;s|$||'
39 readonly dnsmasqConfFile
="/tmp/dnsmasq.d/${packageName}"
40 readonly dnsmasqConfCache
="/var/run/${packageName}/dnsmasq.conf.cache"
41 readonly dnsmasqConfGzip
="${packageName}.dnsmasq.conf.gz"
42 readonly dnsmasqConfFilter
='s|^|local=/|;s|$|/|'
43 readonly dnsmasqIpsetFile
="/tmp/dnsmasq.d/${packageName}.ipset"
44 readonly dnsmasqIpsetCache
="/var/run/${packageName}/dnsmasq.ipset.cache"
45 readonly dnsmasqIpsetGzip
="${packageName}.dnsmasq.ipset.gz"
46 readonly dnsmasqIpsetFilter
='s|^|ipset=/|;s|$|/adb|'
47 readonly dnsmasqNftsetFile
="/tmp/dnsmasq.d/${packageName}.nftset"
48 readonly dnsmasqNftsetCache
="/var/run/${packageName}/dnsmasq.nftset.cache"
49 readonly dnsmasqNftsetGzip
="${packageName}.dnsmasq.nftset.gz"
50 readonly dnsmasqNftsetFilter
='s|^|nftset=/|;s|$|/4#inet#fw4#adb4|'
51 readonly dnsmasqNftsetFilterIPv6
='s|^|nftset=/|;s|$|/4#inet#fw4#adb4,6#inet#fw4#adb6|'
52 readonly dnsmasqServersFile
="/var/run/${packageName}/dnsmasq.servers"
53 readonly dnsmasqServersCache
="/var/run/${packageName}/dnsmasq.servers.cache"
54 readonly dnsmasqServersGzip
="${packageName}.dnsmasq.servers.gz"
55 readonly dnsmasqServersFilter
='s|^|server=/|;s|$|/|'
56 readonly unboundFile
="/var/lib/unbound/adb_list.${packageName}"
57 readonly unboundCache
="/var/run/${packageName}/unbound.cache"
58 readonly unboundGzip
="${packageName}.unbound.gz"
59 readonly unboundFilter
='s|^|local-zone: "|;s|$|" static|'
60 readonly A_TMP
="/var/${packageName}.hosts.a.tmp"
61 readonly B_TMP
="/var/${packageName}.hosts.b.tmp"
62 readonly jsonFile
="/dev/shm/$packageName-status.json"
63 readonly sharedMemoryError
="/dev/shm/$packageName-error"
64 readonly hostsFilter
='/localhost/d;/^#/d;/^[^0-9]/d;s/^0\.0\.0\.0.//;s/^127\.0\.0\.1.//;s/[[:space:]]*#.*$//;s/[[:cntrl:]]$//;s/[[:space:]]//g;/[`~!@#\$%\^&\*()=+;:"'\'',<>?/\|[{}]/d;/]/d;/\./!d;/^$/d;/[^[:alnum:]_.-]/d;'
65 readonly domainsFilter
='/^#/d;s/[[:space:]]*#.*$//;s/[[:space:]]*$//;s/[[:cntrl:]]$//;/[[:space:]]/d;/[`~!@#\$%\^&\*()=+;:"'\'',<>?/\|[{}]/d;/]/d;/\./!d;/^$/d;/[^[:alnum:]_.-]/d;'
66 readonly adBlockPlusFilter
='/^#/d;/^!/d;s/[[:space:]]*#.*$//;s/^||//;s/\^$//;s/[[:space:]]*$//;s/[[:cntrl:]]$//;/[[:space:]]/d;/[`~!@#\$%\^&\*()=+;:"'\'',<>?/\|[{}]/d;/]/d;/\./!d;/^$/d;/[^[:alnum:]_.-]/d;'
67 readonly dnsmasqFileFilter
='\|^server=/[[:alnum:]_.-].*/|!d;s|server=/||;s|/.*$||'
68 readonly dnsmasq2FileFilter
='\|^local=/[[:alnum:]_.-].*/|!d;s|local=/||;s|/.*$||'
69 readonly dnsmasq3FileFilter
='\|^address=/[[:alnum:]_.-].*/|!d;s|address=/||;s|/.*$||'
70 readonly _OK_
='\033[0;32m\xe2\x9c\x93\033[0m'
71 readonly _FAIL_
='\033[0;31m\xe2\x9c\x97\033[0m'
72 readonly __OK__
='\033[0;32m[\xe2\x9c\x93]\033[0m'
73 readonly __FAIL__
='\033[0;31m[\xe2\x9c\x97]\033[0m'
74 readonly _ERROR_
='\033[0;31mERROR\033[0m'
75 readonly _WARNING_
='\033[0;33mWARNING\033[0m'
76 # shellcheck disable=SC2155
77 readonly ipset
="$(command -v ipset)"
78 # shellcheck disable=SC2155
79 readonly nft
="$(command -v nft)"
80 readonly canaryDomainsMozilla
='use-application-dns.net'
81 readonly canaryDomainsiCloud
='mask.icloud.com mask-h2.icloud.com'
92 load_environment_flag
=
96 debug
() { local i j
; for i
in "$@"; do eval "j=\$$i"; echo "${i}: ${j} "; done; }
98 uci_add_list_if_new() {
104 [ -n "$PACKAGE" ] && [ -n "$CONFIG" ] && [ -n "$OPTION" ] && [ -n "$VALUE" ] || return 1
105 for i in $(uci_get "$PACKAGE" "$CONFIG" "$OPTION"); do
106 [ "$i" = "$VALUE" ] && return 0
108 uci_add_list "$PACKAGE" "$CONFIG" "$OPTION" "$VALUE"
114 /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} changes "$PACKAGE${CONFIG:+.$CONFIG}${OPTION:+.$OPTION}"
117 ipset
() { "$ipset" "$@" >/dev
/null
2>&1; }
118 nft
() { "$nft" "$@" >/dev
/null
2>&1; }
123 errorConfigValidationFail
) r
="$packageName config validation failed";;
124 errorServiceDisabled
) r
="$packageName is currently disabled";;
126 r
="dnsmasq ipset support is enabled in $packageName, but dnsmasq is either not installed or installed dnsmasq does not support ipset";;
128 r
="dnsmasq ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:net' type";;
129 errorNoDnsmasqNftset
)
130 r
="dnsmasq nft set support is enabled in $packageName, but dnsmasq is either not installed or installed dnsmasq does not support nft set";;
131 errorNoNft
) r
="dnsmasq nft sets support is enabled in $packageName, but nft is not installed";;
132 errorNoWanGateway
) r
="The ${serviceName} failed to discover WAN gateway";;
133 errorOutputDirCreate
) r
="failed to create directory for %s file";;
134 errorOutputFileCreate
) r
="failed to create $outputFile file";;
135 errorFailDNSReload
) r
="failed to restart/reload DNS resolver";;
136 errorSharedMemory
) r
="failed to access shared memory";;
137 errorSorting
) r
="failed to sort data file";;
138 errorOptimization
) r
="failed to optimize data file";;
139 errorAllowListProcessing
) r
="failed to process allow-list";;
140 errorDataFileFormatting
) r
="failed to format data file";;
141 errorMovingDataFile
) r
="failed to move data file '${A_TMP}' to '${outputFile}'";;
142 errorCreatingCompressedCache
) r
="failed to create compressed cache";;
143 errorRemovingTempFiles
) r
="failed to remove temporary files";;
144 errorRestoreCompressedCache
) r
="failed to unpack compressed cache";;
145 errorRestoreCache
) r
="failed to move '$outputCache' to '$outputFile'";;
146 errorOhSnap
) r
="failed to create block-list or restart DNS resolver";;
147 errorStopping
) r
="failed to stop $serviceName";;
148 errorDNSReload
) r
="failed to reload/restart DNS resolver";;
149 errorDownloadingConfigUpdate
) r
="failed to download Config Update file";;
150 errorDownloadingList
) r
="failed to download";;
151 errorParsingConfigUpdate
) r
="failed to parse Config Update file";;
152 errorParsingList
) r
="failed to parse";;
153 errorNoSSLSupport
) r
="no HTTPS/SSL support on device";;
154 errorCreatingDirectory
) r
="failed to create output/cache/gzip file directory";;
155 errorDetectingFileType
) r
="failed to detect format";;
156 errorNothingToDo
) r
="no blocked list URLs nor blocked-domains enabled";;
158 statusNoInstall
) r
="$serviceName is not installed or not found";;
159 statusStopped
) r
="Stopped";;
160 statusStarting
) r
="Starting";;
161 statusRestarting
) r
="Restarting";;
162 statusForceReloading
) r
="Force Reloading";;
163 statusDownloading
) r
="Downloading";;
164 statusProcessing
) r
="Processing";;
165 statusError
) r
="Error";;
166 statusWarning
) r
="Warning";;
167 statusFail
) r
="Fail";;
168 statusSuccess
) r
="Success";;
170 warningExternalDnsmasqConfig
)
171 r
="use of external dnsmasq config file detected, please set 'dns' option to 'dnsmasq.conf'";;
172 warningMissingRecommendedPackages
) r
="Some recommended packages are missing";;
173 warningInvalidCompressedCacheDir
) r
="invalid compressed cache directory '%s'";;
178 output_ok
() { output
1 "$_OK_"; output
2 "$__OK__\\n"; }
179 output_okn
() { output
1 "$_OK_\\n"; output
2 "$__OK__\\n"; }
180 output_fail
() { output
1 "$_FAIL_"; output
2 "$__FAIL__\\n"; }
181 output_failn
() { output
1 "$_FAIL_\\n"; output
2 "$__FAIL__\\n"; }
182 str_replace
() { printf "%b" "$1" |
sed -e "s/$(printf "%b
" "$2")/$(printf "%b
" "$3")/g"; }
183 str_contains
() { test "$1" != "$(str_replace "$1" "$2" '')"; }
184 is_greater
() { test "$(printf '%s\n' "$@
" | sort -V | head -n 1)" != "$1"; }
185 is_greater_or_equal
() { test "$(printf '%s\n' "$@
" | sort -V | head -n 1)" = "$2"; }
186 is_chaos_calmer
() { ubus
-S call system board |
grep -q 'Chaos Calmer'; }
187 led_on
(){ if [ -n "${1}" ] && [ -e "${1}/trigger" ]; then echo 'default-on' > "${1}/trigger" 2>&1; fi; }
188 led_off(){ if [ -n "${1}" ] && [ -e "${1}/trigger" ]; then echo 'none' > "${1}/trigger" 2>&1; fi; }
189 dnsmasq_hup
() { killall
-q -s HUP dnsmasq
; }
190 dnsmasq_kill
() { killall
-q -s KILL dnsmasq
; }
191 dnsmasq_restart
() { /etc
/init.d
/dnsmasq restart
>/dev
/null
2>&1; }
192 unbound_restart
() { /etc
/init.d
/unbound restart
>/dev
/null
2>&1; }
193 is_present
() { command -v "$1" >/dev
/null
2>&1; }
194 sanitize_dir
() { [ -d "$(readlink -fn "$1")" ] && readlink
-fn "$1"; }
197 # Can take a single parameter (text) to be output at any verbosity
198 # Or target verbosity level and text to be output at specifc verbosity
199 local msg memmsg logmsg
200 local sharedMemoryOutput
="/dev/shm/$packageName-output"
201 verbosity
="${verbosity:-2}"
202 if [ $# -ne 1 ]; then
203 if [ $
((verbosity
& $1)) -gt 0 ] ||
[ "$verbosity" = "$1" ]; then shift; else return 0; fi
205 [ -t 1 ] && printf "%b" "$1"
206 msg
="${1//$serviceName /service }";
207 if [ "$(printf "%b
" "$msg" | wc -l)" -gt 0 ]; then
208 [ -s "$sharedMemoryOutput" ] && memmsg
="$(cat "$sharedMemoryOutput")"
209 logmsg
="$(printf "%b
" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')"
210 logger
-t "${packageName:-service} [$$]" "$(printf "%b
" "$logmsg")"
211 rm -f "$sharedMemoryOutput"
213 printf "%b" "$msg" >> "$sharedMemoryOutput"
219 local i j wan_if wan_gw wan_proto
220 local counter wan_if_timeout
="$procd_boot_wan_timeout" wan_gw_timeout
='5'
222 while [ -z "$wan_if" ]; do
224 network_find_wan wan_if
225 if [ -n "$wan_if" ]; then
226 output
"WAN interface found: '${wan_if}'.\\n"
229 if [ "$counter" -gt "$wan_if_timeout" ]; then
230 output
"WAN interface timeout, assuming 'wan'.\\n"
234 counter
=$
((counter
+1))
235 output
"Waiting to discover WAN Interface...\\n"
240 wan_proto
="$(uci -q get "network.
${wan_if}.proto
")"
241 if [ "$wan_proto" = 'pppoe' ]; then
242 wan_gw_timeout
=$
((wan_gw_timeout
+10))
244 while [ "$counter" -le "$wan_gw_timeout" ]; do
246 network_get_gateway wan_gw
"$wan_if"
247 if [ -n "$wan_gw" ]; then
248 output
"WAN gateway found: '${wan_gw}.'\\n"
251 counter
=$
((counter
+1))
252 output
"Waiting to discover $wan_if gateway...\\n"
255 json add error
"errorNoWanGateway"
256 output
"${_ERROR_}: $(get_text 'errorNoWanGateway')!\\n"; return 1;
260 local cfg
="$1" var
="$2"
262 config_get en
"$cfg" enabled
'1'
263 config_get action
"$cfg" action
'block'
264 config_get url
"$cfg" url
265 if [ "$en" = '1' ]; then
266 if [ "$action" = 'allow' ]; then
267 allowed_url
="${allowed_url:+$allowed_url }${url}"
269 blocked_url
="${blocked_url:+$blocked_url }${url}"
276 if [ "$(head -1 "$file")" = '[Adblock Plus]' ] || \
277 grep -q '^||' "$file"; then
279 elif grep -q '^server=' "$file"; then
281 elif grep -q '^local=' "$file"; then
283 elif grep -q '^address=' "$file"; then
285 elif grep -q '^0.0.0.0' "$file" ||
grep -q '^127.0.0.1' "$file"; then
287 elif [ -n "$(sed "$domainsFilter" "$file" | head -1)" ]; then
291 # detect_file_type() {
293 # if [ -n "$(sed "$adBlockPlusFilter" "$file" | head -1)" ]; then
295 # elif [ -n "$(sed "$dnsmasqFileFilter" "$file" | head -1)" ]; then
297 # elif [ -n "$(sed "$dnsmasq2FileFilter" "$file" | head -1)" ]; then
299 # elif [ -n "$(sed "$hostsFilter" "$file" | head -1)" ]; then
301 # elif [ -n "$(sed "$domainsFilter" "$file" | head -1)" ]; then
308 local validation_result
="$1" param
="$2"
310 [ -z "$load_environment_flag" ] ||
return 0
312 if [ "$validation_result" != '0' ]; then
313 json add error
"errorConfigValidationFail"
314 output
"${_ERROR_}: $(get_text 'errorConfigValidationFail')!\\n"
315 output
"Please check if the '$packageConfigFile' contains correct values for config options.\\n"
319 if [ "$enabled" -eq 0 ]; then
320 json add error
"errorServiceDisabled"
321 output
"${_ERROR_}: $(get_text 'errorServiceDisabled')!\\n"
322 output
"Run the following commands before starting service again:\\n"
323 output
"uci set ${packageName}.config.enabled='1'; uci commit $packageName;\\n"
327 if [ "$debug" -ne 0 ]; then
328 exec 1>>"/tmp/$packageName.log"
333 if [ -n "$dnsmasq_config_file_url" ]; then
337 if [ "$param" != 'quiet' ]; then
338 json add warning
"warningExternalDnsmasqConfig"
339 output
"${_WARNING_}: $(get_text 'warningExternalDnsmasqConfig')!\\n"
346 dnsmasq.addnhosts|dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset|dnsmasq.servers
)
347 if dnsmasq
-v 2>/dev
/null |
grep -q 'no-IDN' ||
! dnsmasq
-v 2>/dev
/null |
grep -q -w 'IDN'; then
357 if dnsmasq
-v 2>/dev
/null |
grep -q 'no-ipset' ||
! dnsmasq
-v 2>/dev
/null |
grep -q -w 'ipset'; then
358 if [ "$param" != 'quiet' ]; then
359 json add error
"errorNoDnsmasqIpset"
360 output
"${_ERROR_}: $(get_text 'errorNoDnsmasqIpset')!\\n"
362 dns
='dnsmasq.servers'
364 if ! ipset
help hash:net
; then
365 if [ "$param" != 'quiet' ]; then
366 json add error
"errorNoIpset"
367 output
"${_ERROR_}: $(get_text 'errorNoIpset')!\\n"
369 dns
='dnsmasq.servers'
373 if dnsmasq
-v 2>/dev
/null |
grep -q 'no-nftset' ||
! dnsmasq
-v 2>/dev
/null |
grep -q -w 'nftset'; then
374 if [ "$param" != 'quiet' ]; then
375 json add error
"errorNoDnsmasqNftset"
376 output
"${_ERROR_}: $(get_text 'errorNoDnsmasqNftset')!\\n"
378 dns
='dnsmasq.servers'
380 if [ -z "$nft" ]; then
381 if [ "$param" != 'quiet' ]; then
382 json add error
"errorNoNft"
383 output
"${_ERROR_}: $(get_text 'errorNoNft')!\\n"
385 dns
='dnsmasq.servers'
390 if [ "$(sanitize_dir "$compressed_cache_dir")" = '/' ]; then
391 compressed_cache_dir
=''
392 elif [ -n "$(sanitize_dir "$compressed_cache_dir")" ]; then
393 compressed_cache_dir
="$(sanitize_dir "$compressed_cache_dir")"
395 json add warning
'warningInvalidCompressedCacheDir' "$compressed_cache_dir"
396 compressed_cache_dir
="/etc"
401 outputFilter
="$dnsmasqAddnhostsFilter"
402 outputFile
="$dnsmasqAddnhostsFile"
403 outputCache
="$dnsmasqAddnhostsCache"
404 outputGzip
="${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
405 if [ "$ipv6_enabled" -ne 0 ]; then
406 outputFilterIPv6
="$dnsmasqAddnhostsFilterIPv6"
408 rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "${compressed_cache_dir}/${dnsmasqConfGzip}"
409 rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
410 rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
411 rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
412 rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
415 outputFilter
="$dnsmasqConfFilter"
416 outputFile
="$dnsmasqConfFile"
417 outputCache
="$dnsmasqConfCache"
418 outputGzip
="${compressed_cache_dir}/${dnsmasqConfGzip}"
419 rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
420 rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
421 rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
422 rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
423 rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
426 outputFilter
="$dnsmasqIpsetFilter"
427 outputFile
="$dnsmasqIpsetFile"
428 outputCache
="$dnsmasqIpsetCache"
429 outputGzip
="${compressed_cache_dir}/${dnsmasqIpsetGzip}"
430 rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
431 rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "${compressed_cache_dir}/${dnsmasqConfGzip}"
432 rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
433 rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
434 rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
437 if [ "$ipv6_enabled" -ne 0 ]; then
438 outputFilter
="$dnsmasqNftsetFilterIPv6"
440 outputFilter
="$dnsmasqNftsetFilter"
442 outputFile
="$dnsmasqNftsetFile"
443 outputCache
="$dnsmasqNftsetCache"
444 outputGzip
="${compressed_cache_dir}/${dnsmasqNftsetGzip}"
445 rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
446 rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "${compressed_cache_dir}/${dnsmasqConfGzip}"
447 rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
448 rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
449 rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
452 outputFilter
="$dnsmasqServersFilter"
453 outputFile
="$dnsmasqServersFile"
454 outputCache
="$dnsmasqServersCache"
455 outputGzip
="${compressed_cache_dir}/${dnsmasqServersGzip}"
456 rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
457 rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "${compressed_cache_dir}/${dnsmasqConfGzip}"
458 rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
459 rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
460 rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
463 outputFilter
="$unboundFilter"
464 outputFile
="$unboundFile"
465 outputCache
="$unboundCache"
466 outputGzip
="$unboundGzip"
467 rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
468 rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "${compressed_cache_dir}/${dnsmasqConfGzip}"
469 rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
470 rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
471 rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
475 for i
in "$jsonFile" "$outputFile" "$outputCache" "$outputGzip"; do
476 if ! mkdir
-p "$(dirname "$i")"; then
477 if [ "$param" != 'quiet' ]; then
478 json add error
"errorOutputDirCreate" "$i"
479 output
"${_ERROR_}: $(get_text 'errorOutputDirCreate' "$i")!\\n"
484 is_present
'gawk' && awk='gawk'
485 if ! is_present
'/usr/libexec/grep-gnu' ||
! is_present
'/usr/libexec/sed-gnu' || \
486 ! is_present
'/usr/libexec/sort-coreutils' ||
! is_present
'gawk'; then
487 local s
="opkg update; opkg --force-overwrite install"
488 is_present
'gawk' || s
="$s gawk"
489 is_present
'/usr/libexec/grep-gnu' || s
="$s grep"
490 is_present
'/usr/libexec/sed-gnu' || s
="$s sed"
491 is_present
'/usr/libexec/sort-coreutils' || s
="$s coreutils-sort"
492 if [ "$param" != 'quiet' ]; then
493 json add warning
"warningMissingRecommendedPackages" "${i}"
494 output
"${_WARNING_}: $(get_text 'warningMissingRecommendedPackages'), install them by running:\\n"
498 # Prefer curl because it supports the file:// scheme.
499 if is_present
'curl'; then
500 dl_command
='curl --silent --insecure'
501 dl_command
="${dl_command}${curl_additional_param:+ $curl_additional_param}"
502 dl_command
="${dl_command}${curl_max_file_size:+ --max-filesize $curl_max_file_size}"
503 dl_command
="${dl_command}${curl_retry:+ --retry $curl_retry}"
504 dl_command
="${dl_command}${download_timeout:+ --connect-timeout $download_timeout}"
506 elif is_present
'/usr/libexec/wget-ssl'; then
507 dl_command
='/usr/libexec/wget-ssl --no-check-certificate -q'
508 dl_command
="${dl_command}${download_timeout:+ --timeout $download_timeout}"
510 size_command
='/usr/libexec/wget-ssl --no-check-certificate -q -O /dev/null --server-response'
511 size_command
="${size_command}${download_timeout:+ --timeout $download_timeout}"
512 elif is_present wget
&& wget
--version 2>/dev
/null |
grep -q "+https"; then
513 dl_command
="wget --no-check-certificate -q"
514 dl_command
="${dl_command}${download_timeout:+ --timeout $download_timeout}"
516 size_command
='wget --no-check-certificate -q -O /dev/null --server-response'
517 size_command
="${size_command}${download_timeout:+ --timeout $download_timeout}"
519 dl_command
="uclient-fetch --no-check-certificate -q"
520 dl_command
="${dl_command}${download_timeout:+ --timeout $download_timeout}"
523 led
="${led:+/sys/class/leds/$led}"
524 if curl
--version 2>/dev
/null |
grep -q "https" \
525 || wget
--version 2>/dev
/null |
grep -q "+https" \
526 ||
grep -q "libustream-mbedtls" /usr
/lib
/opkg
/status \
527 ||
grep -q "libustream-openssl" /usr
/lib
/opkg
/status \
528 ||
grep -q "libustream-wolfssl" /usr
/lib
/opkg
/status
; then
533 config_load
"$packageName"
534 config_foreach append_url
'file_url'
535 load_environment_flag
=1
536 cache
'test' && return 0
537 cache
'test_gzip' && return 0
538 if [ "$param" = 'on_boot' ]; then
539 load_network
"$param"
547 local url
="$1" size size_command
548 [ -n "$url" ] ||
return 0
549 is_present
'curl' ||
return 0
550 size_command
='curl --silent --insecure --fail --head --request GET'
551 size
="$($size_command "$url" | grep -Po '^[cC]ontent-[lL]ength: \K\w+')"
555 get_local_filesize
() {
557 [ -f "$file" ] ||
return 0
558 if is_present stat
; then
559 size
="$(stat -c%s "$file")"
560 elif is_present
wc; then
561 size
="$(wc -c < "$file")"
567 local cfg
="$1" param
="$2"
570 if [ "$(uci_get 'dhcp' "$cfg" 'serversfile')" = "$dnsmasqServersFile" ]; then
571 uci_remove
'dhcp' "$cfg" 'serversfile'
573 uci_add_list_if_new
'dhcp' "$cfg" 'addnhosts' "$dnsmasqAddnhostsFile"
575 cleanup|dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset|unbound.adb_list
)
576 uci_remove_list
'dhcp' "$cfg" 'addnhosts' "$dnsmasqAddnhostsFile"
577 if [ "$(uci_get 'dhcp' "$cfg" 'serversfile')" = "$dnsmasqServersFile" ]; then
578 uci_remove
'dhcp' "$cfg" 'serversfile'
582 uci_remove_list
'dhcp' "$cfg" 'addnhosts' "$dnsmasqAddnhostsFile"
583 if [ "$(uci_get 'dhcp' "$cfg" 'serversfile')" != "$dnsmasqServersFile" ]; then
584 uci_set
'dhcp' "$cfg" 'serversfile' "$dnsmasqServersFile"
591 local param output_text i
594 if [ ! -s "$outputFile" ]; then
595 json
set status
"statusFail"
596 json add error
"errorOutputFileCreate"
597 output
"${_ERROR_}: $(get_text 'errorOutputFileCreate')!\\n"
602 if [ "$dnsmasq_instance" = "*" ]; then
603 config_foreach resolver_config
'dnsmasq' "$dns"
604 elif [ -n "$dnsmasq_instance" ]; then
605 for i
in $dnsmasq_instance; do
606 resolver_config
"@dnsmasq[$i]" "$dns" || resolver_config
"$i" "$dns"
611 dnsmasq.addnhosts|dnsmasq.servers
)
612 chmod 660 "$outputFile"
613 chown root
:dnsmasq
"$outputFile"
614 param
=dnsmasq_restart
615 output_text
='Reloading dnsmasq'
617 dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset
)
618 chmod 660 "$outputFile"
619 chown root
:dnsmasq
"$outputFile"
620 param
=dnsmasq_restart
621 output_text
='Restarting dnsmasq'
624 param
=unbound_restart
625 output_text
='Restarting Unbound'
629 if [ -n "$(uci_changes dhcp)" ]; then
631 if [ "$param" = 'unbound_restart' ]; then
632 param
='dnsmasq_restart; unbound_restart;'
633 output_text
='Restarting Unbound/dnsmasq'
635 param
=dnsmasq_restart
636 output_text
='Restarting dnsmasq'
639 output
1 "$output_text "
640 output
2 "$output_text "
641 json
set message
"$output_text"
642 if eval "$param"; then
643 json
set status
"statusSuccess"
648 json
set status
"statusFail"
649 json add error
"errorDNSReload"
650 output
"${_ERROR_}: $(get_text 'errorDNSReload')!\\n"
656 dnsmasq.addnhosts|dnsmasq.servers
)
657 param
=dnsmasq_restart
659 dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset
)
660 param
=dnsmasq_restart
663 param
=unbound_restart
666 if [ -n "$(uci_changes dhcp)" ]; then
668 if [ "$param" = 'unbound_restart' ]; then
669 param
='dnsmasq_restart; unbound_restart;'
671 param
=dnsmasq_restart
679 dnsmasq.addnhosts|dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset|dnsmasq.servers
)
680 param
=dnsmasq_restart
683 param
=unbound_restart
693 # shellcheck disable=SC2034
694 local action
="$1" param
="$2" value
="$3"
696 # shellcheck disable=SC2124
697 local extras
="$@" line
698 local status message error stats
699 local reload restart curReload curRestart ret i
700 if [ -s "$jsonFile" ]; then
701 json_load_file
"$jsonFile" 2>/dev
/null
702 json_select
'data' 2>/dev
/null
703 for i
in status message error stats reload restart
; do
704 json_get_var
"$i" "$i" 2>/dev
/null
711 curReload
="$parallel_downloads $debug $download_timeout \
712 $allowed_domain $blocked_domain $allowed_url $blocked_url $dns \
713 $config_update_enabled $config_update_url $dnsmasq_config_file_url \
714 $curl_additional_param $curl_max_file_size $curl_retry"
715 curRestart
="$compressed_cache $compressed_cache_dir $force_dns $led \
717 if [ ! -s "$jsonFile" ]; then
719 elif [ "$curReload" != "$reload" ]; then
721 elif [ "$curRestart" != "$restart" ]; then
727 printf "%b" "$(eval echo "\$
$param")"; return;;
731 line
="$(eval echo "\$
$param")"
732 eval "$param"='${line:+$line }${value}${extras:+|$extras}'
737 unset status message error stats
;;
739 unset reload restart
;;
747 reload
="$parallel_downloads $debug $download_timeout \
748 $allowed_domain $blocked_domain $allowed_url $blocked_url $dns \
749 $config_update_enabled $config_update_url $dnsmasq_config_file_url \
750 $curl_additional_param $curl_max_file_size $curl_retry"
751 restart
="$compressed_cache $compressed_cache_dir $force_dns $led \
755 eval "$param"='${value}${extras:+|$extras}';;
760 json_add_object
'data'
761 json_add_string version
"$PKG_VERSION"
762 json_add_string status
"$status"
763 json_add_string message
"$message"
764 json_add_string error
"$error"
765 json_add_string stats
"$stats"
766 json_add_string reload
"$reload"
767 json_add_string restart
"$restart"
769 mkdir
-p "$(dirname "$jsonFile")"
770 json_dump
> "$jsonFile"
778 [ -s "$outputFile" ] && { mv -f "$outputFile" "$outputCache"; } >/dev
/null
2>/dev
/null
782 [ -s "$outputCache" ] && mv "$outputCache" "$outputFile" >/dev
/null
2>/dev
/null
786 [ -s "$outputCache" ]
790 [ -s "$outputGzip" ] && gzip -t -c "$outputGzip"
794 rm -f "$outputGzip" >/dev
/null
2>/dev
/null
795 R_TMP
="$(mktemp -u -q -t ${packageName}_tmp.XXXXXXXX)"
796 if gzip < "$outputFile" > "$R_TMP"; then
797 if mv "$R_TMP" "$outputGzip"; then
808 expand|unpack|unpack_gzip
)
809 [ -s "$outputGzip" ] && gzip -dc < "$outputGzip" > "$outputCache"
815 _process_file_url
() {
816 if [ "$2" != '0' ]; then
817 json add error
"errorConfigValidationFail"
818 output
"${_ERROR_}: $(get_text 'errorConfigValidationFail')!\\n"
819 output
"Please check if the '$packageConfigFile' contains correct values for config options.\\n"
821 if [ "$parallel_downloads" -gt 0 ]; then
822 process_file_url
"$1" &
824 process_file_url
"$1"
829 local cfg
="$1" new_size
830 local label
type D_TMP R_TMP filter
831 if [ -z "$cfg" ] ||
[ -n "${2}${3}" ]; then
836 [ "$enabled" = '1' ] ||
return 0
837 [ -n "$url" ] ||
return 1
843 allow
) type='Allowed'; D_TMP
="$A_TMP"
845 block
) type='Blocked'; D_TMP
="$B_TMP"
847 file) type='File'; D_TMP
="$B_TMP"
850 if [ "${1:0:5}" = "https" ] && [ -z "$isSSLSupported" ]; then
852 output
2 "[DL] $type $label $__FAIL__\\n"
853 echo "errorNoSSLSupport|${1}" >> "$sharedMemoryError"
856 while [ -z "$R_TMP" ] ||
[ -e "$R_TMP" ]; do
857 R_TMP
="$(mktemp -u -q -t ${packageName}_tmp.XXXXXXXX)"
859 if [ -z "$url" ] ||
! $dl_command "$url" "$dl_flag" "$R_TMP" 2>/dev
/null || \
860 [ ! -s "$R_TMP" ]; then
862 output
2 "[DL] $type $label $__FAIL__\\n"
863 echo "errorDownloadingList|${url}" >> "$sharedMemoryError"
865 [ -n "$cfg" ] && new_size
="$(get_local_filesize "$R_TMP")"
866 if [ -n "$new_size" ] && [ "$size" != "$new_size" ]; then
867 uci
set "${packageName}.${cfg}.size=$size"
869 format
="$(detect_file_type "$R_TMP")"
871 adblockplus
) filter
="$adBlockPlusFilter";;
872 dnsmasq
) filter
="$dnsmasqFileFilter";;
873 dnsmasq2
) filter
="$dnsmasq2FileFilter";;
874 dnsmasq3
) filter
="$dnsmasq3FileFilter";;
875 domains
) filter
="$domainsFilter";;
876 hosts
) filter
="$hostsFilter";;
879 output
2 "[DL] $type $label $__FAIL__\\n"
880 echo "errorDetectingFileType|${url}" >> "$sharedMemoryError"
885 if [ -n "$filter" ] && [ "$action" != 'file' ]; then
886 sed -i "$filter" "$R_TMP"
888 if [ ! -s "$R_TMP" ]; then
890 output
2 "[DL] $type $label ($format) $__FAIL__\\n"
891 echo "errorParsingList|${url}" >> "$sharedMemoryError"
893 cat "${R_TMP}" >> "$D_TMP"
895 output
2 "[DL] $type $label ($format) $__OK__\\n"
902 download_dnsmasq_file
() {
903 local hf allow_filter j
=0 R_TMP
905 json
set message
"$(get_text "statusDownloading
")..."
906 json
set status
"statusDownloading"
908 rm -f "$A_TMP" "$B_TMP" "$outputFile" "$outputCache" "$outputGzip"
909 if [ "$($awk '/^MemFree/ {print int($2/1000)}' "/proc
/meminfo
")" -lt 32 ]; then
910 output
3 'Low free memory, restarting resolver '
917 touch $A_TMP; touch $B_TMP;
918 output
1 'Downloading dnsmasq file '
919 rm -f "$sharedMemoryError"
920 process_file_url
'' "$dnsmasq_config_file_url" 'file'
921 if [ -s "$sharedMemoryError" ]; then
922 while IFS
= read -r line
; do
923 json add error
"$line"
924 done < "$sharedMemoryError"
925 rm -f "$sharedMemoryError"
927 output
2 'Moving dnsmasq file '
928 if mv "$B_TMP" "$outputFile"; then
929 output
2 "$__OK__\\n"
931 output
2 "$__FAIL__\\n"
932 json add error
"errorMovingDataFile"
938 local hf allow_filter j
=0 R_TMP
940 json
set message
"$(get_text "statusDownloading
")..."
941 json
set status
"statusDownloading"
943 rm -f "$A_TMP" "$B_TMP" "$outputFile" "$outputCache" "$outputGzip"
944 if [ "$($awk '/^MemFree/ {print int($2/1000)}' "/proc
/meminfo
")" -lt 32 ]; then
945 output
3 'Low free memory, restarting resolver '
952 touch $A_TMP; touch $B_TMP;
953 output
1 'Downloading lists '
954 rm -f "$sharedMemoryError"
955 config_load
"$packageName"
956 config_foreach load_validate_file_url_section
'file_url' _process_file_url
958 if [ -n "$(uci changes "$packageName")" ]; then
959 output
2 "Saving updated file size(s) "
960 uci commit
"$packageName" && output_okn || output_failn
964 if [ -s "$sharedMemoryError" ]; then
965 while IFS
= read -r line
; do
966 json add error
"$line"
967 done < "$sharedMemoryError"
968 rm -f "$sharedMemoryError"
971 if [ "$canary_domains_icloud" -ne 0 ]; then
972 canaryDomains
="${canaryDomains:+$canaryDomains }${canaryDomainsiCloud}"
974 if [ "$canary_domains_mozilla" -ne 0 ]; then
975 canaryDomains
="${canaryDomains:+$canaryDomains }${canaryDomainsMozilla}"
978 for hf
in $blocked_domain $canaryDomains; do echo "$hf" |
sed "$domainsFilter" >> $B_TMP; done
979 allowed_domain
="${allowed_domain}
981 for hf
in ${allowed_domain}; do hf
="$(echo "$hf" | sed 's/\./\\./g')"; allow_filter
="$allow_filter/(^|\.)${hf}$/d;"; done
983 [ ! -s "$B_TMP" ] && return 1
985 output
1 'Processing downloads '
986 output
2 'Sorting combined list '
987 json
set status
"statusProcessing"
988 json
set message
"$(get_text "statusProcessing
"): sorting combined list"
989 if [ "$allow_non_ascii" -gt 0 ]; then
990 if sort -u "$B_TMP" > "$A_TMP"; then
994 json add error
"errorSorting"
997 if sort -u "$B_TMP" |
grep -E -v '[^a-zA-Z0-9=/.-]' > "$A_TMP"; then
1001 json add error
"errorSorting"
1005 if [ "$dns" = 'dnsmasq.conf' ] || \
1006 [ "$dns" = 'dnsmasq.ipset' ] || \
1007 [ "$dns" = 'dnsmasq.nftset' ] || \
1008 [ "$dns" = 'dnsmasq.servers' ] || \
1009 [ "$dns" = 'unbound.adb_list' ]; then
1010 # TLD optimization written by Dirk Brenken (dev@brenken.org)
1011 output
2 'Optimizing combined list '
1012 json
set message
"$(get_text "statusProcessing
"): optimizing combined list"
1013 # sed -E 'G;:t;s/(.*)(\.)(.*)(\n)(.*)/\1\4\5\2\3/;tt;s/(.*)\n(\.)(.*)/\3\2\1/' is actually slower than command below
1014 if $awk -F "." '{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "$A_TMP" > "$B_TMP"; then
1015 if sort "$B_TMP" > "$A_TMP"; then
1016 if $awk '{if(NR=1){tld=$NF};while(getline){if($NF!~tld"\\."){print tld;tld=$NF}}print tld}' "$A_TMP" > "$B_TMP"; then
1017 if $awk -F "." '{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "$B_TMP" > "$A_TMP"; then
1018 if sort -u "$A_TMP" > "$B_TMP"; then
1022 json add error
"errorOptimization"
1023 mv "$A_TMP" "$B_TMP"
1027 json add error
"errorOptimization"
1031 json add error
"errorOptimization"
1032 mv "$A_TMP" "$B_TMP"
1036 json add error
"errorOptimization"
1040 json add error
"errorOptimization"
1041 mv "$A_TMP" "$B_TMP"
1044 mv "$A_TMP" "$B_TMP"
1047 if [ -n "$allow_filter" ]; then
1048 output
2 'Allowing domains '
1049 json
set message
"$(get_text "statusProcessing
"): allowing domains"
1050 if sed -i -E "$allow_filter" "$B_TMP"; then
1054 json add error
"errorAllowListProcessing"
1057 output
2 'Formatting merged file '
1058 json
set message
"$(get_text "statusProcessing
"): formatting merged file"
1059 if [ -z "$outputFilterIPv6" ]; then
1060 if sed "$outputFilter" "$B_TMP" > "$A_TMP"; then
1064 json add error
"errorDataFileFormatting"
1069 if sed "$outputFilter" "$B_TMP" > "$A_TMP" && \
1070 sed "$outputFilterIPv6" "$B_TMP" >> "$A_TMP"; then
1074 json add error
"errorDataFileFormatting"
1082 output
2 'Creating dnsmasq addnhosts file '
1083 json
set message
"$(get_text "statusProcessing
"): creating dnsmasq addnhosts file"
1086 output
2 'Creating dnsmasq config file '
1087 json
set message
"$(get_text "statusProcessing
"): creating dnsmasq config file"
1090 output
2 'Creating dnsmasq ipset file '
1091 json
set message
"$(get_text "statusProcessing
"): creating dnsmasq ipset file"
1094 output
2 'Creating dnsmasq nft set file '
1095 json
set message
"$(get_text "statusProcessing
"): creating dnsmasq nft set file"
1098 output
2 'Creating dnsmasq servers file '
1099 json
set message
"$(get_text "statusProcessing
"): creating dnsmasq servers file"
1102 output
2 'Creating Unbound adb_list file '
1103 json
set message
"$(get_text "statusProcessing
"): creating Unbound adb_list file"
1107 if mv "$A_TMP" "$outputFile"; then
1111 json add error
"errorMovingDataFile"
1113 if [ "$compressed_cache" -gt 0 ]; then
1114 output
2 'Creating compressed cache '
1115 json
set message
"$(get_text "statusProcessing
"): creating compressed cache"
1116 if cache
'create_gzip'; then
1120 json add error
"errorCreatingCompressedCache"
1125 output
2 'Removing temporary files '
1126 json
set message
"$(get_text "statusProcessing
"): removing temporary files"
1127 rm -f "/tmp/${packageName}_tmp.*" "$A_TMP" "$B_TMP" "$outputCache" || j
=1
1128 if [ $j -eq 0 ]; then
1132 json add error
"errorRemovingTempFiles"
1138 local c hf string
="$1"
1139 local validation_result
="$3"
1140 load_environment
"$validation_result" 'quiet' ||
return 1
1141 if [ ! -s "$outputFile" ]; then
1142 output
"No block-list ('$outputFile') found.\\n"
1144 elif [ -z "$string" ]; then
1145 output
"Usage: /etc/init.d/${packageName} allow 'domain' ...\\n"
1147 elif [ -n "$dnsmasq_config_file_url" ]; then
1148 output
"Allowing individual domains is not possible when using external dnsmasq config file.\\n"
1152 dnsmasq.addnhosts|dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset|dnsmasq.servers
)
1153 output
1 "Allowing domain(s) and restarting dnsmasq "
1154 output
2 "Allowing domain(s) \\n"
1155 for c
in $string; do
1157 hf
="$(echo "$c" | sed 's/\./\\./g')"
1158 if sed -i "/\(^\|\.\)${hf}$/d;" "$outputFile" && \
1159 uci_add_list_if_new
"${packageName}" 'config' 'allowed_domain' "$c"; then
1165 if [ "$compressed_cache" -gt 0 ]; then
1166 output
2 'Creating compressed cache '
1167 if cache
'create_gzip'; then
1173 output
2 "Committing changes to config "
1174 if [ -n "$(uci_changes "$packageName")" ] && uci_commit
"$packageName"; then
1175 allowed_domain
="$(uci_get "$packageName" 'config' 'allowed_domain')"
1177 json
set stats
"$serviceName is blocking $(wc -l < "$outputFile") domains (with ${dns})"
1179 if [ "$dns" = 'dnsmasq.ipset' ]; then
1180 output
2 "Flushing adb ipset "
1181 if ipset
-q -! flush adb
; then output_ok
; else output_fail
; fi
1183 if [ "$dns" = 'dnsmasq.nftset' ]; then
1184 output
2 "Flushing adb nft sets "
1185 nft flush
set inet fw4 adb6
1186 if nft flush
set inet fw4 adb4
; then output_ok
; else output_fail
; fi
1188 output
2 "Restarting dnsmasq "
1189 if dnsmasq_restart
; then output_okn
; else output_failn
; fi
1195 output
1 "Allowing domain(s) and restarting Unbound "
1196 output
2 "Allowing domain(s) \\n"
1197 for c
in $string; do
1199 if sed -i "/${string}/d" "$outputFile" && \
1200 uci_add_list_if_new
"$packageName" 'config' 'allowed_domain' "$string"; then
1206 if [ "$compressed_cache" -gt 0 ]; then
1207 output
2 'Creating compressed cache '
1208 if cache
'create_gzip'; then
1214 output
2 "Committing changes to config "
1215 if [ -n "$(uci_changes "$packageName")" ] && uci_commit
"$packageName"; then
1216 allowed_domain
="$(uci_get "$packageName" 'config' 'allowed_domain')"
1218 json
set stats
"$serviceName is blocking $(wc -l < "$outputFile") domains (with ${dns})"
1220 output
2 "Restarting Unbound "
1221 if unbound_restart
; then output_okn
; else output_failn
; fi
1231 local validation_result
="$3"
1232 load_environment
"$validation_result" 'quiet' ||
return 1
1233 if [ ! -s "$outputFile" ]; then
1234 output
"No block-list ('$outputFile') found.\\n"
1236 elif [ -z "$param" ]; then
1237 output
"Usage: /etc/init.d/${packageName} check 'domain' ...\\n"
1240 for string
in ${param}; do
1241 c
="$(grep -c "$string" "$outputFile")"
1242 if [ "$c" -gt 0 ]; then
1243 if [ "$c" -eq 1 ]; then
1244 output
"Found 1 match for '$string' in '$outputFile'.\\n"
1246 output
"Found $c matches for '$string' in '$outputFile'.\\n"
1248 if [ "$c" -le 20 ]; then
1251 grep "$string" "$outputFile" |
sed 's|^127.0.0.1 ||;s|^:: ||;';;
1253 grep "$string" "$outputFile" |
sed 's|local=/||;s|/$||;';;
1255 grep "$string" "$outputFile" |
sed 's|ipset=/||;s|/adb$||;';;
1257 grep "$string" "$outputFile" |
sed 's|nftset=/||;s|/4#inet#adb#adb4||;';;
1259 grep "$string" "$outputFile" |
sed 's|server=/||;s|/$||;';;
1261 grep "$string" "$outputFile" |
sed 's|^local-zone: "||;s|" static$||;';;
1265 output
"The '$string' is not found in current block-list ('$outputFile').\\n"
1270 adb_config_update
() {
1272 local param validation_result
="$3"
1274 on_boot
) param
="$1";;
1277 load_environment
"$validation_result" "$param" ||
return 1
1278 label
="${config_update_url##*//}"
1279 label
="${label%%/*}";
1280 [ "$config_update_enabled" -ne 0 ] ||
return 0
1282 if [ "$param" != 'download' ]; then
1283 cache
'test' && return 0
1284 cache
'test_gzip' && return 0
1286 output
1 'Updating config '
1287 while [ -z "$R_TMP" ] ||
[ -e "$R_TMP" ]; do
1288 R_TMP
="$(mktemp -u -q -t ${packageName}_tmp.XXXXXXXX)"
1290 if ! $dl_command "$config_update_url" "$dl_flag" "$R_TMP" 2>/dev
/null ||
[ ! -s "$R_TMP" ]; then
1291 output
1 "$_FAIL_\\n"
1292 output
2 "[DL] Config Update: $label $__FAIL__\\n"
1293 json add error
"errorDownloadingConfigUpdate"
1295 if [ -s "$R_TMP" ] && sed -f "$R_TMP" -i "$packageConfigFile" 2>/dev
/null
; then
1297 output
2 "[DL] Config Update: $label $__OK__\\n"
1299 output
1 "$_FAIL_\\n"
1300 output
2 "[DL] Config Update: $label $__FAIL__\\n"
1301 json add error
"errorParsingConfigUpdate"
1308 _config_add_url_size
() {
1309 local cfg
="$1" url size
1310 config_get url
"$cfg" url
1311 size
="$(get_url_filesize "$url")"
1312 output
"$url${size:+: $size} "
1313 if [ -n "$size" ]; then
1314 uci
set "${packageName}.${cfg}.size=$size"
1323 local validation_result
="$3"
1324 load_environment
"$validation_result" 'quiet' ||
return 1
1325 config_load
"$packageName"
1326 config_foreach _config_add_url_size
'file_url'
1327 uci commit
"$packageName"
1330 # shellcheck disable=SC2120
1332 local action status error message stats c
1333 local param
="$1" validation_result
="$3"
1335 load_environment
"$validation_result" "$param" ||
return 1
1337 status
="$(json get status)"
1338 error
="$(json get error)"
1339 message
="$(json get message)"
1340 stats
="$(json get stats)"
1341 action
="$(json get triggers)"
1343 if [ "$action" = 'on_boot' ] ||
[ "$param" = 'on_boot' ]; then
1344 if cache
'test_gzip' || cache
'test'; then
1349 elif [ "$action" = 'download' ] ||
[ "$param" = 'download' ] ||
[ -n "$error" ]; then
1351 elif [ ! -s "$outputFile" ]; then
1352 if cache
'test_gzip' || cache
'test'; then
1357 elif [ "$action" = 'restart' ] ||
[ "$param" = 'restart' ]; then
1359 elif [ -s "$outputFile" ] && [ "$status" = "statusSuccess" ] && [ -z "$error" ]; then
1369 if [ "$action" = 'restore' ]; then
1370 output
0 "Starting $serviceName... "
1371 output
3 "Starting $serviceName...\\n"
1372 json
set status
"statusStarting"
1373 if cache
'test_gzip' && ! cache
'test' && [ ! -s "$outputFile" ]; then
1374 output
3 'Found compressed cache file, unpacking it '
1375 json
set message
'found compressed cache file, unpacking it.'
1376 if cache
'unpack_gzip'; then
1380 json add error
"errorRestoreCompressedCache"
1381 output
"${_ERROR_}: $(get_text 'errorRestoreCompressedCache')!\\n"
1385 if cache
'test' && [ ! -s "$outputFile" ]; then
1386 output
3 'Found cache file, reusing it '
1387 json
set message
'found cache file, reusing it.'
1388 if cache
'restore'; then
1393 json add error
"errorRestoreCache"
1394 output
"${_ERROR_}: $(get_text 'errorRestoreCache')!\\n"
1399 if [ "$action" = 'download' ]; then
1400 if [ -z "$blocked_url" ] && [ -z "$blocked_domain" ]; then
1401 json
set status
"statusFail"
1402 json add error
"errorNothingToDo"
1403 output
"${_ERROR_}: $(get_text 'errorNothingToDo')!\\n"
1405 if [ -s "$outputFile" ] || cache
'test' || cache
'test_gzip'; then
1406 output
0 "Force-reloading $serviceName... "
1407 output
3 "Force-reloading $serviceName...\\n"
1408 json
set status
"statusForceReloading"
1410 output
0 "Starting $serviceName... "
1411 output
3 "Starting $serviceName...\\n"
1412 json
set status
"statusStarting"
1414 if [ "$dns" = 'dnsmasq.conf' ] && [ -n "$dnsmasq_config_file_url" ]; then
1415 download_dnsmasq_file
1422 if [ "$action" = 'restart' ]; then
1423 output
0 "Restarting $serviceName... "
1424 output
3 "Restarting $serviceName...\\n"
1425 json
set status
"statusRestarting"
1428 if [ "$action" = 'start' ]; then
1429 output
0 "Starting $serviceName... "
1430 output
3 "Starting $serviceName...\\n"
1431 json
set status
"statusStarting"
1434 if [ -s "$outputFile" ] && [ "$(json get status)" != "statusFail" ]; then
1435 output
0 "$__OK__\\n";
1437 json
set status
"statusSuccess"
1438 json
set stats
"$serviceName is blocking $(wc -l < "$outputFile") domains (with ${dns})"
1441 output
0 "$__FAIL__\\n";
1442 json
set status
"statusFail"
1443 json add error
"errorOhSnap"
1447 procd_open_instance
'main'
1448 procd_set_param
command /bin
/true
1449 procd_set_param stdout
1
1450 procd_set_param stderr
1
1452 json_add_string
'status' "$(json get status)"
1453 json_add_string
'errors' "$(json get error)"
1454 json_add_string
'warnings' "$(json get warning)"
1455 if [ -s "$outputFile" ]; then
1456 json_add_int
'entries' "$(wc -l < "$outputFile")"
1458 json_add_int
'entries' '0'
1460 json_add_array firewall
1461 if [ "$force_dns" -ne 0 ]; then
1462 for c
in ${force_dns_port/,/ }; do
1463 if netstat
-tuln |
grep LISTEN |
grep ":${c}" >/dev
/null
2>&1; then
1465 json_add_string
type redirect
1466 json_add_string target DNAT
1467 json_add_string src lan
1468 json_add_string proto
"tcp udp"
1469 json_add_string src_dport
"$c"
1470 json_add_string dest_port
"$c"
1471 json_add_string family any
1472 json_add_boolean reflection
0
1476 json_add_string
type rule
1477 json_add_string src lan
1478 json_add_string dest
"*"
1479 json_add_string proto
"tcp udp"
1480 json_add_string dest_port
"$c"
1481 json_add_string target REJECT
1489 json_add_string
type ipset
1490 json_add_string name adb
1491 json_add_string match dest_net
1492 json_add_string storage
hash
1495 json_add_string
type rule
1496 json_add_string ipset adb
1497 json_add_string src lan
1498 json_add_string dest
"*"
1499 json_add_string proto
"tcp udp"
1500 json_add_string target REJECT
1505 json_add_string
type ipset
1506 json_add_string name adb4
1507 json_add_string family
4
1508 json_add_string match dest_net
1511 json_add_string
type rule
1512 json_add_string ipset adb4
1513 json_add_string src lan
1514 json_add_string dest
"*"
1515 json_add_string proto
"tcp udp"
1516 json_add_string target REJECT
1518 if [ "$ipv6_enabled" -ne 0 ]; then
1520 json_add_string
type ipset
1521 json_add_string name adb6
1522 json_add_string family
6
1523 json_add_string match dest_net
1526 json_add_string
type rule
1527 json_add_string ipset adb6
1528 json_add_string src lan
1529 json_add_string dest
"*"
1530 json_add_string proto
"tcp udp"
1531 json_add_string target REJECT
1538 procd_close_instance
1542 local c url status message error stats
1543 local validation_result
="$3"
1544 load_environment
"$validation_result" 'quiet' ||
return 1
1545 status
="$(json get status)"
1546 message
="$(json get message)"
1547 error
="$(json get error)"
1548 stats
="$(json get stats)"
1549 if [ "$status" = "statusSuccess" ]; then
1550 output
"$stats "; output_okn
;
1552 [ -n "$status" ] && status
="$(get_text "$status")"
1553 if [ -n "$status" ] && [ -n "$message" ]; then
1554 status
="${status}: $message"
1556 [ -n "$status" ] && output
"$serviceName $status\\n"
1558 if [ -n "$error" ]; then
1563 errorDownloadingList|errorParsingList
)
1564 output
"${_ERROR_}: $(get_text "$c") $url!\\n";;
1566 output
"${_ERROR_}: $(get_text "$c")!\\n";;
1573 # shellcheck disable=SC2120
1575 local validation_result
="$3"
1576 load_environment
"$validation_result" 'quiet' ||
return 1
1577 if [ -s "$outputFile" ]; then
1578 output
"Stopping $serviceName... "
1580 if dns
'on_stop'; then
1581 ipset
-q -! flush adb
1582 ipset
-q -! destroy adb
1583 nft delete
set inet fw4 adb4
1584 nft delete
set inet fw4 adb6
1586 output
0 "$__OK__\\n"; output_okn
;
1587 json
set status
"statusStopped"
1590 output
0 "$__FAIL__\\n"; output_fail
;
1591 json
set status
"statusFail"
1592 json add error
"errorStopping"
1593 output
"${_ERROR_}: $(get_text 'errorStopping')!\\n"
1599 local timeout
="${1:-$pause_timeout}"
1600 local validation_result
="$3"
1601 adb_stop
'on_pause' '' "$validation_result"
1602 output
"Sleeping for $timeout seconds... "
1603 if sleep "$timeout"; then
1608 adb_start
'on_pause' '' "$validation_result"
1611 allow
() { load_validate_config
'config' adb_allow
"'$*'"; }
1613 ubus
-t 30 wait_for network.interface
2>/dev
/null
1614 rc_procd start_service
'on_boot'
1616 check
() { load_validate_config
'config' adb_check
"'$*'"; }
1617 dl
() { rc_procd start_service
'download'; }
1619 local compressed_cache_dir
1620 config_load
"$packageName"
1621 config_get compressed_cache_dir
'config' 'compressed_cache_dir' '/etc'
1622 if [ "$(sanitize_dir "$compressed_cache_dir")" = '/' ]; then
1623 compressed_cache_dir
=''
1624 elif [ -n "$(sanitize_dir "$compressed_cache_dir")" ]; then
1625 compressed_cache_dir
="$(sanitize_dir "$compressed_cache_dir")"
1627 compressed_cache_dir
="/etc"
1629 rm -f "$dnsmasqAddnhostsCache" "${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
1630 rm -f "$dnsmasqConfCache" "${compressed_cache_dir}/${dnsmasqConfGzip}"
1631 rm -f "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
1632 rm -f "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
1633 rm -f "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
1634 rm -f "$unboundCache" "$unboundGzip"
1636 config_foreach resolver_config
'dnsmasq' 'cleanup'
1640 reload_service
() { rc_procd start_service
'restart'; }
1641 restart_service
() { rc_procd start_service
'restart'; }
1642 service_started
() { procd_set_config_changed firewall
; }
1643 service_stopped
() { procd_set_config_changed firewall
; }
1644 service_triggers
() {
1646 local procd_trigger_wan6
1647 config_load
"$packageName"
1648 config_get_bool procd_trigger_wan6
'config' 'procd_trigger_wan6' '0'
1649 .
/lib
/functions
/network.sh
1651 network_find_wan wan
1653 if [ "$procd_trigger_wan6" -ne 0 ]; then
1654 network_find_wan6 wan6
1655 wan6
="${wan6:-wan6}"
1657 for i
in "$wan" "$wan6"; do
1658 [ -n "$i" ] && procd_add_interface_trigger
"interface.*" "$i" "/etc/init.d/${packageName}" start
1660 procd_add_config_trigger
"config.change" "$packageName" "/etc/init.d/${packageName}" reload
1662 sizes
() { load_validate_config
'config' adb_sizes
"''"; }
1664 load_validate_config
'config' adb_config_update
"'$*'"
1665 load_validate_config
'config' adb_start
"'$*'"
1667 status_service
() { load_validate_config
'config' adb_status
"''"; }
1668 stop_service
() { load_validate_config
'config' adb_stop
"'$*'"; }
1669 pause
() { load_validate_config
'config' adb_pause
"'$*'"; }
1670 version
() { echo "$PKG_VERSION"; }
1672 load_validate_file_url_section
() {
1673 uci_load_validate
"$packageName" "$packageName" "$1" "$2" \
1675 'action:or("allow", "block"):block' \
1676 'size:or(uinteger, "")' \
1680 load_validate_config
() {
1681 .
/lib
/functions
/network.sh
1682 .
/usr
/share
/libubox
/jshn.sh
1685 local force_dns_port
1686 local parallel_downloads
1688 local compressed_cache
1689 local compressed_cache_dir
1691 local allow_non_ascii
1692 local canary_domains_icloud
1693 local canary_domains_mozilla
1694 local config_update_enabled
1695 local config_update_url
1696 local download_timeout
1698 local curl_additional_param
1699 local curl_max_file_size
1702 local procd_trigger_wan6
1703 local procd_boot_wan_timeout
1706 local dnsmasq_instance
1707 local allowed_domain
1708 local blocked_domain
1709 local dnsmasq_config_file_url
1710 uci_load_validate
"$packageName" "$packageName" "$1" "${2}${3:+ $3}" \
1712 'force_dns:bool:1' \
1713 'force_dns_port:list(integer):53,853' \
1714 'parallel_downloads:bool:1' \
1716 'compressed_cache:bool:0' \
1717 'compressed_cache_dir:directory:/etc' \
1718 'ipv6_enabled:bool:0' \
1719 'allow_non_ascii:bool:0' \
1720 'canary_domains_icloud:bool:0' \
1721 'canary_domains_mozilla:bool:0' \
1722 'config_update_enabled:bool:0' \
1723 'config_update_url:string:https://cdn.jsdelivr.net/gh/openwrt/packages/net/adblock-fast/files/adblock-fast.conf.update' \
1724 'download_timeout:range(1,60):20' \
1725 'pause_timeout:range(10,120):60' \
1726 'curl_additional_param:or("", string)' \
1727 'curl_max_file_size:or("", uinteger)' \
1728 'curl_retry:range(0,30):3' \
1729 'verbosity:range(0,2):2' \
1730 'procd_trigger_wan6:bool:0' \
1731 'procd_boot_wan_timeout:integer:60' \
1732 'led:or("", "none", file, device, string)' \
1733 'dns:or("dnsmasq.addnhosts", "dnsmasq.conf", "dnsmasq.ipset", "dnsmasq.nftset", "dnsmasq.servers", "unbound.adb_list"):dnsmasq.servers' \
1734 'dnsmasq_instance:list(or(integer, string)):*' \
1735 'allowed_domain:list(string)' \
1736 'blocked_domain:list(string)' \
1737 'dnsmasq_config_file_url:string'