adblock: update 3.5.5
authorDirk Brenken <dev@brenken.org>
Sat, 1 Sep 2018 06:35:35 +0000 (08:35 +0200)
committerDirk Brenken <dev@brenken.org>
Tue, 4 Sep 2018 19:41:09 +0000 (21:41 +0200)
* accept only ascii aka punycode chars in blocklists to prevent possible
dns backend warnings
* fix cornercase issues in json parsing (backend & frontend)
* slightly optimize tld compression performance
* refine logging
* use uci wrapper where possible
* change indentation from spaces to tabs (saves 8kb)
* add experimental youtube blocklist source

Signed-off-by: Dirk Brenken <dev@brenken.org>
(cherry picked from commit 4987f066f9c7face7a35804ef53798786ff8155f)

net/adblock/Makefile
net/adblock/files/README.md
net/adblock/files/adblock.conf
net/adblock/files/adblock.init
net/adblock/files/adblock.notify
net/adblock/files/adblock.sh

index 4b199597ea8062a22eacbd5701f604dd2dfedaf1..ba4d7acc583498f7268a360d407612e8b5ab82c4 100644 (file)
@@ -6,8 +6,8 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=adblock
-PKG_VERSION:=3.5.4
-PKG_RELEASE:=2
+PKG_VERSION:=3.5.5
+PKG_RELEASE:=1
 PKG_LICENSE:=GPL-3.0+
 PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org>
 
