2018-07-17 00:43:16 +00:00
-- Copyright 2016-2018 Stan Grishin <stangri@melmac.net>
-- Licensed to the public under the Apache License 2.0.
2019-08-17 13:15:10 +00:00
local readmeURL = " https://github.com/openwrt/packages/tree/master/net/simple-adblock/files/README.md "
-- local readmeURL = "https://github.com/stangri/openwrt_packages/tree/master/simple-adblock/files/README.md"
2018-07-17 00:43:16 +00:00
local packageName = " simple-adblock "
local uci = require " luci.model.uci " . cursor ( )
local util = require " luci.util "
2019-07-05 15:30:48 +00:00
local sys = require " luci.sys "
local jsonc = require " luci.jsonc "
local fs = require " nixio.fs "
2020-03-29 05:22:21 +00:00
local nutil = require " nixio.util "
2019-07-05 15:30:48 +00:00
local http = require " luci.http "
local dispatcher = require " luci.dispatcher "
2020-05-27 00:38:18 +00:00
function getPackageVersion ( )
local opkgFile = " /usr/lib/opkg/status "
local line
local flag = false
for line in io.lines ( opkgFile ) do
if flag then
return line : match ( ' [%d%.$-]+ ' ) or " "
elseif line : find ( " Package: " .. packageName : gsub ( " %- " , " %%%- " ) ) then
flag = true
end
end
return " "
end
function getFileLines ( file )
local f = io.open ( file )
if f then
local t = f : read ( " *a " )
local _ , n = t : gsub ( " \n " , " " )
f : close ( )
return n
else
return " 0 "
end
end
function checkDnsmasq ( ) return fs.access ( " /usr/sbin/dnsmasq " ) end
function checkUnbound ( ) return fs.access ( " /usr/sbin/unbound " ) end
function checkIpset ( )
if fs.access ( " /usr/sbin/ipset " ) and sys.call ( " /usr/sbin/ipset help hash:net >/dev/null 2>&1 " ) == 0 then
return true
else
return false
end
end
function checkDnsmasqIpset ( )
if checkDnsmasq ( ) then
local o = util.trim ( util.exec ( " /usr/sbin/dnsmasq -v 2>/dev/null " ) )
if not o : match ( " no%-ipset " ) and o : match ( " ipset " ) and checkIpset ( ) then
return true
else
return false
end
else
return false
end
end
2018-07-17 00:43:16 +00:00
local enabledFlag = uci : get ( packageName , " config " , " enabled " )
2019-08-17 13:15:10 +00:00
local command , outputFile , outputCache , outputGzip
local targetDNS = uci : get ( packageName , " config " , " dns " )
if not targetDNS or targetDNS == " " then
targetDNS = " dnsmasq.servers "
end
if targetDNS ~= " dnsmasq.addnhosts " and targetDNS ~= " dnsmasq.conf " and
2019-09-24 16:16:52 +00:00
targetDNS ~= " dnsmasq.ipset " and targetDNS ~= " dnsmasq.servers " and
targetDNS ~= " unbound.adb_list " then
2019-08-17 13:15:10 +00:00
targetDNS = " dnsmasq.servers "
end
if targetDNS == " dnsmasq.addnhosts " then
outputFile = " /var/run/ " .. packageName .. " .addnhosts "
outputCache = " /var/run/ " .. packageName .. " .addnhosts.cache "
outputGzip = " /etc/ " .. packageName .. " .addnhosts.gz "
elseif targetDNS == " dnsmasq.conf " then
outputFile = " /var/dnsmasq.d/ " .. packageName .. " "
outputCache = " /var/run/ " .. packageName .. " .dnsmasq.cache "
outputGzip = " /etc/ " .. packageName .. " .dnsmasq.gz "
elseif targetDNS == " dnsmasq.servers " then
outputFile = " /var/run/ " .. packageName .. " .servers "
outputCache = " /var/run/ " .. packageName .. " .servers.cache "
outputGzip = " /etc/ " .. packageName .. " .servers.gz "
elseif targetDNS == " unbound.adb_list " then
outputFile = " /var/lib/unbound/adb_list. " .. packageName .. " "
outputCache = " /var/run/ " .. packageName .. " .unbound.cache "
outputGzip = " /etc/ " .. packageName .. " .unbound.gz "
end
2019-07-05 15:30:48 +00:00
2020-05-27 00:38:18 +00:00
local packageVersion = getPackageVersion ( )
local tmpfs , tmpfsMessage , tmpfsError , tmpfsStats , tmpfsStatus
if packageVersion == " " then
tmpfsStatus = " statusNoInstall "
else
tmpfsStatus = " statusStopped "
end
2019-07-05 15:30:48 +00:00
if fs.access ( " /var/run/ " .. packageName .. " .json " ) then
2020-05-27 00:38:18 +00:00
local f = io.open ( " /var/run/ " .. packageName .. " .json " )
local s = f : read ( " *a " )
f : close ( )
tmpfs = jsonc.parse ( s )
2019-07-05 15:30:48 +00:00
end
if tmpfs and tmpfs [ ' data ' ] then
if tmpfs [ ' data ' ] [ ' status ' ] and tmpfs [ ' data ' ] [ ' status ' ] ~= " " then
tmpfsStatus = tmpfs [ ' data ' ] [ ' status ' ]
end
if tmpfs [ ' data ' ] [ ' message ' ] and tmpfs [ ' data ' ] [ ' message ' ] ~= " " then
tmpfsMessage = tmpfs [ ' data ' ] [ ' message ' ]
end
if tmpfs [ ' data ' ] [ ' error ' ] and tmpfs [ ' data ' ] [ ' error ' ] ~= " " then
tmpfsError = tmpfs [ ' data ' ] [ ' error ' ]
end
if tmpfs [ ' data ' ] [ ' stats ' ] and tmpfs [ ' data ' ] [ ' stats ' ] ~= " " then
tmpfsStats = tmpfs [ ' data ' ] [ ' stats ' ]
end
2018-07-17 00:43:16 +00:00
end
2019-07-05 15:30:48 +00:00
2020-03-29 05:22:21 +00:00
local statusTable = { }
local errorTable = { }
2020-04-10 21:22:35 +00:00
statusTable [ " statusNoInstall " ] = translatef ( " %s is not installed or not found " , packageName )
2020-03-29 05:22:21 +00:00
statusTable [ " statusStopped " ] = translate ( " Stopped " )
statusTable [ " statusStarting " ] = translate ( " Starting " )
statusTable [ " statusRestarting " ] = translate ( " Restarting " )
statusTable [ " statusForceReloading " ] = translate ( " Force Reloading " )
statusTable [ " statusDownloading " ] = translate ( " Downloading " )
statusTable [ " statusError " ] = translate ( " Error " )
statusTable [ " statusWarning " ] = translate ( " Warning " )
statusTable [ " statusFail " ] = translate ( " Fail " )
statusTable [ " statusSuccess " ] = translate ( " Success " )
2020-04-10 21:22:35 +00:00
errorTable [ " errorOutputFileCreate " ] = translatef ( " failed to create '%s' file " , outputFile )
2020-03-29 05:22:21 +00:00
errorTable [ " errorFailDNSReload " ] = translate ( " failed to restart/reload DNS resolver " )
errorTable [ " errorSharedMemory " ] = translate ( " failed to access shared memory " )
errorTable [ " errorSorting " ] = translate ( " failed to sort data file " )
errorTable [ " errorOptimization " ] = translate ( " failed to optimize data file " )
errorTable [ " errorWhitelistProcessing " ] = translate ( " failed to process whitelist " )
errorTable [ " errorDataFileFormatting " ] = translate ( " failed to format data file " )
2020-04-10 21:22:35 +00:00
errorTable [ " errorMovingDataFile " ] = translatef ( " failed to move temporary data file to '%s' " , outputFile )
2020-03-29 05:22:21 +00:00
errorTable [ " errorCreatingCompressedCache " ] = translate ( " failed to create compressed cache " )
errorTable [ " errorRemovingTempFiles " ] = translate ( " failed to remove temporary files " )
errorTable [ " errorRestoreCompressedCache " ] = translate ( " failed to unpack compressed cache " )
2020-04-10 21:22:35 +00:00
errorTable [ " errorRestoreCache " ] = translatef ( " failed to move '%s' to '%s' " , outputCache , outputFile )
2020-03-29 05:22:21 +00:00
errorTable [ " errorOhSnap " ] = translate ( " failed to create blocklist or restart DNS resolver " )
2020-04-10 21:22:35 +00:00
errorTable [ " errorStopping " ] = translatef ( " failed to stop %s " , packageName )
2020-03-29 05:22:21 +00:00
errorTable [ " errorDNSReload " ] = translate ( " failed to reload/restart DNS resolver " )
errorTable [ " errorDownloadingList " ] = translate ( " failed to download " )
errorTable [ " errorParsingList " ] = translate ( " failed to parse " )
2020-05-27 00:38:18 +00:00
errorTable [ " errorNoSSLSupport " ] = translate ( " no HTTPS/SSL support on device " )
2020-03-29 05:22:21 +00:00
m = Map ( " simple-adblock " , translate ( " Simple AdBlock Settings " ) )
m.apply_on_parse = true
m.on_after_apply = function ( self )
2020-04-03 12:25:17 +00:00
sys.call ( " /etc/init.d/simple-adblock restart " )
2020-03-29 05:22:21 +00:00
end
2020-05-27 00:38:18 +00:00
h = m : section ( NamedSection , " config " , " simple-adblock " , translatef ( " Service Status [%s %s] " , packageName , packageVersion ) )
2019-07-05 15:30:48 +00:00
2020-03-29 05:22:21 +00:00
if tmpfsStatus == " statusStarting " or
tmpfsStatus == " statusRestarting " or
tmpfsStatus == " statusForceReloading " or
tmpfsStatus == " statusDownloading " then
2019-07-05 15:30:48 +00:00
ss = h : option ( DummyValue , " _dummy " , translate ( " Service Status " ) )
ss.template = " simple-adblock/status "
2020-03-29 05:22:21 +00:00
ss.value = statusTable [ tmpfsStatus ] .. ' ... '
2019-07-05 15:30:48 +00:00
if tmpfsMessage then
sm = h : option ( DummyValue , " _dummy " , translate ( " Task " ) )
sm.template = " simple-adblock/status "
sm.value = tmpfsMessage
end
2018-07-17 00:43:16 +00:00
else
2020-03-29 05:22:21 +00:00
if tmpfsStatus == " statusStopped " then
ss = h : option ( DummyValue , " _dummy " , translate ( " Service Status " ) )
ss.template = " simple-adblock/status "
ss.value = statusTable [ tmpfsStatus ]
2019-08-17 13:15:10 +00:00
if fs.access ( outputCache ) then
2019-07-05 15:30:48 +00:00
sm = h : option ( DummyValue , " _dummy " , translate ( " Info " ) )
sm.template = " simple-adblock/status "
2020-05-27 00:38:18 +00:00
sm.value = translatef ( " Cache file containing %s domains found. " , getFileLines ( outputCache ) )
2019-08-17 13:15:10 +00:00
elseif fs.access ( outputGzip ) then
2019-07-05 15:30:48 +00:00
sm = h : option ( DummyValue , " _dummy " , translate ( " Info " ) )
sm.template = " simple-adblock/status "
2020-04-10 21:22:35 +00:00
sm.value = translate ( " Compressed cache file found. " )
2018-07-17 00:43:16 +00:00
end
else
2019-07-05 15:30:48 +00:00
ss = h : option ( DummyValue , " _dummy " , translate ( " Service Status " ) )
ss.template = " simple-adblock/status "
2020-03-29 05:22:21 +00:00
if tmpfsStatus == " statusSuccess " then
2020-05-27 00:38:18 +00:00
ss.value = translatef ( " %s is blocking %s domains (with %s). " , packageVersion , getFileLines ( outputFile ) , targetDNS )
2020-03-29 05:22:21 +00:00
else
ss.value = statusTable [ tmpfsStatus ]
end
2019-07-05 15:30:48 +00:00
if tmpfsMessage then
ms = h : option ( DummyValue , " _dummy " , translate ( " Message " ) )
ms.template = " simple-adblock/status "
ms.value = tmpfsMessage
end
if tmpfsError then
es = h : option ( DummyValue , " _dummy " , translate ( " Collected Errors " ) )
2020-03-29 05:22:21 +00:00
es.template = " simple-adblock/error "
es.value = " "
local err , e , url
for err in tmpfsError : gmatch ( " [%p%w]+ " ) do
2020-05-27 00:38:18 +00:00
if err : match ( " | " ) then
e , url = err : match ( " (.+)|(.+) " )
2020-04-10 21:22:35 +00:00
es.value = translatef ( " %s Error: %s %s " , es.value , errorTable [ e ] , url ) .. " . \n "
2020-03-29 05:22:21 +00:00
else
2020-04-10 21:22:35 +00:00
es.value = translatef ( " %s Error: %s " , es.value , errorTable [ err ] ) .. " . \n "
2020-03-29 05:22:21 +00:00
end
2018-07-17 00:43:16 +00:00
end
end
end
2020-04-21 00:44:35 +00:00
if packageVersion ~= " " then
2020-04-03 12:25:17 +00:00
buttons = h : option ( DummyValue , " _dummy " )
buttons.template = packageName .. " /buttons "
end
2018-07-17 00:43:16 +00:00
end
s = m : section ( NamedSection , " config " , " simple-adblock " , translate ( " Configuration " ) )
-- General options
s : tab ( " basic " , translate ( " Basic Configuration " ) )
2020-03-29 05:22:21 +00:00
o2 = s : taboption ( " basic " , ListValue , " verbosity " , translate ( " Output Verbosity Setting " ) , translate ( " Controls system log and console output verbosity. " ) )
2018-07-17 00:43:16 +00:00
o2 : value ( " 0 " , translate ( " Suppress output " ) )
o2 : value ( " 1 " , translate ( " Some output " ) )
o2 : value ( " 2 " , translate ( " Verbose output " ) )
o2.default = 2
2019-08-17 13:15:10 +00:00
o3 = s : taboption ( " basic " , ListValue , " force_dns " , translate ( " Force Router DNS " ) , translate ( " Forces Router DNS use on local devices, also known as DNS Hijacking. " ) )
2018-07-17 00:43:16 +00:00
o3 : value ( " 0 " , translate ( " Let local devices use their own DNS servers if set " ) )
o3 : value ( " 1 " , translate ( " Force Router DNS server to all local devices " ) )
o3.default = 1
local sysfs_path = " /sys/class/leds/ "
local leds = { }
2020-03-29 05:22:21 +00:00
if fs.access ( sysfs_path ) then
leds = nutil.consume ( ( fs.dir ( sysfs_path ) ) )
2018-07-17 00:43:16 +00:00
end
if # leds ~= 0 then
2020-04-10 21:22:35 +00:00
o4 = s : taboption ( " basic " , Value , " led " , translate ( " LED to indicate status " ) ,
2020-05-02 16:00:39 +00:00
translatef ( " Pick the LED not already used in %sSystem LED Configuration%s. " , " <a href= \" " .. dispatcher.build_url ( " admin " , " system " , " leds " ) .. " \" > " , " </a> " ) )
2019-07-05 15:30:48 +00:00
o4.rmempty = false
o4 : value ( " " , translate ( " none " ) )
2018-07-17 00:43:16 +00:00
for k , v in ipairs ( leds ) do
2019-07-05 15:30:48 +00:00
o4 : value ( v )
2018-07-17 00:43:16 +00:00
end
end
s : tab ( " advanced " , translate ( " Advanced Configuration " ) )
2020-04-10 21:22:35 +00:00
local dns_descr = translatef ( " Pick the DNS resolution option to create the adblock list for, see the <a href= \" %s#dns-resolution-option \" target= \" _blank \" >README</a> for details. " , readmeURL )
2019-09-24 16:16:52 +00:00
2020-05-27 00:38:18 +00:00
if not checkDnsmasq ( ) then
2020-04-10 21:22:35 +00:00
dns_descr = dns_descr .. " <br /> " .. translatef ( " Please note that %s is not supported on this system. " , " <i>dnsmasq.addnhosts</i> " )
dns_descr = dns_descr .. " <br /> " .. translatef ( " Please note that %s is not supported on this system. " , " <i>dnsmasq.conf</i> " )
dns_descr = dns_descr .. " <br /> " .. translatef ( " Please note that %s is not supported on this system. " , " <i>dnsmasq.ipset</i> " )
dns_descr = dns_descr .. " <br /> " .. translatef ( " Please note that %s is not supported on this system. " , " <i>dnsmasq.servers</i> " )
2020-05-27 00:38:18 +00:00
elseif not checkDnsmasqIpset ( ) then
2020-04-10 21:22:35 +00:00
dns_descr = dns_descr .. " <br /> " .. translatef ( " Please note that %s is not supported on this system. " , " <i>dnsmasq.ipset</i> " )
2019-09-24 16:16:52 +00:00
end
2020-05-27 00:38:18 +00:00
if not checkUnbound ( ) then
2020-04-10 21:22:35 +00:00
dns_descr = dns_descr .. " <br /> " .. translatef ( " Please note that %s is not supported on this system. " , " <i>unbound.adb_list</i> " )
2019-09-24 16:16:52 +00:00
end
dns = s : taboption ( " advanced " , ListValue , " dns " , translate ( " DNS Service " ) , dns_descr )
2020-05-27 00:38:18 +00:00
if checkDnsmasq ( ) then
2019-09-24 16:16:52 +00:00
dns : value ( " dnsmasq.addnhosts " , translate ( " DNSMASQ Additional Hosts " ) )
dns : value ( " dnsmasq.conf " , translate ( " DNSMASQ Config " ) )
2020-05-27 00:38:18 +00:00
if checkDnsmasqIpset ( ) then
2019-09-24 16:16:52 +00:00
dns : value ( " dnsmasq.ipset " , translate ( " DNSMASQ IP Set " ) )
end
dns : value ( " dnsmasq.servers " , translate ( " DNSMASQ Servers File " ) )
end
2020-05-27 00:38:18 +00:00
if checkUnbound ( ) then
2019-09-24 16:16:52 +00:00
dns : value ( " unbound.adb_list " , translate ( " Unbound AdBlock List " ) )
end
2019-08-17 13:15:10 +00:00
dns.default = " dnsmasq.servers "
ipv6 = s : taboption ( " advanced " , ListValue , " ipv6_enabled " , translate ( " IPv6 Support " ) , translate ( " Add IPv6 entries to block-list. " ) )
ipv6 : value ( " " , translate ( " Do not add IPv6 entries " ) )
ipv6 : value ( " 1 " , translate ( " Add IPv6 entries " ) )
ipv6 : depends ( { dns = " dnsmasq.addnhosts " } )
ipv6.default = " "
ipv6.rmempty = true
o5 = s : taboption ( " advanced " , Value , " boot_delay " , translate ( " Delay (in seconds) for on-boot start " ) , translate ( " Run service after set delay on boot. " ) )
o5.default = 120
o5.datatype = " range(1,600) "
o6 = s : taboption ( " advanced " , Value , " download_timeout " , translate ( " Download time-out (in seconds) " ) , translate ( " Stop the download if it is stalled for set number of seconds. " ) )
o6.default = 10
o6.datatype = " range(1,60) "
o7 = s : taboption ( " advanced " , Value , " curl_retry " , translate ( " Curl download retry " ) , translate ( " If curl is installed and detected, it would retry download this many times on timeout/fail. " ) )
o7.default = 3
o7.datatype = " range(0,30) "
o8 = s : taboption ( " advanced " , ListValue , " parallel_downloads " , translate ( " Simultaneous processing " ) , translate ( " Launch all lists downloads and processing simultaneously, reducing service start time. " ) )
o8 : value ( " 0 " , translate ( " Do not use simultaneous processing " ) )
o8 : value ( " 1 " , translate ( " Use simultaneous processing " ) )
o8.default = 1
2019-07-05 15:30:48 +00:00
2019-08-17 13:15:10 +00:00
o10 = s : taboption ( " advanced " , ListValue , " compressed_cache " , translate ( " Store compressed cache file on router " ) , translate ( " Attempt to create a compressed cache of block-list in the persistent memory. " ) )
2019-07-05 15:30:48 +00:00
o10 : value ( " 0 " , translate ( " Do not store compressed cache " ) )
o10 : value ( " 1 " , translate ( " Store compressed cache " ) )
o10.default = " 0 "
2019-08-17 13:15:10 +00:00
o11 = s : taboption ( " advanced " , ListValue , " debug " , translate ( " Enable Debugging " ) , translate ( " Enables debug output to /tmp/simple-adblock.log. " ) )
o11 : value ( " 0 " , translate ( " Disable Debugging " ) )
o11 : value ( " 1 " , translate ( " Enable Debugging " ) )
o11.default = " 0 "
2018-07-17 00:43:16 +00:00
s2 = m : section ( NamedSection , " config " , " simple-adblock " , translate ( " Whitelist and Blocklist Management " ) )
-- Whitelisted Domains
2019-08-17 13:15:10 +00:00
d1 = s2 : option ( DynamicList , " whitelist_domain " , translate ( " Whitelisted Domains " ) , translate ( " Individual domains to be whitelisted. " ) )
2018-07-17 00:43:16 +00:00
d1.addremove = false
d1.optional = false
-- Blacklisted Domains
2019-08-17 13:15:10 +00:00
d3 = s2 : option ( DynamicList , " blacklist_domain " , translate ( " Blacklisted Domains " ) , translate ( " Individual domains to be blacklisted. " ) )
2018-07-17 00:43:16 +00:00
d3.addremove = false
d3.optional = false
-- Whitelisted Domains URLs
2019-08-17 13:15:10 +00:00
d2 = s2 : option ( DynamicList , " whitelist_domains_url " , translate ( " Whitelisted Domain URLs " ) , translate ( " URLs to lists of domains to be whitelisted. " ) )
2018-07-17 00:43:16 +00:00
d2.addremove = false
d2.optional = false
-- Blacklisted Domains URLs
2019-08-17 13:15:10 +00:00
d4 = s2 : option ( DynamicList , " blacklist_domains_url " , translate ( " Blacklisted Domain URLs " ) , translate ( " URLs to lists of domains to be blacklisted. " ) )
2018-07-17 00:43:16 +00:00
d4.addremove = false
d4.optional = false
-- Blacklisted Hosts URLs
2019-08-17 13:15:10 +00:00
d5 = s2 : option ( DynamicList , " blacklist_hosts_url " , translate ( " Blacklisted Hosts URLs " ) , translate ( " URLs to lists of hosts to be blacklisted. " ) )
2018-07-17 00:43:16 +00:00
d5.addremove = false
d5.optional = false
return m