1 #!/bin/sh /etc/rc.common
7 readonly A_TMP
='/var/hosts.allowed.tmp'
8 readonly B_TMP
='/var/hosts.blocked.tmp'
9 readonly T_TMP
='/var/simple-adblock.hosts'
10 readonly dl
='wget --no-check-certificate -qO-'
11 readonly h_filter
='/localhost/d;/^#/d;/^[^0-9]/d;s/^0\.0\.0\.0.//;s/^127\.0\.0\.1.//;s/[[:space:]]*#.*$//;s/[[:cntrl:]]$//;s/[[:space:]]//g;/[`~!@#\$%\^&\*()=+;:"'\'',<>?/\|[{}]/d;/]/d;/\./!d;/^$/d;'
12 readonly d_filter
='/^#/d;s/[[:space:]]*#.*$//;s/[[:space:]]*$//;s/[[:cntrl:]]$//;/[[:space:]]/d;/[`~!@#\$%\^&\*()=+;:"'\'',<>?/\|[{}]/d;/]/d;/\./!d;/^$/d;'
13 readonly f_filter
='s|^|local=/|;s|$|/|'
14 readonly _OK_
='\033[0;32m\xe2\x9c\x93\033[0m'
15 readonly _FAIL_
='\033[0;31m\xe2\x9c\x97\033[0m'
16 readonly __OK__
='\033[0;32m[\xe2\x9c\x93]\033[0m'
17 readonly __FAIL__
='\033[0;31m[\xe2\x9c\x97]\033[0m'
18 readonly _ERROR_
='\033[0;31mERROR\033[0m'
20 export EXTRA_COMMANDS
="check killcache"
21 export EXTRA_HELP
=" check Checks if specified <string> is found in current blacklist"
23 readonly packageName
='simple-adblock'
24 readonly serviceName
="$packageName $PKG_VERSION"
25 ok
() { case $verbosity in 1) output
"$_OK_";; 2) output
"$__OK__\n";; esac; }
26 okn
() { case $verbosity in 1) output
"$_OK_\n";; 2) output
"$__OK__\n";; esac; }
27 fail
() { case $verbosity in 1) output
"$_FAIL_";; 2) output
"$__FAIL__\n";; esac; }
28 failn
() { case $verbosity in 1) output
"$_FAIL_\n";; 2) output
"$__FAIL__\n";; esac; }
29 output
() { [[ $# -ne 1 ]] && { [[ ! $
((verbosity
& $1)) -gt 0 ]] && return 0 ||
shift; }; local msg
; msg
=$
(echo -n "${1/$serviceName /service }" | sed 's|\\033\[[0-9]\?;\?[0-9]\?[0-9]\?m||g'); [[ -t 1 ]] && echo -e -n "$1"; [[ $(echo -e -n "$msg" | wc -l) -gt 0 ]] && logger -t "${packageName:-service} [$$]" "$(echo -e -n ${logmsg}${msg})" && logmsg='' || logmsg=${logmsg}${msg}; }
30 led_on(){ [[ -n "$led" && -e "$led/trigger
" ]] && echo "default-on
" > "$led/trigger
"; }
31 led_off(){ [[ -n "$led" && -e "$led/trigger
" ]] && echo "none
" > "$led/trigger
"; }
32 export serviceEnabled verbosity force_dns debug led wan_if wan_gw wanphysdev hosts_file
34 boot() { ( sleep 120 && rc_procd start_service && rc_procd service_triggers | cat &); }
36 load_package_config() {
37 config_load "$packageName"
38 config_get_bool serviceEnabled 'config' 'enabled' 1
39 config_get_bool force_dns 'config' 'force_dns' 1
40 config_get_bool debug 'config' 'debug' 0
41 config_get verbosity 'config' 'verbosity' '2'
42 config_get hosts_file 'config' 'hosts_file' "/var
/dnsmasq.d
/${packageName}"
43 config_get led 'config' 'led'
44 source /lib/functions/network.sh
51 if [ "$debug" -ne 0 ]; then
52 exec 1>>/tmp/simple-adblock.log
57 led="${led:+/sys/class/leds/$led}"
58 [ $serviceEnabled -gt 0 ] || return 1
60 network_flush_cache; network_find_wan wan_if; network_get_gateway wan_gw $wan_if;
61 [[ $sleepCount -ge 25 || -n "$wan_gw" ]] && break
62 output "$serviceName waiting
for wan gateway...
\n"; sleep 2; let "sleepCount
+=1";
64 [ -n "$wan_gw" ] && return 0
65 output "$_ERROR_: $serviceName failed to discover WAN gateway.
\n"; return 1;
69 [ $force_dns -eq 0 ] && return 0
70 [ -z "$packageName" ] && return 1
71 iptables-save | grep -Fv -- "$packageName" | iptables-restore
72 lsmod | grep -q ip6table_nat && ip6tables-save | grep -Fv -- "$packageName" | ip6tables-restore
73 [ -z "$1" ] && output 'No longer forcing local DNS server.\n'
77 local ip ipv6 label ipv6wan brname
78 network_get_ipaddr ip lan; network_get_ipaddr6 ipv6 lan; network_get_device brname lan; network_get_physdev wanphysdev wan;
79 ipv6wan=$(ifconfig $wanphysdev | grep inet6 | awk '{print $3}')
81 iptables_destroy 'quiet'
82 if [ $force_dns -ne 0 ]; then
83 [ -n "$ip" ] && iptables -t nat -A prerouting_rule -i $brname -p tcp --dport 53 -j DNAT --to $ip -m comment --comment "$packageName"
84 [ -n "$ip" ] && iptables -t nat -A prerouting_rule -i $brname -p udp --dport 53 -j DNAT --to $ip -m comment --comment "$packageName"
85 if [[ -n "$ipv6" && -n "$ipv6wan" ]] && lsmod | grep -q ip6table_nat; then
86 ip6tables -t nat -A PREROUTING -i $brname -p tcp --dport 53 -j DNAT --to-destination [$ipv6] -m comment --comment "$packageName"
87 ip6tables -t nat -A PREROUTING -i $brname -p udp --dport 53 -j DNAT --to-destination [$ipv6] -m comment --comment "$packageName"
93 if [ -n "$label" ]; then
94 output "Forcing
local DNS server
: $label.
\n"
96 output "$_ERROR_: $serviceName failed to obtain LAN IP address
for DNS forcing
!\n"
104 [ -f $hosts_file ] && mv $hosts_file $T_TMP
105 output 3 "Restarting dnsmasq
"
107 /etc/init.d/dnsmasq restart >/dev/null 2>&1
108 if [[ $? -eq 0 ]]; then
109 okn; output "$serviceName stopped.
\n";
111 failn; output "$_ERROR_: $serviceName failed to reload dnsmasq
!\n";
116 local label type D_TMP R_TMP
117 [[ -n "$1" && -n "$2" && -n "$3" ]] || return 1
119 [ "$2" == "hosts
" ] && label="Hosts
: $
(echo $1 | cut
-d'/' -f3)" filter="$h_filter" || label="Domains
: $
(echo $1 | cut
-d'/' -f3)" filter="$d_filter"
120 [ "$3" == "blocked
" ] && { type='Blocked'; D_TMP="$B_TMP"; } || { type='Allowed'; D_TMP="$A_TMP"; }
121 R_TMP="/var
/simple-adblock_$
(head -c40 /dev
/urandom
2>/dev
/null |
tr -dc 'A-Za-z0-9' 2>/dev
/null
)"
122 while [ -e "$R_TMP" ]; do R_TMP="/var
/simple-adblock_$
(head -c40 /dev
/urandom
2>/dev
/null |
tr -dc 'A-Za-z0-9' 2>/dev
/null
)"; done
124 output 2 "[DL
] $type $label "
125 $dl "${url}" > "$R_TMP" 2>/dev/null && ok || fail
126 { sed -i "$filter" "$R_TMP"; cat "$R_TMP" >> "$D_TMP"; rm -f "$R_TMP"; } &
130 local whitelist_domains blacklist_domains whitelist_domains_urls blacklist_domains_urls blacklist_hosts_urls
131 config_get whitelist_domains 'config' 'whitelist_domain'
132 config_get blacklist_domains 'config' 'blacklist_domain'
133 config_get whitelist_domains_urls 'config' 'whitelist_domains_url'
134 config_get blacklist_domains_urls 'config' 'blacklist_domains_url'
135 config_get blacklist_hosts_urls 'config' 'blacklist_hosts_url'
139 [ ! -d ${hosts_file%/*} ] && mkdir -p ${hosts_file%/*}
140 [ ! -f "$hosts_file" ] && touch "$hosts_file"
141 if [[ -s $T_TMP && ! "$1" == "reload
" ]]; then
142 output 3 'Found existing data file, reusing it '
143 mv $T_TMP $hosts_file && okn || failn
145 [ -f $A_TMP ] && rm -f $A_TMP; [ -f $B_TMP ] && rm -f $B_TMP; [ -f $T_TMP ] && rm -f $T_TMP; [ -f $hosts_file ] && rm -f $hosts_file;
146 if [ "$
(awk '/^MemFree/ {print int($2/1000)}' "/proc/meminfo")" -lt 32 ]; then
147 output 1 'Low free memory, restarting dnsmasq...'
148 /etc/init.d/dnsmasq restart >/dev/null 2>&1 && okn || failn
150 touch $A_TMP; touch $B_TMP; touch $T_TMP;
151 if [ -n "$blacklist_hosts_urls" ]; then
152 output 1 '[DL] Blocked Hosts '
153 for hf in ${blacklist_hosts_urls}; do process_url "$hf" 'hosts' 'blocked'; done
156 if [ -n "$blacklist_domains_urls" ]; then
157 output 1 '[DL] Blocked Domains '
158 for hf in ${blacklist_domains_urls}; do process_url "$hf" 'domains' 'blocked'; done
161 if [ -n "$whitelist_domains_urls" ]; then
162 output 1 '[DL] Allowed Domains '
163 for hf in ${whitelist_domains_urls}; do process_url "$hf" 'domains' 'allowed'; done
166 output 3 'Waiting for background processes '
168 [ -n "$blacklist_domains" ] && for hf in ${blacklist_domains}; do echo "$hf" | sed "$d_filter" >> $B_TMP; done
169 whitelist_domains="${whitelist_domains}"$'\n'"$
(cat $A_TMP)"
170 [ -n "$whitelist_domains" ] && for hf in ${whitelist_domains}; do hf=$(echo $hf | sed 's/\./\\./g'); w_filter="$w_filter/^${hf}$/d;/\\.${hf}$/d;"; done
171 if [ -s $B_TMP ]; then
172 output
1 'Processing downloads '
173 output
2 'Sorting merged file '; sort $B_TMP |
uniq > $T_TMP && ok || fail
174 output
2 'Whitelisting domains '; sed -i "$w_filter" $T_TMP && ok || fail
175 output
2 'Formatting merged file '; sed "$f_filter" $T_TMP > $B_TMP && mv $B_TMP $hosts_file && ok || fail
177 output
3 'Removing temporary files '
178 [ -f $A_TMP ] && rm -f $A_TMP; [ -f $B_TMP ] && rm -f $B_TMP; [ -f $T_TMP ] && rm -f $T_TMP;
183 if [ -s $hosts_file ]; then
184 output
3 'Restarting dnsmasq '
185 /etc
/init.d
/dnsmasq restart
>/dev
/null
2>&1
186 if [[ $?
-eq 0 ]]; then
188 output
"$serviceName blocking $(wc -l < $hosts_file) domains $_OK_\n"
190 failn
; output
"$_ERROR_: $serviceName failed to reload dnsmasq!\n";
194 output
"$_ERROR_: $serviceName failed to create its data file!\n"
202 if [ ! -f $hosts_file ]; then
203 echo "No local blacklist ($hosts_file) found."
204 elif [ -z "$string" ]; then
205 echo "Usage: /etc/init.d/${serviceName} check <string>"
206 elif grep -m1 -q $string $hosts_file; then
207 echo "Found $(grep $string $hosts_file | wc -l) matches for $string in $hosts_file:"
208 grep $string $hosts_file |
sed 's|local=/||;s|/$||;'
210 echo "The $string is not found in current blacklist."
215 is_enabled ||
return 1
216 if [ -f "$hosts_file" ]; then
217 output
"Reloading $serviceName...\n"
218 iptables_create
'quiet'
219 start_adblocking
'reload'
221 output
"Starting $serviceName...\n"
229 output
"Stopping $serviceName...\n"
234 killcache
() { [ -s $T_TMP ] && rm -f $T_TMP; }