packages/net/simple-adblock/files/simple-adblock.init
Stan Grishin 6c45b40317 simple-adblock: update to 1.9.4-1
* update default config for new oisd.nl lists
* conf.update file to migrate oisd.nl lists to the new format
* introduce AdBlockPlus lists support (new oisd.nl format)
* longer wait for WAN up/gateway detection
* make load_environemnt only execute once to suppress duplicate
  warnings/errors

PS. While I was testing this, oisd.nl has brought back the old domains
    lists as well, so this version supports both as I'm unclear as to
    why the "big" ABPlus list is only 6.2Mb where as the "big" domains
    list is whopping 19.9Mb.

Signed-off-by: Stan Grishin <stangri@melmac.ca>
2023-02-16 23:10:22 +00:00

1619 lines
51 KiB
Bash

#!/bin/sh /etc/rc.common
# Copyright 2017-2022 Stan Grishin (stangri@melmac.ca)
# shellcheck disable=SC1091,SC2016,SC3043,SC3057,SC3060
# shellcheck disable=SC2034
START=94
# shellcheck disable=SC2034
USE_PROCD=1
LC_ALL=C
if type extra_command 1>/dev/null 2>&1; then
extra_command 'allow' 'Allows domain in current block-list and config'
extra_command 'check' 'Checks if specified domain is found in current block-list'
extra_command 'dl' 'Force-downloads all enabled block-list'
extra_command 'killcache' 'Delete all cached files'
extra_command 'sizes' 'Displays the file-sizes of enabled block-lists'
extra_command 'version' 'Show version information'
else
# shellcheck disable=SC2034
EXTRA_COMMANDS='allow check dl killcache sizes status_service version'
# shellcheck disable=SC2034
EXTRA_HELP=' allow Allows domain(s) in current block-list and config
check Checks if specified domain is found in current block-list
dl Force-downloads all enabled block-list
sizes Displays the file-sizes of enabled block-lists'
fi
readonly PKG_VERSION='dev-test'
readonly packageName='simple-adblock'
readonly serviceName="$packageName $PKG_VERSION"
readonly packageConfigFile="/etc/config/${packageName}"
readonly dnsmasqAddnhostsFile="/var/run/${packageName}/dnsmasq.addnhosts"
readonly dnsmasqAddnhostsCache="/var/run/${packageName}/dnsmasq.addnhosts.cache"
readonly dnsmasqAddnhostsGzip="/etc/${packageName}.dnsmasq.addnhosts.gz"
readonly dnsmasqAddnhostsFilter='s|^|127.0.0.1 |;s|$||'
readonly dnsmasqAddnhostsFilterIPv6='s|^|:: |;s|$||'
readonly dnsmasqConfFile="/tmp/dnsmasq.d/${packageName}"
readonly dnsmasqConfCache="/var/run/${packageName}/dnsmasq.conf.cache"
readonly dnsmasqConfGzip="/etc/${packageName}.dnsmasq.conf.gz"
readonly dnsmasqConfFilter='s|^|local=/|;s|$|/|'
readonly dnsmasqIpsetFile="/tmp/dnsmasq.d/${packageName}.ipset"
readonly dnsmasqIpsetCache="/var/run/${packageName}/dnsmasq.ipset.cache"
readonly dnsmasqIpsetGzip="/etc/${packageName}.dnsmasq.ipset.gz"
readonly dnsmasqIpsetFilter='s|^|ipset=/|;s|$|/adb|'
readonly dnsmasqNftsetFile="/tmp/dnsmasq.d/${packageName}.nftset"
readonly dnsmasqNftsetCache="/var/run/${packageName}/dnsmasq.nftset.cache"
readonly dnsmasqNftsetGzip="/etc/${packageName}.dnsmasq.nftset.gz"
readonly dnsmasqNftsetFilter='s|^|nftset=/|;s|$|/4#inet#fw4#adb4|'
readonly dnsmasqNftsetFilterIPv6='s|^|nftset=/|;s|$|/4#inet#fw4#adb4,6#inet#fw4#adb6|'
readonly dnsmasqServersFile="/var/run/${packageName}/dnsmasq.servers"
readonly dnsmasqServersCache="/var/run/${packageName}/dnsmasq.servers.cache"
readonly dnsmasqServersGzip="/etc/${packageName}.dnsmasq.servers.gz"
readonly dnsmasqServersFilter='s|^|server=/|;s|$|/|'
readonly unboundFile="/var/lib/unbound/adb_list.${packageName}"
readonly unboundCache="/var/run/${packageName}/unbound.cache"
readonly unboundGzip="/etc/${packageName}.unbound.gz"
readonly unboundFilter='s|^|local-zone: "|;s|$|" static|'
readonly A_TMP="/var/${packageName}.hosts.a.tmp"
readonly B_TMP="/var/${packageName}.hosts.b.tmp"
readonly jsonFile="/var/run/${packageName}/${packageName}.json"
readonly sharedMemoryError="/dev/shm/$packageName-error"
readonly sharedMemoryOutput="/dev/shm/$packageName-output"
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;'
readonly domainsFilter='/^#/d;s/[[:space:]]*#.*$//;s/[[:space:]]*$//;s/[[:cntrl:]]$//;/[[:space:]]/d;/[`~!@#\$%\^&\*()=+;:"'\'',<>?/\|[{}]/d;/]/d;/\./!d;/^$/d;/[^[:alnum:]_.-]/d;'
readonly adBlockPlusFilter='/^#/d;/^!/d;s/[[:space:]]*#.*$//;s/^||//;s/\^$//;s/[[:space:]]*$//;s/[[:cntrl:]]$//;/[[:space:]]/d;/[`~!@#\$%\^&\*()=+;:"'\'',<>?/\|[{}]/d;/]/d;/\./!d;/^$/d;/[^[:alnum:]_.-]/d;'
readonly dnsmasqFileFilter='\|^server=/[[:alnum:]_.-].*/|!d'
readonly _OK_='\033[0;32m\xe2\x9c\x93\033[0m'
readonly _FAIL_='\033[0;31m\xe2\x9c\x97\033[0m'
readonly __OK__='\033[0;32m[\xe2\x9c\x93]\033[0m'
readonly __FAIL__='\033[0;31m[\xe2\x9c\x97]\033[0m'
readonly _ERROR_='\033[0;31mERROR\033[0m'
readonly _WARNING_='\033[0;33mWARNING\033[0m'
# shellcheck disable=SC2155
readonly ipset="$(command -v ipset)"
# shellcheck disable=SC2155
readonly nft="$(command -v nft)"
readonly canaryDomainsMozilla='use-application-dns.net'
readonly canaryDomainsiCloud='mask.icloud.com mask-h2.icloud.com'
dl_command=
dl_flag=
isSSLSupported=
outputFilter=
outputFilterIPv6=
outputFile=
outputGzip=
outputCache=
awk='awk'
load_environment_flag=
. /lib/functions/network.sh
. /usr/share/libubox/jshn.sh
debug() { local i j; for i in "$@"; do eval "j=\$$i"; echo "${i}: ${j} "; done; }
uci_add_list_if_new() {
local PACKAGE="$1"
local CONFIG="$2"
local OPTION="$3"
local VALUE="$4"
local i
[ -n "$PACKAGE" ] && [ -n "$CONFIG" ] && [ -n "$OPTION" ] && [ -n "$VALUE" ] || return 1
for i in $(uci_get "$PACKAGE" "$CONFIG" "$OPTION"); do
[ "$i" = "$VALUE" ] && return 0
done
uci_add_list "$PACKAGE" "$CONFIG" "$OPTION" "$VALUE"
}
uci_changes() {
local PACKAGE="$1"
local CONFIG="$2"
local OPTION="$3"
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} changes "$PACKAGE${CONFIG:+.$CONFIG}${OPTION:+.$OPTION}"
}
ipset() { "$ipset" "$@" >/dev/null 2>&1; }
nft() { "$nft" "$@" >/dev/null 2>&1; }
get_text() {
local r
case "$1" in
errorConfigValidationFail) r="$packageName config validation failed";;
errorServiceDisabled) r="$packageName is currently disabled";;
errorNoDnsmasqIpset)
r="dnsmasq ipset support is enabled in $packageName, but dnsmasq is either not installed or installed dnsmasq does not support ipset";;
errorNoIpset)
r="dnsmasq ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:net' type";;
errorNoDnsmasqNftset)
r="dnsmasq nft set support is enabled in $packageName, but dnsmasq is either not installed or installed dnsmasq does not support nft set";;
errorNoNft) r="dnsmasq nft sets support is enabled in $packageName, but nft is not installed";;
errorNoWanGateway) r="The ${serviceName} failed to discover WAN gateway";;
errorOutputDirCreate) r="failed to create directory for %s file";;
errorOutputFileCreate) r="failed to create $outputFile file";;
errorFailDNSReload) r="failed to restart/reload DNS resolver";;
errorSharedMemory) r="failed to access shared memory";;
errorSorting) r="failed to sort data file";;
errorOptimization) r="failed to optimize data file";;
errorAllowListProcessing) r="failed to process allow-list";;
errorDataFileFormatting) r="failed to format data file";;
errorMovingDataFile) r="failed to move data file '${A_TMP}' to '${outputFile}'";;
errorCreatingCompressedCache) r="failed to create compressed cache";;
errorRemovingTempFiles) r="failed to remove temporary files";;
errorRestoreCompressedCache) r="failed to unpack compressed cache";;
errorRestoreCache) r="failed to move '$outputCache' to '$outputFile'";;
errorOhSnap) r="failed to create block-list or restart DNS resolver";;
errorStopping) r="failed to stop $serviceName";;
errorDNSReload) r="failed to reload/restart DNS resolver";;
errorDownloadingConfigUpdate) r="failed to download Config Update file";;
errorDownloadingList) r="failed to download";;
errorParsingConfigUpdate) r="failed to parse Config Update file";;
errorParsingList) r="failed to parse";;
errorNoSSLSupport) r="no HTTPS/SSL support on device";;
errorCreatingDirectory) r="failed to create output/cache/gzip file directory";;
statusNoInstall) r="$serviceName is not installed or not found";;
statusStopped) r="Stopped";;
statusStarting) r="Starting";;
statusRestarting) r="Restarting";;
statusForceReloading) r="Force Reloading";;
statusDownloading) r="Downloading";;
statusProcessing) r="Processing";;
statusError) r="Error";;
statusWarning) r="Warning";;
statusFail) r="Fail";;
statusSuccess) r="Success";;
warningExternalDnsmasqConfig)
r="use of external dnsmasq config file detected, please set 'dns' option to 'dnsmasq.conf'";;
warningMissingRecommendedPackages) r="Some recommended packages are missing";;
esac
echo "$r"
}
output_ok() { output 1 "$_OK_"; output 2 "$__OK__\\n"; }
output_okn() { output 1 "$_OK_\\n"; output 2 "$__OK__\\n"; }
output_fail() { output 1 "$_FAIL_"; output 2 "$__FAIL__\\n"; }
output_failn() { output 1 "$_FAIL_\\n"; output 2 "$__FAIL__\\n"; }
str_replace() { printf "%b" "$1" | sed -e "s/$(printf "%b" "$2")/$(printf "%b" "$3")/g"; }
str_contains() { test "$1" != "$(str_replace "$1" "$2" '')"; }
is_greater() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
is_greater_or_equal() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" = "$2"; }
is_chaos_calmer() { ubus -S call system board | grep -q 'Chaos Calmer'; }
led_on(){ if [ -n "${1}" ] && [ -e "${1}/trigger" ]; then echo 'default-on' > "${1}/trigger" 2>&1; fi; }
led_off(){ if [ -n "${1}" ] && [ -e "${1}/trigger" ]; then echo 'none' > "${1}/trigger" 2>&1; fi; }
dnsmasq_hup() { killall -q -s HUP dnsmasq; }
dnsmasq_kill() { killall -q -s KILL dnsmasq; }
dnsmasq_restart() { /etc/init.d/dnsmasq restart >/dev/null 2>&1; }
unbound_restart() { /etc/init.d/unbound restart >/dev/null 2>&1; }
is_present() { command -v "$1" >/dev/null 2>&1; }
output() {
# Can take a single parameter (text) to be output at any verbosity
# Or target verbosity level and text to be output at specifc verbosity
local msg memmsg logmsg
verbosity="${verbosity:-2}"
if [ $# -ne 1 ]; then
if [ $((verbosity & $1)) -gt 0 ] || [ "$verbosity" = "$1" ]; then shift; else return 0; fi
fi
[ -t 1 ] && printf "%b" "$1"
msg="${1//$serviceName /service }";
if [ "$(printf "%b" "$msg" | wc -l)" -gt 0 ]; then
[ -s "$sharedMemoryOutput" ] && memmsg="$(cat "$sharedMemoryOutput")"
logmsg="$(printf "%b" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')"
logger -t "${packageName:-service} [$$]" "$(printf "%b" "$logmsg")"
rm -f "$sharedMemoryOutput"
else
printf "%b" "$msg" >> "$sharedMemoryOutput"
fi
}
load_network() {
local param="$1"
local i j wan_if wan_gw wan_proto
local counter wan_if_timeout='20' wan_gw_timeout='5'
counter=0
while [ -z "$wan_if" ]; do
network_flush_cache
network_find_wan wan_if
if [ -n "$wan_if" ]; then
output "WAN Interface found: '${wan_if}'.\\n"
break
fi
if [ "$counter" -gt "$wan_if_timeout" ]; then
output "WAN Interface timeout, assuming 'wan'.\\n"
wan_if='wan'
break
fi
counter=$((counter+1))
output "Waiting to discover WAN Interface...\\n"
sleep 1
done
counter=0
wan_proto="$(uci -q get "network.${wan_if}.proto")"
if [ "$wan_proto" = 'pppoe' ]; then
wan_gw_timeout=$((wan_gw_timeout+10))
fi
while [ "$counter" -le "$wan_gw_timeout" ]; do
network_flush_cache
network_get_gateway wan_gw "$wan_if"
if [ -n "$wan_gw" ]; then
output "WAN Gateway found: '${wan_gw}.'\\n"
return 0
fi
counter=$((counter+1))
output "Waiting to discover $wan_if Gateway...\\n"
sleep 1
done
json add error "errorNoWanGateway"
output "${_ERROR_}: $(get_text 'errorNoWanGateway')!\\n"; return 1;
}
load_environment() {
local i j
local validation_result="$1" param="$2"
[ -z "$load_environment_flag" ] || return 0
if [ "$validation_result" != '0' ]; then
json add error "errorConfigValidationFail"
output "${_ERROR_}: $(get_text 'errorConfigValidationFail')!\\n"
output "Please check if the '$packageConfigFile' contains correct values for config options.\\n"
return 1
fi
if [ "$enabled" -eq 0 ]; then
json add error "errorServiceDisabled"
output "${_ERROR_}: $(get_text 'errorServiceDisabled')!\\n"
output "Run the following commands before starting service again:\\n"
output "uci set ${packageName}.config.enabled='1'; uci commit $packageName;\\n"
return 1
fi
if [ "$debug" -ne 0 ]; then
exec 1>>/tmp/simple-adblock.log
exec 2>&1
set -x
fi
if [ -n "$dnsmasq_config_file_url" ]; then
case "$dns" in
dnsmasq.conf) :;;
*)
if [ "$param" != 'quiet' ]; then
json add warning "warningExternalDnsmasqConfig"
output "${_WARNING_}: $(get_text 'warningExternalDnsmasqConfig')!\\n"
fi
;;
esac
fi
case "$dns" in
dnsmasq.addnhosts|dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset|dnsmasq.servers)
if dnsmasq -v 2>/dev/null | grep -q 'no-IDN' || ! dnsmasq -v 2>/dev/null | grep -q -w 'IDN'; then
allow_non_ascii=0
fi
;;
unbound.adb_list)
allow_non_ascii=1;;
esac
case "$dns" in
dnsmasq.ipset)
if dnsmasq -v 2>/dev/null | grep -q 'no-ipset' || ! dnsmasq -v 2>/dev/null | grep -q -w 'ipset'; then
if [ "$param" != 'quiet' ]; then
json add error "errorNoDnsmasqIpset"
output "${_ERROR_}: $(get_text 'errorNoDnsmasqIpset')!\\n"
fi
dns='dnsmasq.servers'
fi
if ! ipset help hash:net; then
if [ "$param" != 'quiet' ]; then
json add error "errorNoIpset"
output "${_ERROR_}: $(get_text 'errorNoIpset')!\\n"
fi
dns='dnsmasq.servers'
fi
;;
dnsmasq.nftset)
if dnsmasq -v 2>/dev/null | grep -q 'no-nftset' || ! dnsmasq -v 2>/dev/null | grep -q -w 'nftset'; then
if [ "$param" != 'quiet' ]; then
json add error "errorNoDnsmasqNftset"
output "${_ERROR_}: $(get_text 'errorNoDnsmasqNftset')!\\n"
fi
dns='dnsmasq.servers'
fi
if [ -z "$nft" ]; then
if [ "$param" != 'quiet' ]; then
json add error "errorNoNft"
output "${_ERROR_}: $(get_text 'errorNoNft')!\\n"
fi
dns='dnsmasq.servers'
fi
;;
esac
case "$dns" in
dnsmasq.addnhosts)
outputFilter="$dnsmasqAddnhostsFilter"
outputFile="$dnsmasqAddnhostsFile"
outputCache="$dnsmasqAddnhostsCache"
outputGzip="$dnsmasqAddnhostsGzip"
if [ "$ipv6_enabled" -ne 0 ]; then
outputFilterIPv6="$dnsmasqAddnhostsFilterIPv6"
fi
rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "$dnsmasqConfGzip"
rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "$dnsmasqIpsetGzip"
rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "$dnsmasqNftsetGzip"
rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "$dnsmasqServersGzip"
rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
;;
dnsmasq.conf)
outputFilter="$dnsmasqConfFilter"
outputFile="$dnsmasqConfFile"
outputCache="$dnsmasqConfCache"
outputGzip="$dnsmasqConfGzip"
rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "$dnsmasqAddnhostsGzip"
rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "$dnsmasqIpsetGzip"
rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "$dnsmasqNftsetGzip"
rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "$dnsmasqServersGzip"
rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
;;
dnsmasq.ipset)
outputFilter="$dnsmasqIpsetFilter"
outputFile="$dnsmasqIpsetFile"
outputCache="$dnsmasqIpsetCache"
outputGzip="$dnsmasqIpsetGzip"
rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "$dnsmasqAddnhostsGzip"
rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "$dnsmasqConfGzip"
rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "$dnsmasqNftsetGzip"
rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "$dnsmasqServersGzip"
rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
;;
dnsmasq.nftset)
if [ "$ipv6_enabled" -ne 0 ]; then
outputFilter="$dnsmasqNftsetFilterIPv6"
else
outputFilter="$dnsmasqNftsetFilter"
fi
outputFile="$dnsmasqNftsetFile"
outputCache="$dnsmasqNftsetCache"
outputGzip="$dnsmasqNftsetGzip"
rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "$dnsmasqAddnhostsGzip"
rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "$dnsmasqConfGzip"
rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "$dnsmasqIpsetGzip"
rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "$dnsmasqServersGzip"
rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
;;
dnsmasq.servers)
outputFilter="$dnsmasqServersFilter"
outputFile="$dnsmasqServersFile"
outputCache="$dnsmasqServersCache"
outputGzip="$dnsmasqServersGzip"
rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "$dnsmasqAddnhostsGzip"
rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "$dnsmasqConfGzip"
rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "$dnsmasqIpsetGzip"
rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "$dnsmasqNftsetGzip"
rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
;;
unbound.adb_list)
outputFilter="$unboundFilter"
outputFile="$unboundFile"
outputCache="$unboundCache"
outputGzip="$unboundGzip"
rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "$dnsmasqAddnhostsGzip"
rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "$dnsmasqConfGzip"
rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "$dnsmasqIpsetGzip"
rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "$dnsmasqNftsetGzip"
rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "$dnsmasqServersGzip"
;;
esac
for i in "$outputFile" "$outputCache" "$outputGzip"; do
if ! mkdir -p "$(dirname "$i")"; then
if [ "$param" != 'quiet' ]; then
json add error "errorOutputDirCreate" "$i"
output "${_ERROR_}: $(get_text 'errorOutputDirCreate' "$i")!\\n"
fi
fi
done
is_present 'gawk' && awk='gawk'
if ! is_present '/usr/libexec/grep-gnu' || ! is_present '/usr/libexec/sed-gnu' || \
! is_present '/usr/libexec/sort-coreutils' || ! is_present 'gawk'; then
local s="opkg update; opkg --force-overwrite install"
is_present 'gawk' || s="$s gawk"
is_present '/usr/libexec/grep-gnu' || s="$s grep"
is_present '/usr/libexec/sed-gnu' || s="$s sed"
is_present '/usr/libexec/sort-coreutils' || s="$s coreutils-sort"
if [ "$param" != 'quiet' ]; then
json add warning "warningMissingRecommendedPackages" "${i}"
output "${_WARNING_}: $(get_text 'warningMissingRecommendedPackages'), install them by running:\\n"
output "$s;\\n"
fi
fi
# Prefer curl because it supports the file:// scheme.
if is_present 'curl'; then
dl_command="curl --silent --insecure"
dl_command="${dl_command}${curl_max_file_size:+ --max-filesize $curl_max_file_size}"
dl_command="${dl_command}${curl_retry:+ --retry $curl_retry}"
dl_command="${dl_command}${download_timeout:+ --connect-timeout $download_timeout}"
dl_flag="-o"
elif is_present '/usr/libexec/wget-ssl'; then
dl_command="/usr/libexec/wget-ssl --no-check-certificate -q"
dl_command="${dl_command}${download_timeout:+ --timeout $download_timeout}"
dl_flag="-O"
elif is_present wget && wget --version 2>/dev/null | grep -q "+https"; then
dl_command="wget --no-check-certificate -q"
dl_command="${dl_command}${download_timeout:+ --timeout $download_timeout}"
dl_flag="-O"
else
dl_command="uclient-fetch --no-check-certificate -q"
dl_command="${dl_command}${download_timeout:+ --timeout $download_timeout}"
dl_flag="-O"
fi
led="${led:+/sys/class/leds/$led}"
if curl --version 2>/dev/null | grep -q "https" \
|| wget --version 2>/dev/null | grep -q "+https" \
|| grep -q "libustream-mbedtls" /usr/lib/opkg/status \
|| grep -q "libustream-openssl" /usr/lib/opkg/status \
|| grep -q "libustream-wolfssl" /usr/lib/opkg/status; then
isSSLSupported=1
else
unset isSSLSupported
fi
load_environment_flag=1
cache 'test' && return 0
cache 'test_gzip' && return 0
if [ "$param" = 'on_boot' ]; then
load_network "$param"
return "$?"
else
return 0
fi
}
resolver() {
local cfg="$1" param="$2"
case "$param" in
dnsmasq.addnhosts)
if [ "$(uci_get 'dhcp' "$cfg" 'serversfile')" = "$dnsmasqServersFile" ]; then
uci_remove 'dhcp' "$cfg" 'serversfile'
fi
uci_add_list_if_new 'dhcp' "$cfg" 'addnhosts' "$dnsmasqAddnhostsFile"
;;
cleanup|dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset|unbound.adb_list)
uci_remove_list 'dhcp' "$cfg" 'addnhosts' "$dnsmasqAddnhostsFile"
if [ "$(uci_get 'dhcp' "$cfg" 'serversfile')" = "$dnsmasqServersFile" ]; then
uci_remove 'dhcp' "$cfg" 'serversfile'
fi
;;
dnsmasq.servers)
uci_remove_list 'dhcp' "$cfg" 'addnhosts' "$dnsmasqAddnhostsFile"
if [ "$(uci_get 'dhcp' "$cfg" 'serversfile')" != "$dnsmasqServersFile" ]; then
uci_set 'dhcp' "$cfg" 'serversfile' "$dnsmasqServersFile"
fi
;;
esac
}
dns() {
local param output_text i
case $1 in
on_start)
if [ ! -s "$outputFile" ]; then
json set status "statusFail"
json add error "errorOutputFileCreate"
output "${_ERROR_}: $(get_text 'errorOutputFileCreate')!\\n"
return 1
fi
config_load 'dhcp'
if [ "$dns_instance" = "*" ]; then
config_foreach resolver 'dnsmasq' "$dns"
elif [ -n "$dns_instance" ]; then
for i in $dns_instance; do
resolver "@dnsmasq[$i]" "$dns" || resolver "$i" "$dns"
done
fi
case "$dns" in
dnsmasq.addnhosts|dnsmasq.servers)
param=dnsmasq_restart
output_text='Reloading dnsmasq'
;;
dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset)
param=dnsmasq_restart
output_text='Restarting dnsmasq'
;;
unbound.adb_list)
param=unbound_restart
output_text='Restarting Unbound'
;;
esac
if [ -n "$(uci_changes dhcp)" ]; then
uci_commit dhcp
if [ "$param" = 'unbound_restart' ]; then
param='dnsmasq_restart; unbound_restart;'
output_text='Restarting Unbound/dnsmasq'
else
param=dnsmasq_restart
output_text='Restarting dnsmasq'
fi
fi
output 1 "$output_text "
output 2 "$output_text "
json set message "$output_text"
if eval "$param"; then
json set status "statusSuccess"
led_on "$led"
output_okn
else
output_fail
json set status "statusFail"
json add error "errorDNSReload"
output "${_ERROR_}: $(get_text 'errorDNSReload')!\\n"
return 1
fi
;;
on_stop)
case "$dns" in
dnsmasq.addnhosts|dnsmasq.servers)
param=dnsmasq_restart
;;
dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset)
param=dnsmasq_restart
;;
unbound.adb_list)
param=unbound_restart
;;
esac
if [ -n "$(uci_changes dhcp)" ]; then
uci_commit dhcp
if [ "$param" = 'unbound_restart' ]; then
param='dnsmasq_restart; unbound_restart;'
else
param=dnsmasq_restart
fi
fi
eval "$param"
return $?
;;
quiet)
case "$dns" in
dnsmasq.addnhosts|dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset|dnsmasq.servers)
param=dnsmasq_restart
;;
unbound.adb_list)
param=unbound_restart
;;
esac
eval "$param"
return $?
;;
esac
}
json() {
# shellcheck disable=SC2034
local action="$1" param="$2" value="$3"
shift 3
# shellcheck disable=SC2124
local extras="$@" line
local status message error stats
local reload restart curReload curRestart ret i
if [ -s "$jsonFile" ]; then
json_load_file "$jsonFile" 2>/dev/null
json_select 'data' 2>/dev/null
for i in status message error stats reload restart; do
json_get_var $i "$i" 2>/dev/null
done
fi
case "$action" in
get)
case "$param" in
triggers)
curReload="$parallel_downloads $debug $download_timeout $allowed_domain $blocked_domain $allowed_domains_url \
$blocked_adblockplus_url $blocked_domains_url $blocked_hosts_url $dns $config_update_enabled $config_update_url \
$dnsmasq_config_file_url $curl_max_file_size $curl_retry"
curRestart="$compressed_cache $force_dns $led $force_dns_port"
if [ ! -s "$jsonFile" ]; then
ret='on_boot'
elif [ "$curReload" != "$reload" ]; then
ret='download'
elif [ "$curRestart" != "$restart" ]; then
ret='restart'
fi
printf "%b" "$ret"
return;;
*)
printf "%b" "$(eval echo "\$$param")"; return;;
esac
;;
add)
line="$(eval echo "\$$param")"
eval "$param"='${line:+$line }${value}${extras:+|$extras}'
;;
del)
case "$param" in
all)
unset status message error stats;;
triggers)
unset reload restart;;
*)
unset "$param";;
esac
;;
set)
case "$param" in
triggers)
reload="$parallel_downloads $debug $download_timeout $allowed_domain $blocked_domain $allowed_domains_url \
$blocked_adblockplus_url $blocked_domains_url $blocked_hosts_url $dns $config_update_enabled $config_update_url \
$dnsmasq_config_file_url $curl_max_file_size $curl_retry"
restart="$compressed_cache $force_dns $led $force_dns_port"
;;
*)
eval "$param"='${value}${extras:+|$extras}';;
esac
;;
esac
json_init
json_add_object 'data'
json_add_string version "$PKG_VERSION"
json_add_string status "$status"
json_add_string message "$message"
json_add_string error "$error"
json_add_string stats "$stats"
json_add_string reload "$reload"
json_add_string restart "$restart"
json_close_object
json_dump > "$jsonFile"
sync
}
cache() {
local R_TMP
case "$1" in
create|backup)
[ -s "$outputFile" ] && { mv -f "$outputFile" "$outputCache"; true > "$outputFile"; } >/dev/null 2>/dev/null
return $?
;;
restore|use)
[ -s "$outputCache" ] && mv "$outputCache" "$outputFile" >/dev/null 2>/dev/null
return $?
;;
test)
[ -s "$outputCache" ]
return $?
;;
test_gzip)
[ -s "$outputGzip" ] && gzip -t -c "$outputGzip"
return $?
;;
create_gzip)
rm -f "$outputGzip" >/dev/null 2>/dev/null
R_TMP="$(mktemp -u -q -t ${packageName}_tmp.XXXXXXXX)"
if gzip < "$outputFile" > "$R_TMP"; then
if mv "$R_TMP" "$outputGzip"; then
rm -f "$R_TMP"
return 0
else
rm -f "$R_TMP"
return 1
fi
else
return 1
fi
;;
expand|unpack|unpack_gzip)
[ -s "$outputGzip" ] && gzip -dc < "$outputGzip" > "$outputCache"
return $?
;;
esac
}
process_url() {
local label type D_TMP R_TMP
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then return 1; fi
label="${1##*//}"; label="${label%%/*}";
case "$2" in
adbp) label="ADBPlus: $label"; filter="$adBlockPlusFilter"
;;
dnsmasq) label="Dnsmasq: $label"; filter="$dnsmasqFileFilter"
;;
domains) label="Domains: $label"; filter="$domainsFilter"
;;
hosts) label="Hosts: $label"; filter="$hostsFilter"
;;
esac
case "$3" in
allowed) type='Allowed'; D_TMP="$A_TMP"
;;
blocked) type='Blocked'; D_TMP="$B_TMP"
;;
file) type='File'; D_TMP="$B_TMP"
;;
esac
if [ "${1:0:5}" = "https" ] && [ -z "$isSSLSupported" ]; then
output 1 "$_FAIL_"
output 2 "[DL] $type $label $__FAIL__\\n"
echo "errorNoSSLSupport|${1}" >> "$sharedMemoryError"
return 0
fi
while [ -z "$R_TMP" ] || [ -e "$R_TMP" ]; do
R_TMP="$(mktemp -u -q -t ${packageName}_tmp.XXXXXXXX)"
done
if ! $dl_command "$1" "$dl_flag" "$R_TMP" 2>/dev/null || [ ! -s "$R_TMP" ]; then
output 1 "$_FAIL_"
output 2 "[DL] $type $label $__FAIL__\\n"
echo "errorDownloadingList|${1}" >> "$sharedMemoryError"
else
sed -i "$filter" "$R_TMP"
if [ ! -s "$R_TMP" ]; then
output 1 "$_FAIL_"
output 2 "[DL] $type $label $__FAIL__\\n"
echo "errorParsingList|${1}" >> "$sharedMemoryError"
else
cat "${R_TMP}" >> "$D_TMP"
output 1 "$_OK_"
output 2 "[DL] $type $label $__OK__\\n"
fi
fi
rm -f "$R_TMP"
return 0
}
download_dnsmasq_file() {
local hf allow_filter j=0 R_TMP
json set message "$(get_text "statusDownloading")..."
json set status "statusDownloading"
rm -f "$A_TMP" "$B_TMP" "$outputFile" "$outputCache" "$outputGzip"
if [ "$($awk '/^MemFree/ {print int($2/1000)}' "/proc/meminfo")" -lt 32 ]; then
output 3 'Low free memory, restarting resolver '
if dns 'quiet'; then
output_okn
else
output_failn
fi
fi
touch $A_TMP; touch $B_TMP;
output 1 'Downloading dnsmasq file '
rm -f "$sharedMemoryError"
process_url "$dnsmasq_config_file_url" 'dnsmasq' 'file'
# output 1 '\n'
if [ -s "$sharedMemoryError" ]; then
while IFS= read -r line; do
json add error "$line"
done < "$sharedMemoryError"
rm -f "$sharedMemoryError"
fi
output 2 'Creating dnsmasq file '
if mv "$B_TMP" "$outputFile"; then
output 2 "$__OK__\\n"
else
output 2 "$__FAIL__\\n"
json add error "errorMovingDataFile"
fi
output 1 '\n'
}
download_lists() {
local hf allow_filter j=0 R_TMP
json set message "$(get_text "statusDownloading")..."
json set status "statusDownloading"
rm -f "$A_TMP" "$B_TMP" "$outputFile" "$outputCache" "$outputGzip"
if [ "$($awk '/^MemFree/ {print int($2/1000)}' "/proc/meminfo")" -lt 32 ]; then
output 3 'Low free memory, restarting resolver '
if dns 'quiet'; then
output_okn
else
output_failn
fi
fi
touch $A_TMP; touch $B_TMP;
output 1 'Downloading lists '
rm -f "$sharedMemoryError"
for hf in ${blocked_hosts_url}; do
if [ "$parallel_downloads" -gt 0 ]; then
process_url "$hf" 'hosts' 'blocked' &
else
process_url "$hf" 'hosts' 'blocked'
fi
done
for hf in ${blocked_adblockplus_url}; do
if [ "$parallel_downloads" -gt 0 ]; then
process_url "$hf" 'adbp' 'blocked' &
else
process_url "$hf" 'adbp' 'blocked'
fi
done
for hf in ${blocked_domains_url}; do
if [ "$parallel_downloads" -gt 0 ]; then
process_url "$hf" 'domains' 'blocked' &
else
process_url "$hf" 'domains' 'blocked'
fi
done
for hf in ${allowed_domains_url}; do
if [ "$parallel_downloads" -gt 0 ]; then
process_url "$hf" 'domains' 'allowed' &
else
process_url "$hf" 'domains' 'allowed'
fi
done
wait
output 1 '\n'
if [ -s "$sharedMemoryError" ]; then
while IFS= read -r line; do
json add error "$line"
done < "$sharedMemoryError"
rm -f "$sharedMemoryError"
fi
if [ "$canary_domains_icloud" -ne 0 ]; then
canaryDomains="${canaryDomains:+$canaryDomains }${canaryDomainsiCloud}"
fi
if [ "$canary_domains_mozilla" -ne 0 ]; then
canaryDomains="${canaryDomains:+$canaryDomains }${canaryDomainsMozilla}"
fi
for hf in $blocked_domain $canaryDomains; do echo "$hf" | sed "$domainsFilter" >> $B_TMP; done
allowed_domain="${allowed_domain}
$(cat $A_TMP)"
for hf in ${allowed_domain}; do hf="$(echo "$hf" | sed 's/\./\\./g')"; allow_filter="$allow_filter/(^|\.)${hf}$/d;"; done
[ ! -s "$B_TMP" ] && return 1
output 1 'Processing downloads '
output 2 'Sorting combined list '
json set status "statusProcessing"
json set message "$(get_text "statusProcessing"): sorting combined list"
if [ "$allow_non_ascii" -gt 0 ]; then
if sort -u "$B_TMP" > "$A_TMP"; then
output_ok
else
output_failn
json add error "errorSorting"
fi
else
if sort -u "$B_TMP" | grep -E -v '[^a-zA-Z0-9=/.-]' > "$A_TMP"; then
output_ok
else
output_failn
json add error "errorSorting"
fi
fi
if [ "$dns" = 'dnsmasq.conf' ] || \
[ "$dns" = 'dnsmasq.ipset' ] || \
[ "$dns" = 'dnsmasq.nftset' ] || \
[ "$dns" = 'dnsmasq.servers' ] || \
[ "$dns" = 'unbound.adb_list' ]; then
# TLD optimization written by Dirk Brenken (dev@brenken.org)
output 2 'Optimizing combined list '
json set message "$(get_text "statusProcessing"): optimizing combined list"
# sed -E 'G;:t;s/(.*)(\.)(.*)(\n)(.*)/\1\4\5\2\3/;tt;s/(.*)\n(\.)(.*)/\3\2\1/' is actually slower than command below
if $awk -F "." '{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "$A_TMP" > "$B_TMP"; then
if sort "$B_TMP" > "$A_TMP"; then
if $awk '{if(NR=1){tld=$NF};while(getline){if($NF!~tld"\\."){print tld;tld=$NF}}print tld}' "$A_TMP" > "$B_TMP"; then
if $awk -F "." '{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "$B_TMP" > "$A_TMP"; then
if sort -u "$A_TMP" > "$B_TMP"; then
output_ok
else
output_failn
json add error "errorOptimization"
mv "$A_TMP" "$B_TMP"
fi
else
output_failn
json add error "errorOptimization"
fi
else
output_failn
json add error "errorOptimization"
mv "$A_TMP" "$B_TMP"
fi
else
output_failn
json add error "errorOptimization"
fi
else
output_failn
json add error "errorOptimization"
mv "$A_TMP" "$B_TMP"
fi
else
mv "$A_TMP" "$B_TMP"
fi
output 2 'Allowing domains '
json set message "$(get_text "statusProcessing"): allowing domains"
if sed -i -E "$allow_filter" "$B_TMP"; then
output_ok
else
output_failn
json add error "errorAllowListProcessing"
fi
output 2 'Formatting merged file '
json set message "$(get_text "statusProcessing"): formatting merged file"
if [ -z "$outputFilterIPv6" ]; then
if sed "$outputFilter" "$B_TMP" > "$A_TMP"; then
output_ok
else
output_failn
json add error "errorDataFileFormatting"
fi
else
case "$dns" in
dnsmasq.addnhosts)
if sed "$outputFilter" "$B_TMP" > "$A_TMP" && \
sed "$outputFilterIPv6" "$B_TMP" >> "$A_TMP"; then
output_ok
else
output_failn
json add error "errorDataFileFormatting"
fi
;;
esac
fi
case "$dns" in
dnsmasq.addnhosts)
output 2 'Creating dnsmasq addnhosts file '
json set message "$(get_text "statusProcessing"): creating dnsmasq addnhosts file"
;;
dnsmasq.conf)
output 2 'Creating dnsmasq config file '
json set message "$(get_text "statusProcessing"): creating dnsmasq config file"
;;
dnsmasq.ipset)
output 2 'Creating dnsmasq ipset file '
json set message "$(get_text "statusProcessing"): creating dnsmasq ipset file"
;;
dnsmasq.nftset)
output 2 'Creating dnsmasq nft set file '
json set message "$(get_text "statusProcessing"): creating dnsmasq nft set file"
;;
dnsmasq.servers)
output 2 'Creating dnsmasq servers file '
json set message "$(get_text "statusProcessing"): creating dnsmasq servers file"
;;
unbound.adb_list)
output 2 'Creating Unbound adb_list file '
json set message "$(get_text "statusProcessing"): creating Unbound adb_list file"
;;
esac
if mv "$A_TMP" "$outputFile"; then
output_ok
else
output_failn
json add error "errorMovingDataFile"
fi
if [ "$compressed_cache" -gt 0 ]; then
output 2 'Creating compressed cache '
json set message "$(get_text "statusProcessing"): creating compressed cache"
if cache 'create_gzip'; then
output_ok
else
output_failn
json add error "errorCreatingCompressedCache"
fi
else
rm -f "$outputGzip"
fi
output 2 'Removing temporary files '
json set message "$(get_text "statusProcessing"): removing temporary files"
rm -f "/tmp/${packageName}_tmp.*" "$A_TMP" "$B_TMP" "$outputCache" || j=1
if [ $j -eq 0 ]; then
output_ok
else
output_failn
json add error "errorRemovingTempFiles"
fi
output 1 '\n'
}
adb_allow() {
local c hf string="$1"
local validation_result="$3"
load_environment "$validation_result" 'quiet' || return 1
if [ ! -s "$outputFile" ]; then
output "No block-list ('$outputFile') found.\\n"
return 0
elif [ -z "$string" ]; then
output "Usage: /etc/init.d/${packageName} allow 'domain' ...\\n"
return 0
elif [ -n "$dnsmasq_config_file_url" ]; then
output "Allowing individual domains is not possible when using external dnsmasq config file.\\n"
return 0
fi
case "$dns" in
dnsmasq.addnhosts|dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset|dnsmasq.servers)
output 1 "Allowing domain(s) and restarting dnsmasq "
output 2 "Allowing domain(s) \\n"
for c in $string; do
output 2 " $c "
hf="$(echo "$c" | sed 's/\./\\./g')"
if sed -i "/(^|\.)${hf}$/d;" "$outputFile" && \
uci_add_list_if_new "${packageName}" 'config' 'allowed_domain' "$c"; then
output_ok
else
output_fail
fi
done
if [ "$compressed_cache" -gt 0 ]; then
output 2 'Creating compressed cache '
if cache 'create_gzip'; then
output_ok
else
output_failn
fi
fi
output 2 "Committing changes to config "
if [ -n "$(uci_changes "$packageName")" ] && uci_commit "$packageName"; then
allowed_domain="$(uci_get "$packageName" 'config' 'allowed_domain')"
json set triggers
json set stats "$serviceName is blocking $(wc -l < "$outputFile") domains (with ${dns})"
output_ok;
if [ "$dns" = 'dnsmasq.ipset' ]; then
output 2 "Flushing adb ipset "
if ipset -q -! flush adb; then output_ok; else output_fail; fi
fi
if [ "$dns" = 'dnsmasq.nftset' ]; then
output 2 "Flushing adb nft sets "
nft flush set inet fw4 adb6
if nft flush set inet fw4 adb4; then output_ok; else output_fail; fi
fi
output 2 "Restarting dnsmasq "
if dnsmasq_restart; then output_okn; else output_failn; fi
else
output_fail;
fi
;;
unbound.adb_list)
output 1 "Allowing domain(s) and restarting Unbound "
output 2 "Allowing domain(s) \\n"
for c in $string; do
output 2 " $c "
if sed -i "/${string}/d" "$outputFile" && \
uci_add_list_if_new "$packageName" 'config' 'allowed_domain' "$string"; then
output_ok
else
output_fail
fi
done
if [ "$compressed_cache" -gt 0 ]; then
output 2 'Creating compressed cache '
if cache 'create_gzip'; then
output_ok
else
output_failn
fi
fi
output 2 "Committing changes to config "
if [ -n "$(uci_changes "$packageName")" ] && uci_commit "$packageName"; then
allowed_domain="$(uci_get "$packageName" 'config' 'allowed_domain')"
json set triggers
json set stats "$serviceName is blocking $(wc -l < "$outputFile") domains (with ${dns})"
output_ok;
output 2 "Restarting Unbound "
if unbound_restart; then output_okn; else output_failn; fi
else
output_fail;
fi
;;
esac
}
adb_check() {
local c param="$1"
local validation_result="$3"
load_environment "$validation_result" 'quiet' || return 1
if [ ! -s "$outputFile" ]; then
output "No block-list ('$outputFile') found.\\n"
return 0
elif [ -z "$param" ]; then
output "Usage: /etc/init.d/${packageName} check 'domain' ...\\n"
return 0
fi
for string in ${param}; do
c="$(grep -c "$string" "$outputFile")"
if [ "$c" -gt 0 ]; then
if [ "$c" -eq 1 ]; then
output "Found 1 match for '$string' in '$outputFile'.\\n"
else
output "Found $c matches for '$string' in '$outputFile'.\\n"
fi
if [ "$c" -le 20 ]; then
case "$dns" in
dnsmasq.addnhosts)
grep "$string" "$outputFile" | sed 's|^127.0.0.1 ||;s|^:: ||;';;
dnsmasq.conf)
grep "$string" "$outputFile" | sed 's|local=/||;s|/$||;';;
dnsmasq.ipset)
grep "$string" "$outputFile" | sed 's|ipset=/||;s|/adb$||;';;
dnsmasq.nftset)
grep "$string" "$outputFile" | sed 's|nftset=/||;s|/4#inet#adb#adb4||;';;
dnsmasq.servers)
grep "$string" "$outputFile" | sed 's|server=/||;s|/$||;';;
unbound.adb_list)
grep "$string" "$outputFile" | sed 's|^local-zone: "||;s|" static$||;';;
esac
fi
else
output "The '$string' is not found in current block-list ('$outputFile').\\n"
fi
done
}
adb_config_update() {
local R_TMP label
local param validation_result="$3"
case "$1" in
on_boot) param="$1";;
*) param='quiet';;
esac
load_environment "$validation_result" "$param" || return 1
label="${config_update_url##*//}"
label="${label%%/*}";
[ "$config_update_enabled" -ne 0 ] || return 0
if [ "$param" != 'download' ]; then
cache 'test' && return 0
cache 'test_gzip' && return 0
fi
output 1 'Updating config '
while [ -z "$R_TMP" ] || [ -e "$R_TMP" ]; do
R_TMP="$(mktemp -u -q -t ${packageName}_tmp.XXXXXXXX)"
done
if ! $dl_command "$config_update_url" "$dl_flag" "$R_TMP" 2>/dev/null || [ ! -s "$R_TMP" ]; then
output 1 "$_FAIL_\\n"
output 2 "[DL] Config Update: $label $__FAIL__\\n"
json add error "errorDownloadingConfigUpdate"
else
if [ -s "$R_TMP" ] && sed -f "$R_TMP" -i "$packageConfigFile" 2>/dev/null; then
output 1 "$_OK_\\n"
output 2 "[DL] Config Update: $label $__OK__\\n"
else
output 1 "$_FAIL_\\n"
output 2 "[DL] Config Update: $label $__FAIL__\\n"
json add error "errorParsingConfigUpdate"
fi
fi
rm -f "$R_TMP"
return 0
}
adb_sizes() {
local i
local validation_result="$3"
load_environment "$validation_result" 'quiet' || return 1
echo "# $(date)"
for i in ${blocked_adblockplus_url}; do
[ "${i//melmac}" != "$i" ] && continue
if $dl_command "$i" "$dl_flag" /tmp/sast 2>/dev/null && [ -s /tmp/sast ]; then
echo "# File size: $(du -sh /tmp/sast | $awk '{print $1}')"
if is_greater "$(du -sk /tmp/sast)" "500"; then
echo "# block-list too big for most routers"
elif is_greater "$(du -sk /tmp/sast)" "100"; then
echo "# block-list may be too big for some routers"
fi
rm -rf /tmp/sast
echo " list blocked_adblockplus_url '$i'"
echo ""
else
echo "# site was down on last check"
echo "# list blocked_adblockplus_url '$i'"
echo ""
fi
done
for i in ${blocked_domains_url}; do
[ "${i//melmac}" != "$i" ] && continue
if $dl_command "$i" "$dl_flag" /tmp/sast 2>/dev/null && [ -s /tmp/sast ]; then
echo "# File size: $(du -sh /tmp/sast | $awk '{print $1}')"
if is_greater "$(du -sk /tmp/sast)" "500"; then
echo "# block-list too big for most routers"
elif is_greater "$(du -sk /tmp/sast)" "100"; then
echo "# block-list may be too big for some routers"
fi
rm -rf /tmp/sast
echo " list blocked_domains_url '$i'"
echo ""
else
echo "# site was down on last check"
echo "# list blocked_domains_url '$i'"
echo ""
fi
done
for i in ${blocked_hosts_url}; do
if $dl_command "$i" "$dl_flag" /tmp/sast 2>/dev/null && [ -s /tmp/sast ]; then
echo "# File size: $(du -sh /tmp/sast | $awk '{print $1}')"
if is_greater "$(du -sk /tmp/sast)" "500"; then
echo "# block-list too big for most routers"
elif is_greater "$(du -sk /tmp/sast)" "100"; then
echo "# block-list may be too big for some routers"
fi
rm -rf /tmp/sast
echo " list blocked_hosts_url '$i'"
echo ""
else
echo "# site was down on last check"
echo "# list blocked_hosts_url '$i'"
echo ""
fi
done
}
adb_start() {
local action status error message stats c
local param="$1" validation_result="$3"
load_environment "$validation_result" "$param" || return 1
status="$(json get status)"
error="$(json get error)"
message="$(json get message)"
stats="$(json get stats)"
action="$(json get triggers)"
if [ "$action" = 'on_boot' ] || [ "$1" = 'on_boot' ]; then
if cache 'test_gzip' || cache 'test'; then
action='restore'
else
action='download'
fi
elif [ "$action" = 'download' ] || [ "$1" = 'download' ] || [ -n "$error" ]; then
action='download'
elif [ ! -s "$outputFile" ]; then
if cache 'test_gzip' || cache 'test'; then
action='restore'
else
action='download'
fi
elif [ "$action" = 'restart' ] || [ "$1" = 'restart' ]; then
action='restart'
elif [ -s "$outputFile" ] && [ "$status" = "statusSuccess" ] && [ -z "$error" ]; then
status_service
return 0
else
action='download'
fi
json del all
json set triggers
if [ "$action" = 'restore' ]; then
output 0 "Starting $serviceName... "
output 3 "Starting $serviceName...\\n"
json set status "statusStarting"
if cache 'test_gzip' && ! cache 'test' && [ ! -s "$outputFile" ]; then
output 3 'Found compressed cache file, unpacking it '
json set message 'found compressed cache file, unpacking it.'
if cache 'unpack_gzip'; then
output_okn
else
output_failn
json add error "errorRestoreCompressedCache"
output "${_ERROR_}: $(get_text 'errorRestoreCompressedCache')!\\n"
action='download'
fi
fi
if cache 'test' && [ ! -s "$outputFile" ]; then
output 3 'Found cache file, reusing it '
json set message 'found cache file, reusing it.'
if cache 'restore'; then
output_okn
dns 'on_start'
else
output_failn
json add error "errorRestoreCache"
output "${_ERROR_}: $(get_text 'errorRestoreCache')!\\n"
action='download'
fi
fi
fi
if [ "$action" = 'download' ]; then
if [ -s "$outputFile" ] || cache 'test' || cache 'test_gzip'; then
output 0 "Force-reloading $serviceName... "
output 3 "Force-reloading $serviceName...\\n"
json set status "statusForceReloading"
else
output 0 "Starting $serviceName... "
output 3 "Starting $serviceName...\\n"
json set status "statusStarting"
fi
if [ -n "$dnsmasq_config_file_url" ]; then
download_dnsmasq_file
else
download_lists
fi
dns 'on_start'
fi
if [ "$action" = 'restart' ]; then
output 0 "Restarting $serviceName... "
output 3 "Restarting $serviceName...\\n"
json set status "statusRestarting"
dns 'on_start'
fi
if [ "$action" = 'start' ]; then
output 0 "Starting $serviceName... "
output 3 "Starting $serviceName...\\n"
json set status "statusStarting"
dns 'on_start'
fi
if [ -s "$outputFile" ] && [ "$(json get status)" != "statusFail" ]; then
output 0 "$__OK__\\n";
json del message
json set status "statusSuccess"
json set stats "$serviceName is blocking $(wc -l < "$outputFile") domains (with ${dns})"
status_service
else
output 0 "$__FAIL__\\n";
json set status "statusFail"
json add error "errorOhSnap"
status_service
fi
procd_open_instance 'main'
procd_set_param command /bin/true
procd_set_param stdout 1
procd_set_param stderr 1
procd_open_data
json_add_string 'status' "$(json get status)"
json_add_string 'errors' "$(json get errors)"
if [ -s "$outputFile" ]; then
json_add_int 'entries' "$(wc -l < "$outputFile")"
else
json_add_int 'entries' '0'
fi
json_add_array firewall
if [ "$force_dns" -ne 0 ]; then
for c in $force_dns_port; do
if netstat -tuln | grep LISTEN | grep ":${c}" >/dev/null 2>&1; then
json_add_object ""
json_add_string type redirect
json_add_string target DNAT
json_add_string src lan
json_add_string proto "tcp udp"
json_add_string src_dport "$c"
json_add_string dest_port "$c"
json_add_boolean reflection 0
json_close_object
else
json_add_object ""
json_add_string type rule
json_add_string src lan
json_add_string dest "*"
json_add_string proto "tcp udp"
json_add_string dest_port "$c"
json_add_string target REJECT
json_close_object
fi
done
fi
case "$dns" in
dnsmasq.ipset)
json_add_object ""
json_add_string type ipset
json_add_string name adb
json_add_string match dest_net
json_add_string storage hash
json_close_object
json_add_object ""
json_add_string type rule
json_add_string ipset adb
json_add_string src lan
json_add_string dest "*"
json_add_string proto "tcp udp"
json_add_string target REJECT
json_close_object
;;
dnsmasq.nftset)
json_add_object ""
json_add_string type ipset
json_add_string name adb4
json_add_string family 4
json_add_string match dest_net
json_close_object
json_add_object ""
json_add_string type rule
json_add_string ipset adb4
json_add_string src lan
json_add_string dest "*"
json_add_string proto "tcp udp"
json_add_string target REJECT
json_close_object
if [ "$ipv6_enabled" -ne 0 ]; then
json_add_object ""
json_add_string type ipset
json_add_string name adb6
json_add_string family 6
json_add_string match dest_net
json_close_object
json_add_object ""
json_add_string type rule
json_add_string ipset adb6
json_add_string src lan
json_add_string dest "*"
json_add_string proto "tcp udp"
json_add_string target REJECT
json_close_object
fi
;;
esac
json_close_array
procd_close_data
procd_close_instance
}
adb_status() {
local c url status message error stats
local validation_result="$3"
load_environment "$validation_result" 'quiet' || return 1
status="$(json get status)"
message="$(json get message)"
error="$(json get error)"
stats="$(json get stats)"
if [ "$status" = "statusSuccess" ]; then
output "$stats "; output_okn;
else
[ -n "$status" ] && status="$(get_text "$status")"
if [ -n "$status" ] && [ -n "$message" ]; then
status="${status}: $message"
fi
[ -n "$status" ] && output "$serviceName $status\\n"
fi
if [ -n "$error" ]; then
for c in $error; do
url="${c##*|}"
c="${c%|*}"
case "$c" in
errorDownloadingList|errorParsingList)
output "${_ERROR_}: $(get_text "$c") $url!\\n";;
*)
output "${_ERROR_}: $(get_text "$c")!\\n";;
esac
n=$((n+1))
done
fi
}
adb_stop() {
local validation_result="$3"
load_environment "$validation_result" 'quiet' || return 1
if [ -s "$outputFile" ]; then
output "Stopping $serviceName... "
cache 'create'
if dns 'on_stop'; then
ipset -q -! flush adb
ipset -q -! destroy adb
nft delete set inet fw4 adb4
nft delete set inet fw4 adb6
led_off "$led"
output 0 "$__OK__\\n"; output_okn;
json set status "statusStopped"
json del message
else
output 0 "$__FAIL__\\n"; output_fail;
json set status "statusFail"
json add error "errorStopping"
output "${_ERROR_}: $(get_text 'errorStopping')!\\n"
fi
fi
}
allow() { load_validate_config 'config' adb_allow "'$*'"; }
boot() {
ubus -t 30 wait_for network.interface 2>/dev/null
rc_procd start_service 'on_boot'
}
check() { load_validate_config 'config' adb_check "'$*'"; }
dl() { rc_procd start_service 'download'; }
killcache() {
rm -f "$dnsmasqAddnhostsCache" "$dnsmasqAddnhostsGzip"
rm -f "$dnsmasqConfCache" "$dnsmasqConfGzip"
rm -f "$dnsmasqIpsetCache" "$dnsmasqIpsetGzip"
rm -f "$dnsmasqNftsetCache" "$dnsmasqNftsetGzip"
rm -f "$dnsmasqServersCache" "$dnsmasqServersGzip"
rm -f "$unboundCache" "$unboundGzip"
config_load 'dhcp'
config_foreach resolver 'dnsmasq' 'cleanup'
uci_commit 'dhcp'
return 0
}
reload_service() { rc_procd start_service 'restart'; }
restart_service() { rc_procd start_service 'restart'; }
service_started() { procd_set_config_changed firewall; }
service_stopped() { procd_set_config_changed firewall; }
service_triggers() {
local wan wan6 i
local procd_trigger_wan6
config_load "$packageName"
config_get_bool procd_trigger_wan6 'config' 'procd_trigger_wan6' '0'
. /lib/functions/network.sh
network_flush_cache
network_find_wan wan
wan="${wan:-wan}"
if [ "$procd_trigger_wan6" -ne 0 ]; then
network_find_wan6 wan6
wan6="${wan6:-wan6}"
fi
for i in "$wan" "$wan6"; do
[ -n "$i" ] && procd_add_interface_trigger "interface.*" "$i" "/etc/init.d/${packageName}" start
done
procd_add_config_trigger "config.change" "$packageName" "/etc/init.d/${packageName}" reload
}
sizes() { load_validate_config 'config' adb_sizes "''"; }
start_service() {
load_validate_config 'config' adb_config_update "'$*'"
load_validate_config 'config' adb_start "'$*'"
}
status_service() { load_validate_config 'config' adb_status "''"; }
stop_service() { load_validate_config 'config' adb_stop "'$*'"; }
version() { echo "$PKG_VERSION"; }
load_validate_config() {
local enabled
local force_dns
local force_dns_port
local parallel_downloads
local debug
local compressed_cache
local ipv6_enabled
local allow_non_ascii
local canary_domains_icloud
local canary_domains_mozilla
local config_update_enabled
local config_update_url
local boot_delay
local download_timeout
local curl_max_file_size
local curl_retry
local verbosity
local led
local dns
local dns_instance
local allowed_domain
local allowed_domains_url
local blocked_adblockplus_url
local blocked_domain
local blocked_domains_url
local blocked_hosts_url
local dnsmasq_config_file_url
uci_load_validate "$packageName" "$packageName" "$1" "${2}${3:+ $3}" \
'enabled:bool:0' \
'force_dns:bool:1' \
'force_dns_port:list(integer):53 853' \
'parallel_downloads:bool:1' \
'debug:bool:0' \
'compressed_cache:bool:0' \
'ipv6_enabled:bool:0' \
'allow_non_ascii:bool:0' \
'canary_domains_icloud:bool:0' \
'canary_domains_mozilla:bool:0' \
'config_update_enabled:bool:0' \
'config_update_url:string:https://cdn.jsdelivr.net/gh/openwrt/packages/net/simple-adblock/files/simple-adblock.conf.update' \
'download_timeout:range(1,60):20' \
'curl_max_file_size:uinteger' \
'curl_retry:range(0,30):3' \
'verbosity:range(0,2):2' \
'procd_trigger_wan6:bool:0' \
'led:or("", "none", file, device, string)' \
'dns:or("dnsmasq.addnhosts", "dnsmasq.conf", "dnsmasq.ipset", "dnsmasq.nftset", "dnsmasq.servers", "unbound.adb_list"):dnsmasq.servers' \
'dns_instance:or(list(integer, string)):0' \
'allowed_domain:list(string)' \
'allowed_domains_url:list(string)' \
'blocked_domain:list(string)' \
'blocked_adblockplus_url:list(string)' \
'blocked_domains_url:list(string)' \
'blocked_hosts_url:list(string)' \
'dnsmasq_config_file_url:string'
}