index 8e146ee5b762992c91b15452c6f0ceb0a495a903..a9350651d42109da2b7c448674658ecdd67d1199 100644 (file)
@@ -61,6 +61,8 @@ A lot of people already use adblocker plugins within their desktop browsers, but
     * => infrequent updates, approx. 15.000 entries
     * [winspy](https://github.com/crazy-max/WindowsSpyBlocker)
     * => infrequent updates, approx. 120 entries
+    * [youtube]https://api.hackertarget.com/hostsearch/?q=googlevideo.com
+    * => dynamic request API to filter "random" youtube ad domains (experimental!), approx. 150 entries
     * [yoyo](http://pgl.yoyo.org/adservers)
     * => weekly updates, approx. 2.500 entries (enabled by default)
     * [zeus tracker](https://zeustracker.abuse.ch)
@@ -96,7 +98,7 @@ A lot of people already use adblocker plugins within their desktop browsers, but
 * optional: add new adblock sources on your own, see example below
 
 ## Prerequisites
-* [OpenWrt](https://openwrt.org), tested with the stable release series (17.01.x) and with the latest OpenWrt snapshot
+* [OpenWrt](https://openwrt.org), tested with the stable release series (18.06) and with the latest snapshot
 * a usual setup with an enabled dns backend at minimum - dump AP modes without a working dns backend are _not_ supported
 * a download utility:
     * to support all blocklist sources a full version (with ssl support) of 'wget', 'uclient-fetch' with one of the 'libustream-*' ssl libraries, 'aria2c' or 'curl' is required
@@ -109,7 +111,7 @@ A lot of people already use adblocker plugins within their desktop browsers, but
 * control the adblock service manually with _/etc/init.d/adblock_ start/stop/restart/reload/suspend/resume/status or use the LuCI frontend
 
 ## LuCI adblock companion package
-* for easy management of the various blocklist sources and all other adblock options you should use the provided LuCI frontend
+* for easy management of the various blocklist sources and adblock runtime options you should use the provided LuCI frontend
 * install 'luci-app-adblock' (_opkg install luci-app-adblock_)
 * the application is located in LuCI under 'Services' menu
 
@@ -143,7 +145,7 @@ A lot of people already use adblocker plugins within their desktop browsers, but
     * adb\_forcedns => force dns requests to local resolver (bool/default: '0', disabled)
     * adb\_forcesrt => force overall sort on low memory devices with less than 64 MB RAM (bool/default: '0', disabled)
     * adb\_backup_mode => do not automatically update blocklists during startup, use backups instead (bool/default: '0', disabled)
-    * adb\maxqueue => size of the download queue to handle downloads & list processing in parallel (int/default: '4')
+    * adb\_maxqueue => size of the download queue to handle downloads & list processing in parallel (int/default: '4')
     * adb\_jail => builds an additional 'Jail' list (/tmp/adb_list.jail) to block access to all domains except those listed in the whitelist file (bool/default: '0', disabled)
     * adb\_dnsflush => flush DNS cache after adblock processing, i.e. enable the old restart behavior (bool/default: '0', disabled)
     * adb\_notify => send notification emails in case of a processing error or if the overall domain count is &le; 0 (bool/default: '0', disabled)
@@ -216,12 +218,12 @@ Finally make this file executable via 'chmod' and test it directly. If no more e
 /etc/init.d/adblock status
 ::: adblock runtime information
   + adblock_status  : enabled
-  + adblock_version : 3.5.0
-  + overall_domains : 102324 (normal mode)
-  + fetch_utility   : /usr/bin/wget (built-in)
-  + dns_backend     : kresd (/etc/kresd)
-  + last_rundate    : 30.01.2018 21:24:11
-  + system_release  : Turris Omnia, OpenWrt omnia 15.05/3.9.4
+  + adblock_version : 3.5.5
+  + overall_domains : 97199 (backup mode)
+  + fetch_utility   : /bin/uclient-fetch (libustream-ssl)
+  + dns_backend     : unbound (/var/lib/unbound)
+  + last_rundate    : 01.09.2018 07:09:16
+  + system_release  : PC Engines APU, OpenWrt SNAPSHOT r7986-dc9388ac55
 </code></pre>
   
 **cronjob for a regular block list update (/etc/crontabs/root):**
index a10d158a91b80acb291a949d038fd1fed857a296..c68b82cb6f235734776992059aded3dc753f289d 100644 (file)
@@ -16,127 +16,127 @@ config adblock 'extra'
 
 config source 'adaway'
        option adb_src 'https://adaway.org/hosts.txt'
-       option adb_src_rset '/^127\.0\.0\.1[[:space:]]+([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
+       option adb_src_rset '/^127\.0\.0\.1[[:space:]]+([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
        option adb_src_desc 'focus on mobile ads, infrequent updates, approx. 400 entries'
        option enabled '1'
 
 config source 'adguard'
        option adb_src 'https://filters.adtidy.org/windows/filters/15.txt'
-       option adb_src_rset 'BEGIN{FS=\"[/|^|\r]\"}/^\|\|([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([\/\^\r]|$)/{print tolower(\$3)}'
+       option adb_src_rset 'BEGIN{FS=\"[/|^|\r]\"}/^\|\|([[:alnum:]_-]+\.)+[[:alpha:]]+([\/\^\r]|$)/{print tolower(\$3)}'
        option adb_src_desc 'combined adguard dns filter list, frequent updates, approx. 17.000 entries'
        option enabled '0'
 
 config source 'bitcoin'
        option adb_src 'https://raw.githubusercontent.com/hoshsadiq/adblock-nocoin-list/master/hosts.txt'
-       option adb_src_rset '/^0\.0\.0\.0[[:space:]]+([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
+       option adb_src_rset '/^0\.0\.0\.0[[:space:]]+([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
        option adb_src_desc 'focus on malicious bitcoin mining sites, infrequent updates, approx. 80 entries'
        option enabled '0'
 
 config source 'blacklist'
        option adb_src '/etc/adblock/adblock.blacklist'
-       option adb_src_rset '/^([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
+       option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
        option adb_src_desc 'static local domain blacklist, always deny these domains'
        option enabled '1'
 
 config source 'disconnect'
        option adb_src 'https://s3.amazonaws.com/lists.disconnect.me/simple_malvertising.txt'
-       option adb_src_rset '/^([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
+       option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
        option adb_src_desc 'mozilla driven blocklist, numerous updates on the same day, approx. 4.700 entries'
        option enabled '1'
 
 config source 'dshield'
        option adb_src 'https://www.dshield.org/feeds/suspiciousdomains_Low.txt'
-       option adb_src_rset '/^([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
+       option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
        option adb_src_desc 'generic blocklist, daily updates, approx. 3.500 entries'
        option enabled '0'
 
 config source 'feodo'
        option adb_src 'https://feodotracker.abuse.ch/blocklist/?download=domainblocklist'
-       option adb_src_rset '/^([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
+       option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
        option adb_src_desc 'focus on feodo botnet, daily updates, approx. 0-10 entries'
        option enabled '0'
 
 config source 'hphosts'
        option adb_src 'https://hosts-file.net/ad_servers.txt'
-       option adb_src_rset '/^127\.0\.0\.1[[:space:]]+([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|\$)+/{print tolower(\$2)}'
+       option adb_src_rset '/^127\.0\.0\.1[[:space:]]+([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|\$)+/{print tolower(\$2)}'
        option adb_src_desc 'broad blocklist, monthly updates, approx. 19.200 entries'
        option enabled '0'
 
 config source 'malware'
        option adb_src 'https://mirror.espoch.edu.ec/malwaredomains/justdomains'
-       option adb_src_rset '/^([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
+       option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
        option adb_src_desc 'broad blocklist, daily updates, approx. 18.300 entries'
        option enabled '0'
 
 config source 'malwarelist'
        option adb_src 'http://www.malwaredomainlist.com/hostslist/hosts.txt'
-       option adb_src_rset '/^127\.0\.0\.1[[:space:]]+([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
+       option adb_src_rset '/^127\.0\.0\.1[[:space:]]+([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
        option adb_src_desc 'focus on malware, daily updates, approx. 1.200 entries'
        option enabled '0'
 
 config source 'openphish'
        option adb_src 'https://openphish.com/feed.txt'
-       option adb_src_rset 'BEGIN{FS=\"/\"}/^http[s]?:\/\/([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+(\/|$)/{print tolower(\$3)}'
+       option adb_src_rset 'BEGIN{FS=\"/\"}/^http[s]?:\/\/([[:alnum:]_-]+\.)+[[:alpha:]]+(\/|$)/{print tolower(\$3)}'
        option adb_src_desc 'focus on phishing, numerous updates on the same day, approx. 2.400 entries'
        option enabled '0'
 
 config source 'ransomware'
        option adb_src 'https://ransomwaretracker.abuse.ch/downloads/RW_DOMBL.txt'
-       option adb_src_rset '/^([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
+       option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
        option adb_src_desc 'focus on ransomware by abuse.ch, numerous updates on the same day, approx. 1900 entries'
        option enabled '0'
 
 config source 'reg_cn'
        option adb_src 'https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt'
-       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
+       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([[:alnum:]_-]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
        option adb_src_desc 'focus on chinese ads plus generic easylist additions, daily updates, approx. 11.700 entries'
        option enabled '0'
 
 config source 'reg_cz'
        option adb_src 'https://raw.githubusercontent.com/qxstyles/turris-hole-czech-block-list/master/turris-hole-czech-block-list'
-       option adb_src_rset '/^([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
+       option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
        option adb_src_desc 'focus on czech ads maintained by Turris Omnia Users, infrequent updates, approx. 100 entries'
        option enabled '0'
 
 config source 'reg_de'
        option adb_src 'https://easylist-downloads.adblockplus.org/easylistgermany+easylist.txt'
-       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
+       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([[:alnum:]_-]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
        option adb_src_desc 'focus on german ads plus generic easylist additions, daily updates, approx. 9.200 entries'
        option enabled '0'
 
 config source 'reg_id'
        option adb_src 'https://easylist-downloads.adblockplus.org/abpindo+easylist.txt'
-       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
+       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([[:alnum:]_-]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
        option adb_src_desc 'focus on indonesian ads plus generic easylist additions, weekly updates, approx. 9.600 entries'
        option enabled '0'
 
 config source 'reg_nl'
        option adb_src 'https://easylist-downloads.adblockplus.org/easylistdutch+easylist.txt'
-       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
+       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([[:alnum:]_-]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
        option adb_src_desc 'focus on dutch ads plus generic easylist additions, weekly updates, approx. 9.400 entries'
        option enabled '0'
 
 config source 'reg_pl'
        option adb_src 'http://adblocklist.org/adblock-pxf-polish.txt'
-       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
+       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([[:alnum:]_-]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
        option adb_src_desc 'focus on polish ads, daily updates, approx. 90 entries'
        option enabled '0'
 
 config source 'reg_ro'
        option adb_src 'https://easylist-downloads.adblockplus.org/rolist+easylist.txt'
-       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
+       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([[:alnum:]_-]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
        option adb_src_desc 'focus on romanian ads plus generic easylist additions, weekly updates, approx. 9.400 entries'
        option enabled '0'
 
 config source 'reg_ru'
        option adb_src 'https://easylist-downloads.adblockplus.org/ruadlist+easylist.txt'
-       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
+       option adb_src_rset 'BEGIN{FS=\"[|^]\"}/^\|\|([[:alnum:]_-]+\.)+[[:alpha:]]+\^("\\\$third-party")?$/{print tolower(\$3)}'
        option adb_src_desc 'focus on russian ads plus generic easylist additions, weekly updates, approx. 14.500 entries'
        option enabled '0'
 
 config source 'shalla'
        option adb_src 'http://www.shallalist.de/Downloads/shallalist.tar.gz'
-       option adb_src_rset '/^([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
+       option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
        option adb_src_desc 'huge blocklist archive subdivided in different categories, daily updates. Check http://www.shallalist.de/categories.html for more categories'
        list adb_src_cat 'adv'
        list adb_src_cat 'costtraps'
@@ -147,26 +147,27 @@ config source 'shalla'
 
 config source 'spam404'
        option adb_src 'https://raw.githubusercontent.com/Dawsey21/Lists/master/main-blacklist.txt'
-       option adb_src_rset '/^([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)+/{print tolower(\$1)}'
+       option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)+/{print tolower(\$1)}'
        option adb_src_desc 'generic blocklist, infrequent updates, approx. 6.000 entries'
        option enabled '0'
 
 config source 'sysctl'
        option adb_src 'http://sysctl.org/cameleon/hosts'
-       option adb_src_rset '/^127\.0\.0\.1[[:space:]]+([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
+       option adb_src_rset '/^127\.0\.0\.1[[:space:]]+([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
        option adb_src_desc 'broad blocklist, weekly updates, approx. 16.500 entries'
        option enabled '0'
 
 config source 'urlhaus'
        option adb_src 'https://urlhaus.abuse.ch/downloads/rpz'
-       option adb_src_rset '/^([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)+/{print tolower(\$1)}'
+       option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)+/{print tolower(\$1)}'
        option adb_src_desc 'urlhaus RPZ domains by abuse.ch, numerous updates on the same day, approx. 3.500 entries'
        option enabled '0'
 
 config source 'ut_capitole'
        option adb_src 'https://dsi.ut-capitole.fr/blacklists/download/blacklists.tar.gz'
-       option adb_src_rset '/^([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
+       option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
        option adb_src_desc 'huge blocklist archive subdivided in different categories, daily updates. Check https://dsi.ut-capitole.fr/blacklists/index_en.php for more categories'
+       list adb_src_cat 'publicite'
        list adb_src_cat 'cryptojacking'
        list adb_src_cat 'ddos'
        list adb_src_cat 'malware'
@@ -176,31 +177,36 @@ config source 'ut_capitole'
 
 config source 'whocares'
        option adb_src 'http://someonewhocares.org/hosts/hosts'
-       option adb_src_rset '/^127\.0\.0\.1[[:space:]]+([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
+       option adb_src_rset '/^127\.0\.0\.1[[:space:]]+([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
        option adb_src_desc 'broad blocklist, weekly updates, approx. 10.000 entries'
        option enabled '0'
 
 config source 'winspy'
        option adb_src 'https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/spy.txt'
-       option adb_src_rset '/^0\.0\.0\.0[[:space:]]+([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
+       option adb_src_rset '/^0\.0\.0\.0[[:space:]]+([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
        option adb_src_desc 'focus on windows spy & telemetry domains, infrequent updates, approx. 300 entries'
        option enabled '0'
 
 config source 'winhelp'
        option adb_src 'http://winhelp2002.mvps.org/hosts.txt'
-       option adb_src_rset '/^0\.0\.0\.0[[:space:]]+([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
+       option adb_src_rset '/^0\.0\.0\.0[[:space:]]+([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$2)}'
        option adb_src_desc 'broad blocklist, infrequent updates, approx. 13.000 entries'
        option enabled '0'
 
+config source 'youtube'
+       option adb_src 'https://api.hackertarget.com/hostsearch/?q=googlevideo.com'
+       option adb_src_rset 'BEGIN{FS=\",\"}/^(r[0-9]+\.){1,1}([[:alnum:]_-]+\.)+[[:alpha:]]+/{sub(/\./,\"---\");print tolower(\$1)}'
+       option adb_src_desc 'focus on youtube ad-related subdomains, dynamic request API, approx. 150 entries'
+       option enabled '0'
+
 config source 'yoyo'
        option adb_src 'https://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=0&mimetype=plaintext'
-       option adb_src_rset '/^([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
+       option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
        option adb_src_desc 'focus on ad related domains, weekly updates, approx. 2.400 entries'
        option enabled '1'
 
 config source 'zeus'
        option adb_src 'https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist'
-       option adb_src_rset '/^([^([:space:]|#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
+       option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}'
        option adb_src_desc 'focus on zeus botnet by abuse.ch, daily updates, approx. 400 entries'
        option enabled '0'
-
index b3981039fde3a317eed4ab2aef34a905b2b2580b..2ae2b086bb0af8b2f726882f78be0936534a4582 100755 (executable)
@@ -16,97 +16,97 @@ adb_pidfile="/var/run/adblock.pid"
 
 boot()
 {
-    adb_boot=1
-    rc_procd start_service
+       adb_boot=1
+       rc_procd start_service
 }
 
 start_service()
 {
-    if [ $("${adb_init}" enabled; printf "%u" ${?}) -eq 0 ]
-    then
-        if [ -n "${adb_boot}" ]
-        then
-            local trigger="$(uci_get adblock global adb_trigger)"
-            if [ "${trigger}" != "timed" ]
-            then
-                return 0
-            fi
-        fi
-        local nice="$(uci_get adblock extra adb_nice)"
-        procd_open_instance "adblock"
-        procd_set_param command "${adb_script}" "${@}"
-        procd_set_param pidfile "${adb_pidfile}"
-        procd_set_param nice ${nice:-0}
-        procd_set_param stdout 1
-        procd_set_param stderr 1
-        procd_close_instance
-    fi
+       if [ $("${adb_init}" enabled; printf "%u" ${?}) -eq 0 ]
+       then
+               if [ -n "${adb_boot}" ]
+               then
+                       local trigger="$(uci_get adblock global adb_trigger)"
+                       if [ "${trigger}" != "timed" ]
+                       then
+                               return 0
+                       fi
+               fi
+               local nice="$(uci_get adblock extra adb_nice)"
+               procd_open_instance "adblock"
+               procd_set_param command "${adb_script}" "${@}"
+               procd_set_param pidfile "${adb_pidfile}"
+               procd_set_param nice ${nice:-0}
+               procd_set_param stdout 1
+               procd_set_param stderr 1
+               procd_close_instance
+       fi
 }
 
 reload_service()
 {
-    rc_procd start_service reload
+       rc_procd start_service reload
 }
 
 stop_service()
 {
-    rc_procd "${adb_script}" stop
-    rc_procd start_service
+       rc_procd "${adb_script}" stop
+       rc_procd start_service
 }
 
 restart()
 {
-    rc_procd start_service restart
+       rc_procd start_service restart
 }
 
 suspend()
 {
-    [ -s "${adb_pidfile}" ] && return 1
-    rc_procd "${adb_script}" suspend
+       [ -s "${adb_pidfile}" ] && return 1
+       rc_procd "${adb_script}" suspend
 }
 
 resume()
 {
-    [ -s "${adb_pidfile}" ] && return 1
-    rc_procd "${adb_script}" resume
+       [ -s "${adb_pidfile}" ] && return 1
+       rc_procd "${adb_script}" resume
 }
 
 query()
 {
-    [ -s "${adb_pidfile}" ] && return 1
-    rc_procd "${adb_script}" query "${1}"
+       [ -s "${adb_pidfile}" ] && return 1
+       rc_procd "${adb_script}" query "${1}"
 }
 
 status()
 {
-    local key keylist value rtfile="$(uci_get adblock extra adb_rtfile)"
+       local key keylist value rtfile="$(uci_get adblock extra adb_rtfile)"
 
-    rtfile="${rtfile:-"/tmp/adb_runtime.json"}"
-    if [ -s "${rtfile}" ]
-    then
-        printf "%s\n" "::: adblock runtime information"
-        json_load "$(cat "${rtfile}" 2>/dev/null)"
-        json_select data
-        json_get_keys keylist
-        for key in ${keylist}
-        do
-            json_get_var value "${key}"
-            printf "  + %-15s : %s\n" "${key}" "${value}"
-        done
-    else
-        printf "%s\n" "::: no adblock runtime information available"
-    fi
+       rtfile="${rtfile:-"/tmp/adb_runtime.json"}"
+       if [ -s "${rtfile}" ]
+       then
+               printf "%s\n" "::: adblock runtime information"
+               json_load_file "${rtfile}"
+               json_select data
+               json_get_keys keylist
+               for key in ${keylist}
+               do
+                       json_get_var value "${key}"
+                       printf "  + %-15s : %s\n" "${key}" "${value}"
+               done
+       else
+               printf "%s\n" "::: no adblock runtime information available"
+       fi
 }
 
 service_triggers()
 {
-    local trigger="$(uci_get adblock global adb_trigger)"
-    local delay="$(uci_get adblock extra adb_triggerdelay)"
+       local trigger="$(uci_get adblock global adb_trigger)"
+       local delay="$(uci_get adblock extra adb_triggerdelay)"
 
-    if [ "${trigger}" != "none" ] && [ "${trigger}" != "timed" ]
-    then
-        PROCD_RELOAD_DELAY=$((${delay:-2} * 1000))
-        procd_add_interface_trigger "interface.*.up" "${trigger}" "${adb_init}" start
-    fi
-    procd_add_reload_trigger "adblock"
+       if [ "${trigger}" != "none" ] && [ "${trigger}" != "timed" ]
+       then
+               PROCD_RELOAD_DELAY=$((${delay:-2} * 1000))
+               procd_add_interface_trigger "interface.*.up" "${trigger}" "${adb_init}" start
+       fi
+       procd_add_reload_trigger "adblock"
 }
index 6a23db79970066568bf46dcb48d2b1105feea87c..54f0288d578aa6ad383eae821176602de09d77c4 100644 (file)
@@ -10,7 +10,7 @@
 
 LC_ALL=C
 PATH="/usr/sbin:/usr/bin:/sbin:/bin"
-mail_ver="1.0.3"
+mail_ver="1.0.4"
 mail_daemon="$(command -v msmtp)"
 mail_profile="adb_notify"
 #mail_debug="--debug"
@@ -18,22 +18,22 @@ mail_rc=1
 
 # mail header & mail receiver check
 #
+mail_receiver=""
 mail_sender="no-reply@adblock"
-mail_receiver="!!!ChangeMe!!!"
 mail_topic="${HOSTNAME}: adblock notification"
 mail_head="From: ${mail_sender}\nTo: ${mail_receiver}\nSubject: ${mail_topic}\nReply-to: ${mail_sender}\nMime-Version: 1.0\nContent-Type: text/html\nContent-Disposition: inline\n\n"
 
-if [ "${mail_receiver}" = "!!!ChangeMe!!!" ]
+if [ -z "${mail_receiver}" ]
 then
-    logger -p "err" -t "adblock-notify-[${mail_ver}]" "please change the 'mail_receiver' in '/etc/adblock/adblock.notify'"
-    exit ${mail_rc}
+       logger -p "err" -t "adblock-notify-${mail_ver}[${$}]" "please supply/customize the 'mail_receiver' in '/etc/adblock/adblock.notify'"
+       exit ${mail_rc}
 fi
 
 # mail daemon check
 #
 if [ ! -x "${mail_daemon}" ]
 then
-    mail_daemon="$(command -v sendmail)"
+       mail_daemon="$(command -v sendmail)"
 fi
 
 # info preparation
@@ -42,9 +42,9 @@ sys_info="$(strings /etc/banner 2>/dev/null; ubus call system board | sed -e 's/
 adb_info="$(/etc/init.d/adblock status 2>/dev/null)"
 if [ -f "/var/log/messages" ]
 then
-    log_info="$(awk '/adblock-/{NR=1;max=79;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max),"&#8629;"} else {print " ",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}' /var/log/messages)"
+       log_info="$(awk '/adblock-/{NR=1;max=79;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max),"&#8629;"} else {print " ",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}' /var/log/messages)"
 else
-    log_info="$(logread -e "adblock-" | awk '{NR=1;max=79;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max),"&#8629;"} else {print " ",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}')"
+       log_info="$(logread -e "adblock-" | awk '{NR=1;max=79;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max),"&#8629;"} else {print " ",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}')"
 fi
 
 # mail body
@@ -59,11 +59,11 @@ mail_text="${mail_text}</pre></body></html>"
 #
 if [ -x "${mail_daemon}" ]
 then
-    printf "%b" "${mail_head}${mail_text}" 2>/dev/null | "${mail_daemon}" ${mail_debug} -a "${mail_profile}" "${mail_receiver}" >/dev/null 2>&1
-    mail_rc=${?}
-    logger -p "info" -t "adblock-notify-[${mail_ver}]" "mail sent to '${mail_receiver}' with rc '${mail_rc}'"
+       printf "%b" "${mail_head}${mail_text}" 2>/dev/null | "${mail_daemon}" ${mail_debug} -a "${mail_profile}" "${mail_receiver}" >/dev/null 2>&1
+       mail_rc=${?}
+       logger -p "info" -t "adblock-notify-${mail_ver}[${$}]" "mail sent to '${mail_receiver}' with rc '${mail_rc}'"
 else
-    logger -p "err" -t "adblock-notify-[${mail_ver}]" "msmtp mail daemon not found"
+       logger -p "err" -t "adblock-notify-${mail_ver}[${$}]" "msmtp mail daemon not found"
 fi
 
 exit ${mail_rc}
index e91f8e9d7a7d49936c30303f949cca34c5111299..a8f2622421a2064ad3193eac01e9bca125fa0760 100755 (executable)
@@ -10,7 +10,7 @@
 #
 LC_ALL=C
 PATH="/usr/sbin:/usr/bin:/sbin:/bin"
-adb_ver="3.5.4-2"
+adb_ver="3.5.5"
 adb_sysver="unknown"
 adb_enabled=0
 adb_debug=0
@@ -44,1037 +44,1025 @@ adb_pidfile="/var/run/adblock.pid"
 #
 f_envload()
 {
-    local dns_up sys_call sys_desc sys_model sys_ver cnt=0
-
-    # get system information
-    #
-    sys_call="$(ubus -S call system board 2>/dev/null)"
-    if [ -n "${sys_call}" ]
-    then
-        sys_desc="$(printf '%s' "${sys_call}" | jsonfilter -e '@.release.description')"
-        sys_model="$(printf '%s' "${sys_call}" | jsonfilter -e '@.model')"
-        sys_ver="$(cat /etc/turris-version 2>/dev/null)"
-        if [ -n "${sys_ver}" ]
-        then
-            sys_desc="${sys_desc}/${sys_ver}"
-        fi
-        adb_sysver="${sys_model}, ${sys_desc}"
-    fi
-
-    # check hash utility
-    #
-    if [ ! -x "${adb_hashutil}" ]
-    then
-        adb_hashutil="$(command -v md5sum)"
-    fi
-
-    # source in system libraries
-    #
-    if [ -r "/lib/functions.sh" ] && [ -r "/usr/share/libubox/jshn.sh" ]
-    then
-        . "/lib/functions.sh"
-        . "/usr/share/libubox/jshn.sh"
-    else
-        f_log "err" "system libraries not found"
-    fi
-
-    # parse 'global' and 'extra' section by callback
-    #
-    config_cb()
-    {
-        local type="${1}"
-        if [ "${type}" = "adblock" ]
-        then
-            option_cb()
-            {
-                local option="${1}"
-                local value="${2}"
-                eval "${option}=\"${value}\""
-            }
-        else
-            reset_cb
-        fi
-    }
-
-    # parse 'source' typed sections
-    #
-    parse_config()
-    {
-        local value opt section="${1}" options="enabled adb_src adb_src_rset adb_src_cat"
-        eval "adb_sources=\"${adb_sources} ${section}\""
-        for opt in ${options}
-        do
-            config_get value "${section}" "${opt}"
-            if [ -n "${value}" ]
-            then
-                eval "${opt}_${section}=\"${value}\""
-            fi
-        done
-    }
-
-    # load adblock config
-    #
-    config_load adblock
-    config_foreach parse_config source
-
-    # check dns backend
-    #
-    case "${adb_dns}" in
-        dnsmasq)
-            adb_dnsinstance="${adb_dnsinstance:-"0"}"
-            adb_dnsuser="${adb_dnsuser:-"dnsmasq"}"
-            adb_dnsdir="${adb_dnsdir:-"/tmp"}"
-            adb_dnsheader=""
-            adb_dnsdeny="awk '{print \"server=/\"\$0\"/\"}'"
-            adb_dnsallow="awk '{print \"server=/\"\$0\"/#\"}'"
-            adb_dnshalt="server=/#/"
-        ;;
-        unbound)
-            adb_dnsinstance="${adb_dnsinstance:-"0"}"
-            adb_dnsuser="${adb_dnsuser:-"unbound"}"
-            adb_dnsdir="${adb_dnsdir:-"/var/lib/unbound"}"
-            adb_dnsheader=""
-            adb_dnsdeny="awk '{print \"local-zone: \042\"\$0\"\042 static\"}'"
-            adb_dnsallow="awk '{print \"local-zone: \042\"\$0\"\042 transparent\"}'"
-            adb_dnshalt="local-zone: \".\" static"
-        ;;
-        named)
-            adb_dnsinstance="${adb_dnsinstance:-"0"}"
-            adb_dnsuser="${adb_dnsuser:-"bind"}"
-            adb_dnsdir="${adb_dnsdir:-"/var/lib/bind"}"
-            adb_dnsheader="\$TTL 2h"$'\n'"@ IN SOA localhost. root.localhost. (1 6h 1h 1w 2h)"$'\n'"  IN NS localhost."
-            adb_dnsdeny="awk '{print \"\"\$0\" CNAME .\n*.\"\$0\" CNAME .\"}'"
-            adb_dnsallow="awk '{print \"\"\$0\" CNAME rpz-passthru.\n*.\"\$0\" CNAME rpz-passthru.\"}'"
-            adb_dnshalt="* CNAME ."
-        ;;
-        kresd)
-            adb_dnsinstance="${adb_dnsinstance:-"0"}"
-            adb_dnsuser="${adb_dnsuser:-"root"}"
-            adb_dnsdir="${adb_dnsdir:-"/etc/kresd"}"
-            adb_dnsheader="\$TTL 2h"$'\n'"@ IN SOA localhost. root.localhost. (1 6h 1h 1w 2h)"$'\n'"  IN NS  localhost."
-            adb_dnsdeny="awk '{print \"\"\$0\" CNAME .\n*.\"\$0\" CNAME .\"}'"
-            adb_dnsallow="awk '{print \"\"\$0\" CNAME rpz-passthru.\n*.\"\$0\" CNAME rpz-passthru.\"}'"
-            adb_dnshalt="* CNAME ."
-        ;;
-        dnscrypt-proxy)
-            adb_dnsinstance="${adb_dnsinstance:-"0"}"
-            adb_dnsuser="${adb_dnsuser:-"nobody"}"
-            adb_dnsdir="${adb_dnsdir:-"/tmp"}"
-            adb_dnsheader=""
-            adb_dnsdeny="awk '{print \$0}'"
-            adb_dnsallow=""
-            adb_dnshalt=""
-        ;;
-    esac
-
-    # check adblock status
-    #
-    if [ ${adb_enabled} -eq 0 ]
-    then
-        f_extconf
-        f_temp
-        f_rmdns
-        f_jsnup
-        f_log "info" "adblock is currently disabled, please set adb_enabled to '1' to use this service"
-        exit 0
-    fi
-
-    if [ -d "${adb_dnsdir}" ] && [ ! -f "${adb_dnsdir}/${adb_dnsfile}" ]
-    then
-        printf '%s\n' "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}"
-    fi
-
-    if [ "${adb_action}" = "start" ] && [ "${adb_trigger}" = "timed" ]
-    then
-        sleep ${adb_triggerdelay}
-    fi
-
-    while [ ${cnt} -le 30 ]
-    do
-        dns_up="$(ubus -S call service list "{\"name\":\"${adb_dns}\"}" 2>/dev/null | jsonfilter -l1 -e "@[\"${adb_dns}\"].instances.*.running" 2>/dev/null)"
-        if [ "${dns_up}" = "true" ]
-        then
-            break
-        fi
-        sleep 1
-        cnt=$((cnt+1))
-    done
-
-    if [ "${dns_up}" != "true" ] || [ -z "${adb_dns}" ] || [ ! -x "$(command -v ${adb_dns})" ]
-    then
-        f_log "err" "'${adb_dns}' not running or not executable"
-    elif [ ! -d "${adb_dnsdir}" ]
-    then
-        f_log "err" "'${adb_dnsdir}' backend directory not found"
-    fi
+       local dns_up sys_call sys_desc sys_model sys_ver cnt=0
+
+       # get system information
+       #
+       sys_call="$(ubus -S call system board 2>/dev/null)"
+       if [ -n "${sys_call}" ]
+       then
+               sys_desc="$(printf '%s' "${sys_call}" | jsonfilter -e '@.release.description')"
+               sys_model="$(printf '%s' "${sys_call}" | jsonfilter -e '@.model')"
+               sys_ver="$(cat /etc/turris-version 2>/dev/null)"
+               if [ -n "${sys_ver}" ]
+               then
+                       sys_desc="${sys_desc}/${sys_ver}"
+               fi
+               adb_sysver="${sys_model}, ${sys_desc}"
+       fi
+
+       # check hash utility
+       #
+       if [ ! -x "${adb_hashutil}" ]
+       then
+               adb_hashutil="$(command -v md5sum)"
+       fi
+
+       # parse 'global' and 'extra' section by callback
+       #
+       config_cb()
+       {
+               local type="${1}"
+               if [ "${type}" = "adblock" ]
+               then
+                       option_cb()
+                       {
+                               local option="${1}"
+                               local value="${2}"
+                               eval "${option}=\"${value}\""
+                       }
+               else
+                       reset_cb
+               fi
+       }
+
+       # parse 'source' typed sections
+       #
+       parse_config()
+       {
+               local value opt section="${1}" options="enabled adb_src adb_src_rset adb_src_cat"
+               eval "adb_sources=\"${adb_sources} ${section}\""
+               for opt in ${options}
+               do
+                       config_get value "${section}" "${opt}"
+                       if [ -n "${value}" ]
+                       then
+                               eval "${opt}_${section}=\"${value}\""
+                       fi
+               done
+       }
+
+       # load adblock config
+       #
+       config_load adblock
+       config_foreach parse_config source
+
+       # check dns backend
+       #
+       case "${adb_dns}" in
+               dnsmasq)
+                       adb_dnsinstance="${adb_dnsinstance:-"0"}"
+                       adb_dnsuser="${adb_dnsuser:-"dnsmasq"}"
+                       adb_dnsdir="${adb_dnsdir:-"/tmp"}"
+                       adb_dnsheader=""
+                       adb_dnsdeny="awk '{print \"server=/\"\$0\"/\"}'"
+                       adb_dnsallow="awk '{print \"server=/\"\$0\"/#\"}'"
+                       adb_dnshalt="server=/#/"
+               ;;
+               unbound)
+                       adb_dnsinstance="${adb_dnsinstance:-"0"}"
+                       adb_dnsuser="${adb_dnsuser:-"unbound"}"
+                       adb_dnsdir="${adb_dnsdir:-"/var/lib/unbound"}"
+                       adb_dnsheader=""
+                       adb_dnsdeny="awk '{print \"local-zone: \042\"\$0\"\042 static\"}'"
+                       adb_dnsallow="awk '{print \"local-zone: \042\"\$0\"\042 transparent\"}'"
+                       adb_dnshalt="local-zone: \".\" static"
+               ;;
+               named)
+                       adb_dnsinstance="${adb_dnsinstance:-"0"}"
+                       adb_dnsuser="${adb_dnsuser:-"bind"}"
+                       adb_dnsdir="${adb_dnsdir:-"/var/lib/bind"}"
+                       adb_dnsheader="\$TTL 2h"$'\n'"@ IN SOA localhost. root.localhost. (1 6h 1h 1w 2h)"$'\n'"  IN NS localhost."
+                       adb_dnsdeny="awk '{print \"\"\$0\" CNAME .\n*.\"\$0\" CNAME .\"}'"
+                       adb_dnsallow="awk '{print \"\"\$0\" CNAME rpz-passthru.\n*.\"\$0\" CNAME rpz-passthru.\"}'"
+                       adb_dnshalt="* CNAME ."
+               ;;
+               kresd)
+                       adb_dnsinstance="${adb_dnsinstance:-"0"}"
+                       adb_dnsuser="${adb_dnsuser:-"root"}"
+                       adb_dnsdir="${adb_dnsdir:-"/etc/kresd"}"
+                       adb_dnsheader="\$TTL 2h"$'\n'"@ IN SOA localhost. root.localhost. (1 6h 1h 1w 2h)"$'\n'"  IN NS  localhost."
+                       adb_dnsdeny="awk '{print \"\"\$0\" CNAME .\n*.\"\$0\" CNAME .\"}'"
+                       adb_dnsallow="awk '{print \"\"\$0\" CNAME rpz-passthru.\n*.\"\$0\" CNAME rpz-passthru.\"}'"
+                       adb_dnshalt="* CNAME ."
+               ;;
+               dnscrypt-proxy)
+                       adb_dnsinstance="${adb_dnsinstance:-"0"}"
+                       adb_dnsuser="${adb_dnsuser:-"nobody"}"
+                       adb_dnsdir="${adb_dnsdir:-"/tmp"}"
+                       adb_dnsheader=""
+                       adb_dnsdeny="awk '{print \$0}'"
+                       adb_dnsallow=""
+                       adb_dnshalt=""
+               ;;
+       esac
+
+       # check adblock status
+       #
+       if [ ${adb_enabled} -eq 0 ]
+       then
+               f_extconf
+               f_temp
+               f_rmdns
+               f_jsnup "disabled"
+               f_log "info" "adblock is currently disabled, please set adb_enabled to '1' to use this service"
+               exit 0
+       fi
+
+       if [ -d "${adb_dnsdir}" ] && [ ! -f "${adb_dnsdir}/${adb_dnsfile}" ]
+       then
+               printf '%s\n' "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}"
+       fi
+
+       if [ "${adb_action}" = "start" ] && [ "${adb_trigger}" = "timed" ]
+       then
+               sleep ${adb_triggerdelay}
+       fi
+
+       while [ ${cnt} -le 30 ]
+       do
+               dns_up="$(ubus -S call service list "{\"name\":\"${adb_dns}\"}" 2>/dev/null | jsonfilter -l1 -e "@[\"${adb_dns}\"].instances.*.running" 2>/dev/null)"
+               if [ "${dns_up}" = "true" ]
+               then
+                       break
+               fi
+               sleep 1
+               cnt=$((cnt+1))
+       done
+
+       if [ "${dns_up}" != "true" ] || [ -z "${adb_dns}" ] || [ ! -x "$(command -v ${adb_dns})" ]
+       then
+               f_log "err" "'${adb_dns}' not running or not executable"
+       elif [ ! -d "${adb_dnsdir}" ]
+       then
+               f_log "err" "'${adb_dnsdir}' backend directory not found"
+       fi
 }
 
 # check environment
 #
 f_envcheck()
 {
-    local ssl_lib
-
-    # check external uci config files
-    #
-    f_extconf
-
-    # check fetch utility
-    #
-    case "${adb_fetchutil}" in
-        uclient-fetch)
-            if [ -f "/lib/libustream-ssl.so" ]
-            then
-                adb_fetchparm="${adb_fetchparm:-"--timeout=10 --no-check-certificate -O"}"
-                ssl_lib="libustream-ssl"
-            else
-                adb_fetchparm="${adb_fetchparm:-"--timeout=10 -O"}"
-            fi
-        ;;
-        wget)
-            adb_fetchparm="${adb_fetchparm:-"--no-cache --no-cookies --max-redirect=0 --timeout=10 --no-check-certificate -O"}"
-            ssl_lib="built-in"
-        ;;
-        wget-nossl)
-            adb_fetchparm="${adb_fetchparm:-"--no-cache --no-cookies --max-redirect=0 --timeout=10 -O"}"
-        ;;
-        busybox)
-            adb_fetchparm="${adb_fetchparm:-"-O"}"
-        ;;
-        curl)
-            adb_fetchparm="${adb_fetchparm:-"--connect-timeout 10 --insecure -o"}"
-            ssl_lib="built-in"
-        ;;
-        aria2c)
-            adb_fetchparm="${adb_fetchparm:-"--timeout=10 --allow-overwrite=true --auto-file-renaming=false --check-certificate=false -o"}"
-            ssl_lib="built-in"
-        ;;
-    esac
-    adb_fetchutil="$(command -v "${adb_fetchutil}")"
-
-    if [ ! -x "${adb_fetchutil}" ] || [ -z "${adb_fetchutil}" ] || [ -z "${adb_fetchparm}" ]
-    then
-        f_log "err" "download utility not found, please install 'uclient-fetch' with 'libustream-mbedtls' or the full 'wget' package"
-    fi
-    adb_fetchinfo="${adb_fetchutil} (${ssl_lib:-"-"})"
-
-    f_temp
-    f_jsnup "running"
-    f_log "info" "start adblock processing (${adb_action})"
+       local ssl_lib
+
+       # startup message
+       #
+       f_log "info" "adblock instance started ::: action: ${adb_action}, priority: ${adb_nice:-"0"}, pid: ${$}"
+       f_jsnup "running"
+
+       # check external uci config files
+       #
+       f_extconf
+
+       # check fetch utility
+       #
+       case "${adb_fetchutil}" in
+               uclient-fetch)
+                       if [ -f "/lib/libustream-ssl.so" ]
+                       then
+                               adb_fetchparm="${adb_fetchparm:-"--timeout=10 --no-check-certificate -O"}"
+                               ssl_lib="libustream-ssl"
+                       else
+                               adb_fetchparm="${adb_fetchparm:-"--timeout=10 -O"}"
+                       fi
+               ;;
+               wget)
+                       adb_fetchparm="${adb_fetchparm:-"--no-cache --no-cookies --max-redirect=0 --timeout=10 --no-check-certificate -O"}"
+                       ssl_lib="built-in"
+               ;;
+               wget-nossl)
+                       adb_fetchparm="${adb_fetchparm:-"--no-cache --no-cookies --max-redirect=0 --timeout=10 -O"}"
+               ;;
+               busybox)
+                       adb_fetchparm="${adb_fetchparm:-"-O"}"
+               ;;
+               curl)
+                       adb_fetchparm="${adb_fetchparm:-"--connect-timeout 10 --insecure -o"}"
+                       ssl_lib="built-in"
+               ;;
+               aria2c)
+                       adb_fetchparm="${adb_fetchparm:-"--timeout=10 --allow-overwrite=true --auto-file-renaming=false --check-certificate=false -o"}"
+                       ssl_lib="built-in"
+               ;;
+       esac
+       adb_fetchutil="$(command -v "${adb_fetchutil}")"
+
+       if [ ! -x "${adb_fetchutil}" ] || [ -z "${adb_fetchutil}" ] || [ -z "${adb_fetchparm}" ]
+       then
+               f_log "err" "download utility not found, please install 'uclient-fetch' with 'libustream-mbedtls' or the full 'wget' package"
+       fi
+       adb_fetchinfo="${adb_fetchutil} (${ssl_lib:-"-"})"
+       f_temp
 }
 
 # create temporary files and directories
 #
 f_temp()
 {
-    if [ -z "${adb_tmpdir}" ]
-    then
-        adb_tmpdir="$(mktemp -p /tmp -d)"
-        adb_tmpload="$(mktemp -p ${adb_tmpdir} -tu)"
-        adb_tmpfile="$(mktemp -p ${adb_tmpdir} -tu)"
-    fi
-    if [ ! -s "${adb_pidfile}" ]
-    then
-        printf '%s' "${$}" > "${adb_pidfile}"
-    fi
+       if [ -z "${adb_tmpdir}" ]
+       then
+               adb_tmpdir="$(mktemp -p /tmp -d)"
+               adb_tmpload="$(mktemp -p ${adb_tmpdir} -tu)"
+               adb_tmpfile="$(mktemp -p ${adb_tmpdir} -tu)"
+       fi
+       if [ ! -s "${adb_pidfile}" ]
+       then
+               printf '%s' "${$}" > "${adb_pidfile}"
+       fi
 }
 
 # remove temporary files and directories
 #
 f_rmtemp()
 {
-    if [ -d "${adb_tmpdir}" ]
-    then
-        rm -rf "${adb_tmpdir}"
-    fi
-    > "${adb_pidfile}"
+       if [ -d "${adb_tmpdir}" ]
+       then
+               rm -rf "${adb_tmpdir}"
+       fi
+       > "${adb_pidfile}"
 }
 
 # remove dns related files and directories
 #
 f_rmdns()
 {
-    if [ -n "${adb_dns}" ]
-    then
-        f_hash
-        printf '%s\n' "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}"
-        > "${adb_dnsdir}/.${adb_dnsfile}"
-        > "${adb_rtfile}"
-        rm -f "${adb_backupdir}/${adb_dnsprefix}"*.gz
-        f_hash
-        if [ ${?} -eq 1 ]
-        then
-            f_dnsup
-        fi
-        f_rmtemp
-    fi
-    f_log "debug" "f_rmdns::: dns: ${adb_dns}, dns_dir: ${adb_dnsdir}, dns_prefix: ${adb_dnsprefix}, dns_file: ${adb_dnsfile}, rt_file: ${adb_rtfile}, backup_dir: ${adb_backupdir}"
+       if [ -n "${adb_dns}" ]
+       then
+               f_hash
+               printf '%s\n' "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}"
+               > "${adb_dnsdir}/.${adb_dnsfile}"
+               > "${adb_rtfile}"
+               rm -f "${adb_backupdir}/${adb_dnsprefix}"*.gz
+               f_hash
+               if [ ${?} -eq 1 ]
+               then
+                       f_dnsup
+               fi
+               f_rmtemp
+       fi
+       f_log "debug" "f_rmdns::: dns: ${adb_dns}, dns_dir: ${adb_dnsdir}, dns_prefix: ${adb_dnsprefix}, dns_file: ${adb_dnsfile}, rt_file: ${adb_rtfile}, backup_dir: ${adb_backupdir}"
 }
 
 # commit uci changes
 #
 f_uci()
 {
-    local change config="${1}"
-
-    if [ -n "${config}" ]
-    then
-        change="$(uci -q changes "${config}" | awk '{ORS=" "; print $0}')"
-        if [ -n "${change}" ]
-        then
-            uci -q commit "${config}"
-            case "${config}" in
-                firewall)
-                    /etc/init.d/firewall reload >/dev/null 2>&1
-                ;;
-                *)
-                    /etc/init.d/"${adb_dns}" reload >/dev/null 2>&1
-                ;;
-            esac
-        fi
-    fi
-    f_log "debug" "f_uci  ::: config: ${config}, change: ${change}"
+       local change config="${1}"
+
+       if [ -n "${config}" ]
+       then
+               change="$(uci -q changes "${config}" | awk '{ORS=" "; print $0}')"
+               if [ -n "${change}" ]
+               then
+                       uci_commit "${config}"
+                       case "${config}" in
+                               firewall)
+                                       /etc/init.d/firewall reload >/dev/null 2>&1
+                               ;;
+                               *)
+                                       /etc/init.d/"${adb_dns}" reload >/dev/null 2>&1
+                               ;;
+                       esac
+               fi
+       fi
+       f_log "debug" "f_uci  ::: config: ${config}, change: ${change}"
 }
 
 # list/overall count
 #
 f_count()
 {
-    local mode="${1}"
-
-    adb_cnt=0
-    if [ -s "${adb_dnsdir}/${adb_dnsfile}" ] && ([ -z "${mode}" ] || [ "${mode}" = "final" ])
-    then
-        adb_cnt="$(( $(wc -l 2>/dev/null < "${adb_dnsdir}/${adb_dnsfile}") - $(wc -l 2>/dev/null < "${adb_tmpdir}/tmp.add_whitelist") ))"
-        if [ "${adb_dns}" = "named" ] || [ "${adb_dns}" = "kresd" ]
-        then
-            adb_cnt="$(( (${adb_cnt} - $(printf '%s' "${adb_dnsheader}" | grep -c "^")) / 2 ))"
-        fi
-    elif [ -s "${adb_tmpfile}" ]
-    then
-        adb_cnt="$(wc -l 2>/dev/null < "${adb_tmpfile}")"
-    fi
+       local mode="${1}"
+
+       adb_cnt=0
+       if [ -s "${adb_dnsdir}/${adb_dnsfile}" ] && ([ -z "${mode}" ] || [ "${mode}" = "final" ])
+       then
+               adb_cnt="$(( $(wc -l 2>/dev/null < "${adb_dnsdir}/${adb_dnsfile}") - $(wc -l 2>/dev/null < "${adb_tmpdir}/tmp.add_whitelist") ))"
+               if [ "${adb_dns}" = "named" ] || [ "${adb_dns}" = "kresd" ]
+               then
+                       adb_cnt="$(( (${adb_cnt} - $(printf '%s' "${adb_dnsheader}" | grep -c "^")) / 2 ))"
+               fi
+       elif [ -s "${adb_tmpfile}" ]
+       then
+               adb_cnt="$(wc -l 2>/dev/null < "${adb_tmpfile}")"
+       fi
 }
 
 # set external config options
 #
 f_extconf()
 {
-    local uci_config port port_list="53 853 5353"
-
-    case "${adb_dns}" in
-        dnsmasq)
-            uci_config="dhcp"
-            if [ ${adb_enabled} -eq 1 ] && [ -z "$(uci -q get dhcp.@dnsmasq[${adb_dnsinstance}].serversfile | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ]
-            then
-                uci -q set dhcp.@dnsmasq[${adb_dnsinstance}].serversfile="${adb_dnsdir}/${adb_dnsfile}"
-            elif [ ${adb_enabled} -eq 0 ] && [ -n "$(uci -q get dhcp.@dnsmasq[${adb_dnsinstance}].serversfile | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ]
-            then
-                uci -q delete dhcp.@dnsmasq[${adb_dnsinstance}].serversfile
-            fi
-        ;;
-        kresd)
-            uci_config="resolver"
-            if [ ${adb_enabled} -eq 1 ] && [ -z "$(uci -q get resolver.kresd.rpz_file | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ]
-            then
-                uci -q add_list resolver.kresd.rpz_file="${adb_dnsdir}/${adb_dnsfile}"
-            elif [ ${adb_enabled} -eq 0 ] && [ -n "$(uci -q get resolver.kresd.rpz_file | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ]
-            then
-                uci -q del_list resolver.kresd.rpz_file="${adb_dnsdir}/${adb_dnsfile}"
-            fi
-            if [ ${adb_enabled} -eq 1 ] && [ ${adb_dnsflush} -eq 0 ] && [ "$(uci -q get resolver.kresd.keep_cache)" != "1" ]
-            then
-                uci -q set resolver.kresd.keep_cache="1"
-            elif [ ${adb_enabled} -eq 0 ] || ([ ${adb_dnsflush} -eq 1 ] && [ "$(uci -q get resolver.kresd.keep_cache)" = "1" ])
-            then
-                uci -q set resolver.kresd.keep_cache="0"
-            fi
-        ;;
-    esac
-    f_uci "${uci_config}"
-
-    uci_config="firewall"
-    if [ ${adb_enabled} -eq 1 ] && [ ${adb_forcedns} -eq 1 ] && \
-       [ -z "$(uci -q get firewall.adblock_dns_53)" ] && [ $(/etc/init.d/firewall enabled; printf '%u' ${?}) -eq 0 ]
-    then
-        for port in ${port_list}
-        do
-            uci_add firewall "redirect" "adblock_dns_${port}"
-            uci_set firewall "adblock_dns_${port}" "name" "Adblock DNS, port ${port}"
-            uci_set firewall "adblock_dns_${port}" "src" "lan"
-            uci_set firewall "adblock_dns_${port}" "proto" "tcp udp"
-            uci_set firewall "adblock_dns_${port}" "src_dport" "${port}"
-            uci_set firewall "adblock_dns_${port}" "dest_port" "${port}"
-            uci_set firewall "adblock_dns_${port}" "target" "DNAT"
-        done
-    elif [ -n "$(uci -q get firewall.adblock_dns_53)" ] && ([ ${adb_enabled} -eq 0 ] || [ ${adb_forcedns} -eq 0 ])
-    then
-        for port in ${port_list}
-        do
-            uci_remove firewall "adblock_dns_${port}"
-        done
-    fi
-    f_uci "${uci_config}"
+       local uci_config port port_list="53 853 5353"
+
+       case "${adb_dns}" in
+               dnsmasq)
+                       uci_config="dhcp"
+                       if [ ${adb_enabled} -eq 1 ] && [ -z "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}].serversfile" | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ]
+                       then
+                               uci_set dhcp "@dnsmasq[${adb_dnsinstance}].serversfile" "${adb_dnsdir}/${adb_dnsfile}"
+                       elif [ ${adb_enabled} -eq 0 ] && [ -n "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}].serversfile" | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ]
+                       then
+                               uci_remove dhcp "@dnsmasq[${adb_dnsinstance}].serversfile"
+                       fi
+               ;;
+               kresd)
+                       uci_config="resolver"
+                       if [ ${adb_enabled} -eq 1 ] && [ -z "$(uci_get resolver kresd.rpz_file | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ]
+                       then
+                               uci -q add_list resolver.kresd.rpz_file="${adb_dnsdir}/${adb_dnsfile}"
+                       elif [ ${adb_enabled} -eq 0 ] && [ -n "$(uci_get resolver kresd.rpz_file | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ]
+                       then
+                               uci -q del_list resolver.kresd.rpz_file="${adb_dnsdir}/${adb_dnsfile}"
+                       fi
+                       if [ ${adb_enabled} -eq 1 ] && [ ${adb_dnsflush} -eq 0 ] && [ "$(uci_get resolver "kresd.keep_cache")" != "1" ]
+                       then
+                               uci_set resolver "kresd.keep_cache" "1"
+                       elif [ ${adb_enabled} -eq 0 ] || ([ ${adb_dnsflush} -eq 1 ] && [ "$(uci_get resolver "kresd.keep_cache")" = "1" ])
+                       then
+                               uci_set resolver "kresd.keep_cache" "0"
+                       fi
+               ;;
+       esac
+       f_uci "${uci_config}"
+
+       uci_config="firewall"
+       if [ ${adb_enabled} -eq 1 ] && [ ${adb_forcedns} -eq 1 ] && \
+               [ -z "$(uci_get firewall adblock_dns_53)" ] && [ $(/etc/init.d/firewall enabled; printf '%u' ${?}) -eq 0 ]
+       then
+               for port in ${port_list}
+               do
+                       uci_add firewall "redirect" "adblock_dns_${port}"
+                       uci_set firewall "adblock_dns_${port}" "name" "Adblock DNS, port ${port}"
+                       uci_set firewall "adblock_dns_${port}" "src" "lan"
+                       uci_set firewall "adblock_dns_${port}" "proto" "tcp udp"
+                       uci_set firewall "adblock_dns_${port}" "src_dport" "${port}"
+                       uci_set firewall "adblock_dns_${port}" "dest_port" "${port}"
+                       uci_set firewall "adblock_dns_${port}" "target" "DNAT"
+               done
+       elif [ -n "$(uci_get firewall adblock_dns_53)" ] && ([ ${adb_enabled} -eq 0 ] || [ ${adb_forcedns} -eq 0 ])
+       then
+               for port in ${port_list}
+               do
+                       uci_remove firewall "adblock_dns_${port}"
+               done
+       fi
+       f_uci "${uci_config}"
 }
 
 # restart of the dns backend
 #
 f_dnsup()
 {
-    local dns_up cache_util cache_rc cnt=0
-
-    if [ ${adb_dnsflush} -eq 0 ] && [ ${adb_enabled} -eq 1 ] && [ "${adb_rc}" -eq 0 ]
-    then
-        case "${adb_dns}" in
-            dnsmasq)
-                killall -q -HUP "${adb_dns}"
-                cache_rc=${?}
-            ;;
-            unbound)
-                cache_util="$(command -v unbound-control)"
-                if [ -x "${cache_util}" ] && [ -d "${adb_tmpdir}" ] && [ -f "${adb_dnsdir}"/unbound.conf ]
-                then
-                    "${cache_util}" -c "${adb_dnsdir}"/unbound.conf dump_cache > "${adb_tmpdir}"/adb_cache.dump 2>/dev/null
-                fi
-                "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
-            ;;
-            kresd)
-                cache_util="keep_cache"
-                "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
-                cache_rc=${?}
-            ;;
-            named)
-                cache_util="$(command -v rndc)"
-                if [ -x "${cache_util}" ] && [ -f /etc/bind/rndc.conf ]
-                then
-                    "${cache_util}" -c /etc/bind/rndc.conf reload >/dev/null 2>&1
-                    cache_rc=${?}
-                else
-                    "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
-                fi
-            ;;
-            *)
-                "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
-            ;;
-        esac
-    else
-        "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
-    fi
-
-    adb_rc=1
-    while [ ${cnt} -le 10 ]
-    do
-        dns_up="$(ubus -S call service list "{\"name\":\"${adb_dns}\"}" | jsonfilter -l1 -e "@[\"${adb_dns}\"].instances.*.running")"
-        if [ "${dns_up}" = "true" ]
-        then
-            case "${adb_dns}" in
-                unbound)
-                    cache_util="$(command -v unbound-control)"
-                    if [ -x "${cache_util}" ] && [ -d "${adb_tmpdir}" ] && [ -s "${adb_tmpdir}"/adb_cache.dump ]
-                    then
-                        while [ ${cnt} -le 10 ]
-                        do
-                            "${cache_util}" -c "${adb_dnsdir}"/unbound.conf load_cache < "${adb_tmpdir}"/adb_cache.dump >/dev/null 2>&1
-                            cache_rc=${?}
-                            if [ ${cache_rc} -eq 0 ]
-                            then
-                                break
-                            fi
-                            cnt=$((cnt+1))
-                            sleep 1
-                        done
-                    fi
-                ;;
-            esac
-            adb_rc=0
-            break
-        fi
-        cnt=$((cnt+1))
-        sleep 1
-    done
-    f_log "debug" "f_dnsup::: cache_util: ${cache_util:-"-"}, cache_rc: ${cache_rc:-"-"}, cache_flush: ${adb_dnsflush}, cache_cnt: ${cnt}, rc: ${adb_rc}"
-    return ${adb_rc}
+       local dns_up cache_util cache_rc cnt=0
+
+       if [ ${adb_dnsflush} -eq 0 ] && [ ${adb_enabled} -eq 1 ] && [ "${adb_rc}" -eq 0 ]
+       then
+               case "${adb_dns}" in
+                       dnsmasq)
+                               killall -q -HUP "${adb_dns}"
+                               cache_rc=${?}
+                       ;;
+                       unbound)
+                               cache_util="$(command -v unbound-control)"
+                               if [ -x "${cache_util}" ] && [ -d "${adb_tmpdir}" ] && [ -f "${adb_dnsdir}"/unbound.conf ]
+                               then
+                                       "${cache_util}" -c "${adb_dnsdir}"/unbound.conf dump_cache > "${adb_tmpdir}"/adb_cache.dump 2>/dev/null
+                               fi
+                               "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
+                       ;;
+                       kresd)
+                               cache_util="keep_cache"
+                               "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
+                               cache_rc=${?}
+                       ;;
+                       named)
+                               cache_util="$(command -v rndc)"
+                               if [ -x "${cache_util}" ] && [ -f /etc/bind/rndc.conf ]
+                               then
+                                       "${cache_util}" -c /etc/bind/rndc.conf reload >/dev/null 2>&1
+                                       cache_rc=${?}
+                               else
+                                       "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
+                               fi
+                       ;;
+                       *)
+                               "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
+                       ;;
+               esac
+       else
+               "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
+       fi
+
+       adb_rc=1
+       while [ ${cnt} -le 10 ]
+       do
+               dns_up="$(ubus -S call service list "{\"name\":\"${adb_dns}\"}" | jsonfilter -l1 -e "@[\"${adb_dns}\"].instances.*.running")"
+               if [ "${dns_up}" = "true" ]
+               then
+                       case "${adb_dns}" in
+                               unbound)
+                                       cache_util="$(command -v unbound-control)"
+                                       if [ -x "${cache_util}" ] && [ -d "${adb_tmpdir}" ] && [ -s "${adb_tmpdir}"/adb_cache.dump ]
+                                       then
+                                               while [ ${cnt} -le 10 ]
+                                               do
+                                                       "${cache_util}" -c "${adb_dnsdir}"/unbound.conf load_cache < "${adb_tmpdir}"/adb_cache.dump >/dev/null 2>&1
+                                                       cache_rc=${?}
+                                                       if [ ${cache_rc} -eq 0 ]
+                                                       then
+                                                               break
+                                                       fi
+                                                       cnt=$((cnt+1))
+                                                       sleep 1
+                                               done
+                                       fi
+                               ;;
+                       esac
+                       adb_rc=0
+                       break
+               fi
+               cnt=$((cnt+1))
+               sleep 1
+       done
+       f_log "debug" "f_dnsup::: cache_util: ${cache_util:-"-"}, cache_rc: ${cache_rc:-"-"}, cache_flush: ${adb_dnsflush}, cache_cnt: ${cnt}, rc: ${adb_rc}"
+       return ${adb_rc}
 }
 
 # backup/restore/remove blocklists
 #
 f_list()
 {
-    local file mode="${1}" in_rc="${adb_rc}"
-
-    case "${mode}" in
-        backup)
-            if [ -d "${adb_backupdir}" ]
-            then
-                gzip -cf "${adb_tmpfile}" 2>/dev/null > "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz"
-                adb_rc=${?}
-            fi
-        ;;
-        restore)
-            if [ -d "${adb_backupdir}" ] && [ -f "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz" ]
-            then
-                gunzip -cf "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz" 2>/dev/null > "${adb_tmpfile}"
-                adb_rc=${?}
-            fi
-        ;;
-        remove)
-            if [ -d "${adb_backupdir}" ]
-            then
-                rm -f "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz"
-            fi
-            adb_rc=${?}
-        ;;
-        merge)
-            for file in "${adb_tmpfile}".*
-            do
-                cat "${file}" 2>/dev/null >> "${adb_tmpdir}/${adb_dnsfile}"
-                if [ ${?} -ne 0 ]
-                then
-                    adb_rc=${?}
-                    break
-                fi
-                rm -f "${file}"
-            done
-            adb_tmpfile="${adb_tmpdir}/${adb_dnsfile}"
-        ;;
-        final)
-            > "${adb_dnsdir}/${adb_dnsfile}"
-
-            if [ -s "${adb_tmpdir}/tmp.add_whitelist" ]
-            then
-                cat "${adb_tmpdir}/tmp.add_whitelist" >> "${adb_dnsdir}/${adb_dnsfile}"
-            fi
-
-            if [ -s "${adb_tmpdir}/tmp.rem_whitelist" ]
-            then
-                grep -vf "${adb_tmpdir}/tmp.rem_whitelist" "${adb_tmpdir}/${adb_dnsfile}" | eval "${adb_dnsdeny}" >> "${adb_dnsdir}/${adb_dnsfile}"
-            else
-                eval "${adb_dnsdeny}" "${adb_tmpdir}/${adb_dnsfile}" >> "${adb_dnsdir}/${adb_dnsfile}"
-            fi
-
-            if [ ${?} -eq 0 ] && [ -n "${adb_dnsheader}" ]
-            then
-                printf '%s\n' "${adb_dnsheader}" | cat - "${adb_dnsdir}/${adb_dnsfile}" > "${adb_tmpdir}/${adb_dnsfile}"
-                cat "${adb_tmpdir}/${adb_dnsfile}" > "${adb_dnsdir}/${adb_dnsfile}"
-            fi
-            adb_rc=${?}
-        ;;
-    esac
-    f_count "${mode}"
-    f_log "debug" "f_list ::: name: ${src_name:-"-"}, mode: ${mode}, cnt: ${adb_cnt}, in_rc: ${in_rc}, out_rc: ${adb_rc}"
+       local file mode="${1}" in_rc="${adb_rc}"
+
+       case "${mode}" in
+               backup)
+                       if [ -d "${adb_backupdir}" ]
+                       then
+                               gzip -cf "${adb_tmpfile}" 2>/dev/null > "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz"
+                               adb_rc=${?}
+                       fi
+               ;;
+               restore)
+                       if [ -d "${adb_backupdir}" ] && [ -f "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz" ]
+                       then
+                               gunzip -cf "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz" 2>/dev/null > "${adb_tmpfile}"
+                               adb_rc=${?}
+                       fi
+               ;;
+               remove)
+                       if [ -d "${adb_backupdir}" ]
+                       then
+                               rm -f "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz"
+                       fi
+                       adb_rc=${?}
+               ;;
+               merge)
+                       for file in "${adb_tmpfile}".*
+                       do
+                               cat "${file}" 2>/dev/null >> "${adb_tmpdir}/${adb_dnsfile}"
+                               if [ ${?} -ne 0 ]
+                               then
+                                       adb_rc=${?}
+                                       break
+                               fi
+                               rm -f "${file}"
+                       done
+                       adb_tmpfile="${adb_tmpdir}/${adb_dnsfile}"
+               ;;
+               final)
+                       > "${adb_dnsdir}/${adb_dnsfile}"
+
+                       if [ -s "${adb_tmpdir}/tmp.add_whitelist" ]
+                       then
+                               cat "${adb_tmpdir}/tmp.add_whitelist" >> "${adb_dnsdir}/${adb_dnsfile}"
+                       fi
+
+                       if [ -s "${adb_tmpdir}/tmp.rem_whitelist" ]
+                       then
+                               grep -vf "${adb_tmpdir}/tmp.rem_whitelist" "${adb_tmpdir}/${adb_dnsfile}" | eval "${adb_dnsdeny}" >> "${adb_dnsdir}/${adb_dnsfile}"
+                       else
+                               eval "${adb_dnsdeny}" "${adb_tmpdir}/${adb_dnsfile}" >> "${adb_dnsdir}/${adb_dnsfile}"
+                       fi
+
+                       if [ ${?} -eq 0 ] && [ -n "${adb_dnsheader}" ]
+                       then
+                               printf '%s\n' "${adb_dnsheader}" | cat - "${adb_dnsdir}/${adb_dnsfile}" > "${adb_tmpdir}/${adb_dnsfile}"
+                               mv -f "${adb_tmpdir}/${adb_dnsfile}" "${adb_dnsdir}/${adb_dnsfile}"
+                       fi
+                       adb_rc=${?}
+               ;;
+       esac
+       f_count "${mode}"
+       f_log "debug" "f_list ::: name: ${src_name:-"-"}, mode: ${mode}, cnt: ${adb_cnt}, in_rc: ${in_rc}, out_rc: ${adb_rc}"
 }
 
 # top level domain compression
 #
 f_tld()
 {
-    local cnt cnt_srt cnt_tld source="${1}" temp="${1}.tld"
-
-    cnt="$(wc -l 2>/dev/null < "${source}")"
-    sort -u "${source}" > "${temp}"
-    if [ ${?} -eq 0 ]
-    then
-        cnt_srt="$(wc -l 2>/dev/null < "${temp}")"
-        awk -F "." '{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "${temp}" > "${source}"
-        if [ ${?} -eq 0 ]
-        then
-            sort "${source}" > "${temp}"
-            if [ ${?} -eq 0 ]
-            then
-                awk '{if(NR==1){tld=$NF};while(getline){if($NF!~tld"\\."){print tld;tld=$NF}}print tld}' "${temp}" > "${source}"
-                if [ ${?} -eq 0 ]
-                then
-                    awk -F "." '{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "${source}" > "${temp}"
-                    if [ ${?} -eq 0 ]
-                    then
-                        sort "${temp}" > "${source}"
-                        if [ ${?} -eq 0 ]
-                        then
-                            cnt_tld="$(wc -l 2>/dev/null < "${source}")"
-                        else
-                            cat "${temp}" > "${source}"
-                        fi
-                    fi
-                else
-                    cat "${temp}" > "${source}"
-                fi
-            fi
-        else
-            cat "${temp}" > "${source}"
-        fi
-    fi
-    rm -f "${temp}"
-    f_log "debug" "f_tld  ::: source: ${source}, cnt: ${cnt:-"-"}, cnt_srt: ${cnt_srt:-"-"}, cnt_tld: ${cnt_tld:-"-"}"
+       local cnt cnt_srt cnt_tld source="${1}" temp="${1}.tld"
+
+       cnt="$(wc -l 2>/dev/null < "${source}")"
+       awk 'BEGIN{FS="."}{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "${source}" > "${temp}"
+       if [ ${?} -eq 0 ]
+       then
+               sort -u "${temp}" > "${source}"
+               if [ ${?} -eq 0 ]
+               then
+                       cnt_srt="$(wc -l 2>/dev/null < "${source}")"
+                       awk '{if(NR==1){tld=$NF};while(getline){if($NF!~tld"\\."){print tld;tld=$NF}}print tld}' "${source}" > "${temp}"
+                       if [ ${?} -eq 0 ]
+                       then
+                               awk 'BEGIN{FS="."}{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "${temp}" > "${source}"
+                               if [ ${?} -eq 0 ]
+                               then
+                                       cnt_tld="$(wc -l 2>/dev/null < "${source}")"
+                               else
+                                       mv -f "${temp}" > "${source}"
+                               fi
+                       fi
+               else
+                       mv -f "${temp}" "${source}"
+               fi
+       fi
+       f_log "debug" "f_tld  ::: source: ${source}, cnt: ${cnt:-"-"}, cnt_srt: ${cnt_srt:-"-"}, cnt_tld: ${cnt_tld:-"-"}"
 }
 
 # blocklist hash compare
 #
 f_hash()
 {
-    local hash hash_rc=1
-
-    if [ -x "${adb_hashutil}" ] && [ -f "${adb_dnsdir}/${adb_dnsfile}" ]
-    then
-        hash="$(${adb_hashutil} "${adb_dnsdir}/${adb_dnsfile}" 2>/dev/null | awk '{print $1}')"
-        if [ -z "${adb_hashold}" ] && [ -n "${hash}" ]
-        then
-            adb_hashold="${hash}"
-        elif [ -z "${adb_hashnew}" ] && [ -n "${hash}" ]
-        then
-            adb_hashnew="${hash}"
-        fi
-        if [ -n "${adb_hashold}" ] && [ -n "${adb_hashnew}" ]
-        then
-            if [ "${adb_hashold}" = "${adb_hashnew}" ]
-            then
-                hash_rc=0
-            fi
-            adb_hashold=""
-            adb_hashnew=""
-        fi
-    fi
-    f_log "debug" "f_hash ::: hash_util: ${adb_hashutil}, hash: ${hash}, out_rc: ${hash_rc}"
-    return ${hash_rc}
+       local hash hash_rc=1
+
+       if [ -x "${adb_hashutil}" ] && [ -f "${adb_dnsdir}/${adb_dnsfile}" ]
+       then
+               hash="$(${adb_hashutil} "${adb_dnsdir}/${adb_dnsfile}" 2>/dev/null | awk '{print $1}')"
+               if [ -z "${adb_hashold}" ] && [ -n "${hash}" ]
+               then
+                       adb_hashold="${hash}"
+               elif [ -z "${adb_hashnew}" ] && [ -n "${hash}" ]
+               then
+                       adb_hashnew="${hash}"
+               fi
+               if [ -n "${adb_hashold}" ] && [ -n "${adb_hashnew}" ]
+               then
+                       if [ "${adb_hashold}" = "${adb_hashnew}" ]
+                       then
+                               hash_rc=0
+                       fi
+                       adb_hashold=""
+                       adb_hashnew=""
+               fi
+       fi
+       f_log "debug" "f_hash ::: hash_util: ${adb_hashutil}, hash: ${hash}, out_rc: ${hash_rc}"
+       return ${hash_rc}
 }
 
 # suspend/resume adblock processing
 #
 f_switch()
 {
-    local mode="${1}"
-
-    if [ ! -s "${adb_dnsdir}/.${adb_dnsfile}" ] && [ "${mode}" = "suspend" ]
-    then
-        f_hash
-        cat "${adb_dnsdir}/${adb_dnsfile}" > "${adb_dnsdir}/.${adb_dnsfile}"
-        printf '%s\n' "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}"
-        f_hash
-    elif [ -s "${adb_dnsdir}/.${adb_dnsfile}" ] && [ "${mode}" = "resume" ]
-    then
-        f_hash
-        cat "${adb_dnsdir}/.${adb_dnsfile}" > "${adb_dnsdir}/${adb_dnsfile}"
-        > "${adb_dnsdir}/.${adb_dnsfile}"
-        f_hash
-    fi
-    if [ ${?} -eq 1 ]
-    then
-        f_temp
-        f_dnsup
-        f_jsnup "${mode}"
-        f_log "info" "${mode} adblock processing"
-        f_rmtemp
-        exit 0
-    fi
+       local mode="${1}"
+
+       if [ ! -s "${adb_dnsdir}/.${adb_dnsfile}" ] && [ "${mode}" = "suspend" ]
+       then
+               f_hash
+               cat "${adb_dnsdir}/${adb_dnsfile}" > "${adb_dnsdir}/.${adb_dnsfile}"
+               printf '%s\n' "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}"
+               f_hash
+       elif [ -s "${adb_dnsdir}/.${adb_dnsfile}" ] && [ "${mode}" = "resume" ]
+       then
+               f_hash
+               cat "${adb_dnsdir}/.${adb_dnsfile}" > "${adb_dnsdir}/${adb_dnsfile}"
+               > "${adb_dnsdir}/.${adb_dnsfile}"
+               f_hash
+       fi
+       if [ ${?} -eq 1 ]
+       then
+               f_temp
+               f_dnsup
+               f_jsnup "${mode}"
+               f_log "info" "${mode} adblock processing"
+               f_rmtemp
+               exit 0
+       fi
 }
 
 # query blocklist for certain (sub-)domains
 #
 f_query()
 {
-    local search result prefix suffix field domain="${1}" tld="${1#*.}"
-
-    if [ -z "${domain}" ] || [ "${domain}" = "${tld}" ]
-    then
-        printf '%s\n' "::: invalid domain input, please submit a single domain, e.g. 'doubleclick.net'"
-    else
-        case "${adb_dns}" in
-            dnsmasq)
-                prefix=".*[\/\.]"
-                suffix="(\/)"
-                field=2
-            ;;
-            unbound)
-                prefix=".*[\"\.]"
-                suffix="(static)"
-                field=3
-            ;;
-            named)
-                prefix="[^\*].*[\.]"
-                suffix="( \.)"
-                field=1
-            ;;
-            kresd)
-                prefix="[^\*].*[\.]"
-                suffix="( \.)"
-                field=1
-            ;;
-            dnscrypt-proxy)
-                prefix=".*[\.]"
-                suffix=""
-                field=1
-            ;;
-        esac
-        while [ "${domain}" != "${tld}" ]
-        do
-            search="${domain//./\.}"
-            result="$(awk -F '/|\"| ' "/^($search|${prefix}+${search}.*${suffix}$)/{i++;{printf(\"  + %s\n\",\$${field})};if(i>9){printf(\"  + %s\n\",\"[...]\");exit}}" "${adb_dnsdir}/${adb_dnsfile}")"
-            printf '%s\n' "::: results for domain '${domain}'"
-            printf '%s\n' "${result:-"  - no match"}"
-            domain="${tld}"
-            tld="${domain#*.}"
-        done
-    fi
+       local search result prefix suffix field domain="${1}" tld="${1#*.}"
+
+       if [ -z "${domain}" ] || [ "${domain}" = "${tld}" ]
+       then
+               printf '%s\n' "::: invalid domain input, please submit a single domain, e.g. 'doubleclick.net'"
+       else
+               case "${adb_dns}" in
+                       dnsmasq)
+                               prefix=".*[\/\.]"
+                               suffix="(\/)"
+                               field=2
+                       ;;
+                       unbound)
+                               prefix=".*[\"\.]"
+                               suffix="(static)"
+                               field=3
+                       ;;
+                       named)
+                               prefix="[^\*].*[\.]"
+                               suffix="( \.)"
+                               field=1
+                       ;;
+                       kresd)
+                               prefix="[^\*].*[\.]"
+                               suffix="( \.)"
+                               field=1
+                       ;;
+                       dnscrypt-proxy)
+                               prefix=".*[\.]"
+                               suffix=""
+                               field=1
+                       ;;
+               esac
+               while [ "${domain}" != "${tld}" ]
+               do
+                       search="${domain//./\.}"
+                       result="$(awk -F '/|\"| ' "/^($search|${prefix}+${search}.*${suffix}$)/{i++;{printf(\"  + %s\n\",\$${field})};if(i>9){printf(\"  + %s\n\",\"[...]\");exit}}" "${adb_dnsdir}/${adb_dnsfile}")"
+                       printf '%s\n' "::: results for domain '${domain}'"
+                       printf '%s\n' "${result:-"  - no match"}"
+                       domain="${tld}"
+                       tld="${domain#*.}"
+               done
+       fi
 }
 
 # update runtime information
 #
 f_jsnup()
 {
-    local bg_pid rundate status="${1:-"enabled"}" mode="normal mode" no_mail=0
-
-    if [ ${adb_rc} -gt 0 ]
-    then
-        status="error"
-        rundate="$(/bin/date "+%d.%m.%Y %H:%M:%S")"
-    fi
-    if [ ${adb_enabled} -eq 0 ]
-    then
-        status="disabled"
-    fi
-    if [ "${status}" = "enabled" ]
-    then
-        rundate="$(/bin/date "+%d.%m.%Y %H:%M:%S")"
-    fi
-    if [ "${status}" = "suspend" ]
-    then
-        status="paused"
-    fi
-    if [ "${status}" = "resume" ]
-    then
-        no_mail=1
-        status="enabled"
-    fi
-    if [ ${adb_backup_mode} -eq 1 ]
-    then
-        mode="backup mode"
-    fi
-
-    if [ -s "${adb_rtfile}" ]
-    then
-        json_load "$(cat "${adb_rtfile}" 2>/dev/null)"
-        json_select data
-
-        if [ -z "${adb_fetchinfo}" ] && [ -s "${adb_rtfile}" ]
-        then
-            json_get_var adb_fetchinfo "fetch_utility"
-        fi
-        if [ -z "${rundate}" ]
-        then
-            json_get_var rundate "last_rundate"
-        fi
-        if [ -z "${adb_cnt}" ]
-        then
-            json_get_var adb_cnt "overall_domains"
-            adb_cnt="${adb_cnt%% *}"
-        fi
-    fi
-
-    json_init
-    json_add_object "data"
-    json_add_string "adblock_status" "${status}"
-    json_add_string "adblock_version" "${adb_ver}"
-    json_add_string "overall_domains" "${adb_cnt:-0} (${mode})"
-    json_add_string "fetch_utility" "${adb_fetchinfo:-"-"}"
-    json_add_string "dns_backend" "${adb_dns} (${adb_dnsdir})"
-    json_add_string "last_rundate" "${rundate:-"-"}"
-    json_add_string "system_release" "${adb_sysver}"
-    json_close_object
-    json_dump > "${adb_rtfile}"
-
-    if [ ${adb_notify} -eq 1 ] && [ ${no_mail} -eq 0 ] && [ -x /etc/adblock/adblock.notify ] && \
-      ([ "${status}" = "error" ] || ([ "${status}" = "enabled" ] && [ ${adb_cnt} -le ${adb_notifycnt} ]))
-    then
-        (/etc/adblock/adblock.notify >/dev/null 2>&1) &
-        bg_pid=${!}
-    fi
-    f_log "debug" "f_jsnup::: status: ${status}, mode: ${mode}, cnt: ${adb_cnt}, notify: ${adb_notify}, notify_cnt: ${adb_notifycnt}, notify_pid: ${bg_pid:-"-"}"
+       local run_time bg_pid status="${1:-"enabled"}" mode="normal mode" no_mail=0
+
+       if [ ${adb_rc} -gt 0 ]
+       then
+               status="error"
+               run_time="$(/bin/date "+%d.%m.%Y %H:%M:%S")"
+       fi
+       if [ "${status}" = "enabled" ]
+       then
+               run_time="$(/bin/date "+%d.%m.%Y %H:%M:%S")"
+       fi
+       if [ "${status}" = "suspend" ]
+       then
+               status="paused"
+       fi
+       if [ "${status}" = "resume" ]
+       then
+               no_mail=1
+               status="enabled"
+       fi
+       if [ ${adb_backup_mode} -eq 1 ]
+       then
+               mode="backup mode"
+       fi
+
+       if [ -z "${adb_fetchinfo}" ]
+       then
+               json_get_var adb_fetchinfo "fetch_utility"
+       fi
+       if [ -z "${adb_cnt}" ]
+       then
+               json_get_var adb_cnt "overall_domains"
+               adb_cnt="${adb_cnt%% *}"
+       fi
+       if [ -z "${run_time}" ]
+       then
+               json_get_var run_time "last_rundate"
+       fi
+       json_add_string "adblock_status" "${status}"
+       json_add_string "adblock_version" "${adb_ver}"
+       json_add_string "overall_domains" "${adb_cnt:-0} (${mode})"
+       json_add_string "fetch_utility" "${adb_fetchinfo:-"-"}"
+       json_add_string "dns_backend" "${adb_dns} (${adb_dnsdir})"
+       json_add_string "last_rundate" "${run_time:-"-"}"
+       json_add_string "system_release" "${adb_sysver}"
+       json_dump > "${adb_rtfile}"
+
+       if [ ${adb_notify} -eq 1 ] && [ ${no_mail} -eq 0 ] && [ -x /etc/adblock/adblock.notify ] && \
+               ([ "${status}" = "error" ] || ([ "${status}" = "enabled" ] && [ ${adb_cnt} -le ${adb_notifycnt} ]))
+       then
+               (/etc/adblock/adblock.notify >/dev/null 2>&1) &
+               bg_pid=${!}
+       fi
+       f_log "debug" "f_jsnup::: status: ${status}, mode: ${mode}, cnt: ${adb_cnt}, notify: ${adb_notify}, notify_cnt: ${adb_notifycnt}, notify_pid: ${bg_pid:-"-"}"
 }
 
 # write to syslog
 #
 f_log()
 {
-    local class="${1}" log_msg="${2}"
-
-    if [ -n "${log_msg}" ] && ([ "${class}" != "debug" ] || [ ${adb_debug} -eq 1 ])
-    then
-        logger -p "${class}" -t "adblock-[${adb_ver}]" "${log_msg}"
-        if [ "${class}" = "err" ]
-        then
-            f_rmdns
-            f_jsnup
-            logger -p "${class}" -t "adblock-[${adb_ver}]" "Please also check 'https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md'"
-            exit 1
-        fi
-    fi
+       local class="${1}" log_msg="${2}"
+
+       if [ -n "${log_msg}" ] && ([ "${class}" != "debug" ] || [ ${adb_debug} -eq 1 ])
+       then
+               logger -p "${class}" -t "adblock-${adb_ver}[${$}]" "${log_msg}"
+               if [ "${class}" = "err" ]
+               then
+                       f_rmdns
+                       f_jsnup
+                       logger -p "${class}" -t "adblock-${adb_ver}[${$}]" "Please also check 'https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md'"
+                       exit 1
+               fi
+       fi
 }
 
 # main function for blocklist processing
 #
 f_main()
 {
-    local tmp_load tmp_file src_name src_rset src_url src_log src_arc src_cat cat list entry suffix mem_total mem_free enabled cnt=1
-
-    mem_total="$(awk '/^MemTotal/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null)"
-    mem_free="$(awk '/^MemFree/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null)"
-    tmp_load="${adb_tmpload}"
-    tmp_file="${adb_tmpfile}"
-    > "${adb_dnsdir}/.${adb_dnsfile}"
-    > "${adb_tmpdir}/tmp.raw_whitelist"
-    > "${adb_tmpdir}/tmp.add_whitelist"
-    > "${adb_tmpdir}/tmp.rem_whitelist"
-    f_log "debug" "f_main ::: dns: ${adb_dns}, fetch_util: ${adb_fetchinfo}, backup: ${adb_backup}, backup_mode: ${adb_backup_mode}, dns_jail: ${adb_jail}, force_srt: ${adb_forcesrt}, force_dns: ${adb_forcedns}, mem_total: ${mem_total:-0}, mem_free: ${mem_free:-0}, max_queue: ${adb_maxqueue}"
-
-    # prepare whitelist entries
-    #
-    if [ -s "${adb_whitelist}" ]
-    then
-        adb_whitelist_rset="/^([^([:space:]|\#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}"
-        awk "${adb_whitelist_rset}" "${adb_whitelist}" > "${adb_tmpdir}/tmp.raw_whitelist"
-        f_tld "${adb_tmpdir}/tmp.raw_whitelist"
-
-        adb_whitelist_rset="/^([^([:space:]|\#|\*|\/).]+\.)+[[:alpha:]]+([[:space:]]|$)/{gsub(\"\\\.\",\"\\\.\",\$1);print tolower(\"^\"\$1\"\\\|\\\.\"\$1)}"
-        awk "${adb_whitelist_rset}" "${adb_tmpdir}/tmp.raw_whitelist" > "${adb_tmpdir}/tmp.rem_whitelist"
-
-        if [ -n "${adb_dnsallow}" ]
-        then
-            eval "${adb_dnsallow}" "${adb_tmpdir}/tmp.raw_whitelist" > "${adb_tmpdir}/tmp.add_whitelist"
-        fi
-    fi
-
-    # build 'dnsjail' list
-    #
-    if [ ${adb_jail} -eq 1 ]
-    then
-        cat "${adb_tmpdir}/tmp.add_whitelist" > "/tmp/${adb_dnsjail}"
-        printf '%s\n' "${adb_dnshalt}" >> "/tmp/${adb_dnsjail}"
-        if [ -n "${adb_dnsheader}" ]
-        then
-            printf '%s\n' "${adb_dnsheader}" | cat - "/tmp/${adb_dnsjail}" > "${adb_tmpdir}/tmp.dnsjail"
-            cat "${adb_tmpdir}/tmp.dnsjail" > "/tmp/${adb_dnsjail}"
-        fi
-    fi
-
-    # main loop
-    #
-    for src_name in ${adb_sources}
-    do
-        enabled="$(eval printf '%s' \"\${enabled_${src_name}\}\")"
-        src_url="$(eval printf '%s' \"\${adb_src_${src_name}\}\")"
-        src_rset="$(eval printf '%s' \"\${adb_src_rset_${src_name}\}\")"
-        src_cat="$(eval printf '%s' \"\${adb_src_cat_${src_name}\}\")"
-        adb_tmpload="${tmp_load}.${src_name}"
-        adb_tmpfile="${tmp_file}.${src_name}"
-
-        # basic pre-checks
-        #
-        f_log "debug" "f_main ::: name: ${src_name}, enabled: ${enabled}"
-        if [ "${enabled}" != "1" ] || [ -z "${src_url}" ] || [ -z "${src_rset}" ]
-        then
-            f_list remove
-            continue
-        fi
-
-        # backup mode
-        #
-        if [ ${adb_backup_mode} -eq 1 ] && [ "${adb_action}" = "start" ] && [ "${src_name}" != "blacklist" ]
-        then
-            f_list restore
-            if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ]
-            then
-                if ([ ${mem_total} -lt 64 ] || [ ${mem_free} -lt 40 ]) && [ ${adb_forcesrt} -eq 0 ]
-                then
-                    f_tld "${adb_tmpfile}"
-                fi
-                continue
-            fi
-        fi
-
-        # download queue processing
-        #
-        if [ "${src_name}" = "blacklist" ]
-        then
-            if [ -s "${src_url}" ]
-            then
-                (
-                  src_log="$(cat "${src_url}" > "${adb_tmpload}" 2>&1)"
-                  adb_rc=${?}
-                  if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpload}" ]
-                  then
-                      awk "${src_rset}" "${adb_tmpload}" 2>/dev/null > "${adb_tmpfile}"
-                      adb_rc=${?}
-                      if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ]
-                      then
-                          rm -f "${adb_tmpload}"
-                          f_list download
-                          if ([ ${mem_total} -lt 64 ] || [ ${mem_free} -lt 40 ]) && [ ${adb_forcesrt} -eq 0 ]
-                          then
-                              f_tld "${adb_tmpfile}"
-                          fi
-                      fi
-                  else
-                      src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')"
-                      f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${adb_rc}, log: ${src_log:-"-"}"
-                  fi
-                ) &
-            else
-                continue
-            fi
-        elif [ -n "${src_cat}" ]
-        then
-            (
-              src_arc="${adb_tmpdir}/${src_url##*/}"
-              src_log="$("${adb_fetchutil}" ${adb_fetchparm} "${src_arc}" "${src_url}" 2>&1)"
-              adb_rc=${?}
-              if [ ${adb_rc} -eq 0 ] && [ -s "${src_arc}" ]
-              then
-                  list="$(tar -tzf "${src_arc}")"
-                  suffix="$(eval printf '%s' \"\${adb_src_suffix_${src_name}:-\"domains\"\}\")"
-                  for cat in ${src_cat}
-                  do
-                      entry="$(printf '%s' "${list}" | grep -E "[\^/]+${cat}/${suffix}")"
-                      if [ -n "${entry}" ]
-                      then
-                          tar -xOzf "${src_arc}" "${entry}" >> "${adb_tmpload}"
-                          adb_rc=${?}
-                          if [ ${adb_rc} -ne 0 ]
-                          then
-                              break
-                          fi
-                      fi
-                  done
-              else
-                  src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')"
-                  f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${adb_rc}, log: ${src_log:-"-"}"
-              fi
-              if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpload}" ]
-              then
-                  rm -f "${src_arc}"
-                  awk "${src_rset}" "${adb_tmpload}" 2>/dev/null > "${adb_tmpfile}"
-                  adb_rc=${?}
-                  if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ]
-                  then
-                      rm -f "${adb_tmpload}"
-                      f_list download
-                      if [ ${adb_backup} -eq 1 ]
-                      then
-                          f_list backup
-                      fi
-                      if ([ ${mem_total} -lt 64 ] || [ ${mem_free} -lt 40 ]) && [ ${adb_forcesrt} -eq 0 ]
-                      then
-                          f_tld "${adb_tmpfile}"
-                      fi
-                  elif [ ${adb_backup} -eq 1 ]
-                  then
-                      f_list restore
-                  fi
-              elif [ ${adb_backup} -eq 1 ]
-              then
-                  f_list restore
-              fi
-            ) &
-        else
-            (
-              src_log="$("${adb_fetchutil}" ${adb_fetchparm} "${adb_tmpload}" "${src_url}" 2>&1)"
-              adb_rc=${?}
-              if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpload}" ]
-              then
-                  awk "${src_rset}" "${adb_tmpload}" 2>/dev/null > "${adb_tmpfile}"
-                  adb_rc=${?}
-                  if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ]
-                  then
-                      rm -f "${adb_tmpload}"
-                      f_list download
-                      if [ ${adb_backup} -eq 1 ]
-                      then
-                          f_list backup
-                      fi
-                      if ([ ${mem_total} -lt 64 ] || [ ${mem_free} -lt 40 ]) && [ ${adb_forcesrt} -eq 0 ]
-                      then
-                          f_tld "${adb_tmpfile}"
-                      fi
-                  elif [ ${adb_backup} -eq 1 ]
-                  then
-                      f_list restore
-                  fi
-              else
-                  src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')"
-                  f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${adb_rc}, log: ${src_log:-"-"}"
-                  if [ ${adb_backup} -eq 1 ]
-                  then
-                      f_list restore
-                  fi
-              fi
-            ) &
-        fi
-        hold=$(( cnt % adb_maxqueue ))
-        if [ ${hold} -eq 0 ]
-        then
-            wait
-        fi
-        cnt=$(( cnt + 1 ))
-    done
-
-    # list merge
-    #
-    wait
-    src_name="overall"
-    adb_tmpfile="${tmp_file}"
-    f_list merge
-
-    # overall sort and conditional dns restart
-    #
-    f_hash
-    if [ -s "${adb_tmpdir}/${adb_dnsfile}" ]
-    then
-        if ([ ${mem_total} -ge 64 ] && [ ${mem_free} -ge 40 ]) || [ ${adb_forcesrt} -eq 1 ]
-        then
-            f_tld "${adb_tmpdir}/${adb_dnsfile}"
-        fi
-        f_list final
-    else
-        > "${adb_dnsdir}/${adb_dnsfile}"
-    fi
-    chown "${adb_dnsuser}" "${adb_dnsdir}/${adb_dnsfile}" 2>/dev/null
-    f_hash
-    if [ ${?} -eq 1 ]
-    then
-        f_dnsup
-    fi
-    f_jsnup
-    if [ ${?} -eq 0 ]
-    then
-        f_log "info" "blocklist with overall ${adb_cnt} domains loaded successfully (${adb_sysver})"
-    else
-        f_log "err" "dns backend restart with active blocklist failed"
-    fi
-    f_rmtemp
-    exit ${adb_rc}
+       local tmp_load tmp_file src_name src_rset src_url src_log src_arc src_cat cat list entry suffix mem_total mem_free enabled cnt=1
+
+       mem_total="$(awk '/^MemTotal/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null)"
+       mem_free="$(awk '/^MemFree/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null)"
+       tmp_load="${adb_tmpload}"
+       tmp_file="${adb_tmpfile}"
+       > "${adb_dnsdir}/.${adb_dnsfile}"
+       > "${adb_tmpdir}/tmp.raw_whitelist"
+       > "${adb_tmpdir}/tmp.add_whitelist"
+       > "${adb_tmpdir}/tmp.rem_whitelist"
+       f_log "debug" "f_main ::: dns: ${adb_dns}, fetch_util: ${adb_fetchinfo}, backup: ${adb_backup}, backup_mode: ${adb_backup_mode}, dns_jail: ${adb_jail}, force_srt: ${adb_forcesrt}, force_dns: ${adb_forcedns}, mem_total: ${mem_total:-0}, mem_free: ${mem_free:-0}, max_queue: ${adb_maxqueue}"
+
+       # prepare whitelist entries
+       #
+       if [ -s "${adb_whitelist}" ]
+       then
+               adb_whitelist_rset="/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}"
+               awk "${adb_whitelist_rset}" "${adb_whitelist}" > "${adb_tmpdir}/tmp.raw_whitelist"
+               f_tld "${adb_tmpdir}/tmp.raw_whitelist"
+
+               adb_whitelist_rset="/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{gsub(\"\\\.\",\"\\\.\",\$1);print tolower(\"^\"\$1\"\\\|\\\.\"\$1)}"
+               awk "${adb_whitelist_rset}" "${adb_tmpdir}/tmp.raw_whitelist" > "${adb_tmpdir}/tmp.rem_whitelist"
+
+               if [ -n "${adb_dnsallow}" ]
+               then
+                       eval "${adb_dnsallow}" "${adb_tmpdir}/tmp.raw_whitelist" > "${adb_tmpdir}/tmp.add_whitelist"
+               fi
+       fi
+
+       # build 'dnsjail' list
+       #
+       if [ ${adb_jail} -eq 1 ]
+       then
+               cat "${adb_tmpdir}/tmp.add_whitelist" > "/tmp/${adb_dnsjail}"
+               printf '%s\n' "${adb_dnshalt}" >> "/tmp/${adb_dnsjail}"
+               if [ -n "${adb_dnsheader}" ]
+               then
+                       printf '%s\n' "${adb_dnsheader}" | cat - "/tmp/${adb_dnsjail}" > "${adb_tmpdir}/tmp.dnsjail"
+                       cat "${adb_tmpdir}/tmp.dnsjail" > "/tmp/${adb_dnsjail}"
+               fi
+       fi
+
+       # main loop
+       #
+       for src_name in ${adb_sources}
+       do
+               enabled="$(eval printf '%s' \"\${enabled_${src_name}\}\")"
+               src_url="$(eval printf '%s' \"\${adb_src_${src_name}\}\")"
+               src_rset="$(eval printf '%s' \"\${adb_src_rset_${src_name}\}\")"
+               src_cat="$(eval printf '%s' \"\${adb_src_cat_${src_name}\}\")"
+               adb_tmpload="${tmp_load}.${src_name}"
+               adb_tmpfile="${tmp_file}.${src_name}"
+
+               # basic pre-checks
+               #
+               f_log "debug" "f_main ::: name: ${src_name}, enabled: ${enabled}"
+               if [ "${enabled}" != "1" ] || [ -z "${src_url}" ] || [ -z "${src_rset}" ]
+               then
+                       f_list remove
+                       continue
+               fi
+
+               # backup mode
+               #
+               if [ ${adb_backup_mode} -eq 1 ] && [ "${adb_action}" = "start" ] && [ "${src_name}" != "blacklist" ]
+               then
+                       f_list restore
+                       if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ]
+                       then
+                               if ([ ${mem_total} -lt 64 ] || [ ${mem_free} -lt 40 ]) && [ ${adb_forcesrt} -eq 0 ]
+                               then
+                                       f_tld "${adb_tmpfile}"
+                               fi
+                               continue
+                       fi
+               fi
+
+               # download queue processing
+               #
+               if [ "${src_name}" = "blacklist" ]
+               then
+                       if [ -s "${src_url}" ]
+                       then
+                               (
+                                       src_log="$(cat "${src_url}" > "${adb_tmpload}" 2>&1)"
+                                       adb_rc=${?}
+                                       if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpload}" ]
+                                       then
+                                               awk "${src_rset}" "${adb_tmpload}" 2>/dev/null > "${adb_tmpfile}"
+                                               adb_rc=${?}
+                                               if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ]
+                                               then
+                                                       rm -f "${adb_tmpload}"
+                                                       f_list download
+                                                       if ([ ${mem_total} -lt 64 ] || [ ${mem_free} -lt 40 ]) && [ ${adb_forcesrt} -eq 0 ]
+                                                       then
+                                                               f_tld "${adb_tmpfile}"
+                                                       fi
+                                               fi
+                                       else
+                                               src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')"
+                                               f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${adb_rc}, log: ${src_log:-"-"}"
+                                       fi
+                               ) &
+                       else
+                               continue
+                       fi
+               elif [ -n "${src_cat}" ]
+               then
+                       (
+                               src_arc="${adb_tmpdir}/${src_url##*/}"
+                               src_log="$("${adb_fetchutil}" ${adb_fetchparm} "${src_arc}" "${src_url}" 2>&1)"
+                               adb_rc=${?}
+                               if [ ${adb_rc} -eq 0 ] && [ -s "${src_arc}" ]
+                               then
+                                       list="$(tar -tzf "${src_arc}")"
+                                       suffix="$(eval printf '%s' \"\${adb_src_suffix_${src_name}:-\"domains\"\}\")"
+                                       for cat in ${src_cat}
+                                       do
+                                               entry="$(printf '%s' "${list}" | grep -E "[\^/]+${cat}/${suffix}")"
+                                               if [ -n "${entry}" ]
+                                               then
+                                                       tar -xOzf "${src_arc}" "${entry}" >> "${adb_tmpload}"
+                                                       adb_rc=${?}
+                                                       if [ ${adb_rc} -ne 0 ]
+                                                       then
+                                                               break
+                                                       fi
+                                               fi
+                                       done
+                               else
+                                       src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')"
+                                       f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${adb_rc}, log: ${src_log:-"-"}"
+                               fi
+                               if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpload}" ]
+                               then
+                                       rm -f "${src_arc}"
+                                       awk "${src_rset}" "${adb_tmpload}" 2>/dev/null > "${adb_tmpfile}"
+                                       adb_rc=${?}
+                                       if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ]
+                                       then
+                                               rm -f "${adb_tmpload}"
+                                               f_list download
+                                               if [ ${adb_backup} -eq 1 ]
+                                               then
+                                                       f_list backup
+                                               fi
+                                               if ([ ${mem_total} -lt 64 ] || [ ${mem_free} -lt 40 ]) && [ ${adb_forcesrt} -eq 0 ]
+                                               then
+                                                       f_tld "${adb_tmpfile}"
+                                               fi
+                                       elif [ ${adb_backup} -eq 1 ]
+                                       then
+                                               f_list restore
+                                       fi
+                               elif [ ${adb_backup} -eq 1 ]
+                               then
+                                       f_list restore
+                               fi
+                       ) &
+               else
+                       (
+                               src_log="$("${adb_fetchutil}" ${adb_fetchparm} "${adb_tmpload}" "${src_url}" 2>&1)"
+                               adb_rc=${?}
+                               if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpload}" ]
+                               then
+                                       awk "${src_rset}" "${adb_tmpload}" 2>/dev/null > "${adb_tmpfile}"
+                                       adb_rc=${?}
+                                       if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ]
+                                       then
+                                               rm -f "${adb_tmpload}"
+                                               f_list download
+                                               if [ ${adb_backup} -eq 1 ]
+                                               then
+                                                       f_list backup
+                                               fi
+                                               if ([ ${mem_total} -lt 64 ] || [ ${mem_free} -lt 40 ]) && [ ${adb_forcesrt} -eq 0 ]
+                                               then
+                                                       f_tld "${adb_tmpfile}"
+                                               fi
+                                       elif [ ${adb_backup} -eq 1 ]
+                                       then
+                                               f_list restore
+                                       fi
+                               else
+                                       src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')"
+                                       f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${adb_rc}, log: ${src_log:-"-"}"
+                                       if [ ${adb_backup} -eq 1 ]
+                                       then
+                                               f_list restore
+                                       fi
+                               fi
+                       ) &
+               fi
+               hold=$(( cnt % adb_maxqueue ))
+               if [ ${hold} -eq 0 ]
+               then
+                       wait
+               fi
+               cnt=$(( cnt + 1 ))
+       done
+
+       # list merge
+       #
+       wait
+       src_name="overall"
+       adb_tmpfile="${tmp_file}"
+       f_list merge
+
+       # overall sort and conditional dns restart
+       #
+       f_hash
+       if [ -s "${adb_tmpdir}/${adb_dnsfile}" ]
+       then
+               if ([ ${mem_total} -ge 64 ] && [ ${mem_free} -ge 40 ]) || [ ${adb_forcesrt} -eq 1 ]
+               then
+                       f_tld "${adb_tmpdir}/${adb_dnsfile}"
+               fi
+               f_list final
+       else
+               > "${adb_dnsdir}/${adb_dnsfile}"
+       fi
+       chown "${adb_dnsuser}" "${adb_dnsdir}/${adb_dnsfile}" 2>/dev/null
+       f_hash
+       if [ ${?} -eq 1 ]
+       then
+               f_dnsup
+       fi
+       f_jsnup
+       if [ ${?} -eq 0 ]
+       then
+               f_log "info" "blocklist with overall ${adb_cnt} domains loaded successfully (${adb_sysver})"
+       else
+               f_log "err" "dns backend restart with active blocklist failed"
+       fi
+       f_rmtemp
+       exit ${adb_rc}
 }
 
+# source required system libraries
+#
+if [ -r "/lib/functions.sh" ] && [ -r "/usr/share/libubox/jshn.sh" ]
+then
+       . "/lib/functions.sh"
+       . "/usr/share/libubox/jshn.sh"
+else
+       f_log "err" "system libraries not found"
+fi
+
+# initialize json runtime file
+#
+json_load_file "${adb_rtfile}" >/dev/null 2>&1
+json_select data >/dev/null 2>&1
+if [ ${?} -ne 0 ]
+then
+       > "${adb_rtfile}"
+       json_init
+       json_add_object "data"
+fi
+
 # handle different adblock actions
 #
 f_envload
 case "${adb_action}" in
-    stop)
-        f_rmdns
-    ;;
-    restart)
-        f_rmdns
-        f_envcheck
-        f_main
-    ;;
-    suspend)
-        f_switch suspend
-    ;;
-    resume)
-        f_switch resume
-    ;;
-    query)
-        f_query "${2}"
-    ;;
-    start|reload)
-        f_envcheck
-        f_main
-    ;;
+       stop)
+               f_rmdns
+       ;;
+       restart)
+               f_rmdns
+               f_envcheck
+               f_main
+       ;;
+       suspend)
+               f_switch suspend
+       ;;
+       resume)
+               f_switch resume
+       ;;
+       query)
+               f_query "${2}"
+       ;;
+       start|reload)
+               f_envcheck
+               f_main
+       ;;
 esac