Advertisement
rs232

adblock_v2_test

Feb 28th, 2023 (edited)
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 48.41 KB | None | 0 0
  1. #!/bin/sh
  2. # Adblock (a.k.a. DNS-filtering) FreshTomato GUI back-end
  3. ver="v2.72d - 01/24" # rs232
  4. PID=$$
  5. pidfile="/var/run/adblock.pid"
  6. export PATH=/bin:/usr/bin:/sbin:/usr/sbin:/home/root:
  7. pre=$(date +%s)
  8. # nvram_ops
  9. alias only="sed -e 's/^[ \t]*//' | grep -Ev '^($|#|!)' | sort"
  10. alias NG="nvram get"
  11. alias NS="nvram set"
  12. alias NC="nvram commit"
  13. black="\033[0;40m"
  14. red="\033[0;41m"
  15. white="\033[1;37m"
  16. grey="\033[0;5;238m"
  17. green="\033[48;2;32m"
  18. yellow="\033[48;2;33m"
  19. # /nvram_ops
  20.  
  21. hashblack() {
  22. hb="=B+ $(NG adblock_blacklist | tr '>' '\n' | grep -E ^1 | cut -d/ -f3- | sort | cut -f1 -d'<') $(NG adblock_enable) $(NG adblock_path) $(NG adblock_limit) =BC+ $(NG adblock_blacklist_custom | only ) =BCF+"
  23. for i in $(NG adblock_blacklist_custom | only | grep -E ^/ ); do hb="$hb $(cat ${i} | only )"; done
  24. echo $hb | tr " " "\n" | grep -Ev '^($|#|!)'
  25. }
  26.  
  27. hashwhite() {
  28. hw="=W+ $(NG adblock_whitelist | only ) =WF+"
  29. for i in $(NG adblock_whitelist | only | grep -E ^/ ); do hw="$hw $(cat ${i} | only)"; done
  30. echo $hw | tr " " "\n" | grep -Ev '^($|#|!)'
  31. }
  32.  
  33. TMP="/tmp/adbtmp" ; mkdir -p "${TMP}"
  34.  
  35. [ $(NG adblock_logs | wc -c) -gt 0 ] && { LOGL=$(NG adblock_logs); } || { LOGL=3; }
  36. alias logo='logger -p NOTICE -t adblock[$PID]'
  37. [ $LOGL -ge 7 ] && alias logd='logger -p DEBUG -t adblock[$PID]' || alias logd=':'
  38. [ $LOGL -ge 6 ] && alias logi='logger -p INFO -t adblock[$PID]' || alias logi=':'
  39. [ $LOGL -ge 5 ] && alias logn='logger -p NOTICE -t adblock[$PID]' || alias logn=':'
  40. [ $LOGL -ge 4 ] && alias logw='logger -p WARN -t adblock[$PID]' || alias logw=':'
  41. [ $LOGL -ge 3 ] && alias loge='logger -p ERROR -t adblock[$PID]' || alias loge=':'
  42. ( [ $LOGL -eq 7 ] && [ $# -eq 0 ] ) || ( [ $LOGL -eq 7 ] && [ $1 == update -o $1 == start ] ) && { exec 2>$TMP/adblock.debug.${pre} ; set -x; echo "Running in trace mode: $TMP/adblock.debug.${pre}"; } || set -
  43. DNS_TIME="${TMP}/dnsmasq.time"
  44.  
  45. dnsrestart() { pr=$(cat /proc/uptime | cut -f1 -d' ') ; service dnsmasq restart &>/dev/null && { echo $(cat /proc/uptime | cut -f1 -d ' ' ) $pr | awk '{print $1 - $2 "s"}' > ${DNS_TIME} ; [ ${LOGL} -ge 6 -a -f ${DNS_TIME} ] && { sleep 1; logi "dnsmasq restart time = $(cat $DNS_TIME)" ;} ;} ;}
  46.  
  47. ( [ -f $pidfile ] && [ $# -eq 0 -o $1 == start -o $1 == update ] ) && {
  48. # If the pidfile is older than $hold min this is very likely and issue = remove it.
  49. [ $((($(date +%s) - $(date -r ${pidfile} +%s))/60)) -gt $hold ] && {
  50. rm -f $pidfile
  51. for process in $(ps | grep [a]dblock | grep -v "status\|$PID" | awk '{print $1}'); do (kill -9 $process) &>/dev/null ; done
  52. dnsrestart
  53. }
  54. logn "Adblock/DNS-filtering is already loading. Skipping call..."
  55. echo "Adblock/DNS-filtering is already loading. Skipping call..."
  56. exit
  57. }
  58.  
  59. ( ls -1tr $TMP/adblock.debug.* | head -n -10 | while read file; do rm -f $file; done ) 2>/dev/null # Keep maximum 10 debug files
  60.  
  61. USERAGENT="Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/109.0"
  62. [ $LOGL -eq 7 ] && Q=" " || Q="-q"
  63. alias yget="wget --no-check-certificate -T 15 $Q -U \"$USERAGENT\" --header \"Cache-Control: no-cache\""
  64.  
  65. alias domain="sed 's/[#!].*//' | grep -Eo '((([a-zA-Z]{1,2})|([0-9]{1,2})|([a-zA-Z0-9]{1,2})|([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]))\.)+[a-zA-Z]{2,6}'| grep -vEi '\.gif$|\.jpe?g$|\.png$|\.jsp?$|\.css$|\.ico$|\.aspx?$|\.php$|\.cer$|\.cfm$|\.cgi$|\.x?html?$|\.py$|\.rss$|\.vb$|\.sh$|\.json$'"
  66. alias notin="grep -Ev '^#.*|^!.*|^::|^\s*?$|^([a-f0-9:]+:+)+[a-f0-9]+'"
  67. alias number="sed ':a;s/\B[0-9]\{3\}\>/,&/;ta'"
  68. hold=30
  69. [ $(NG adblock_path | wc -c) -gt 0 ] && {
  70. NG adblock_path | grep -Eq '^/jffs' && logw "Custom path is pointing to JFFS, this is not ideal. Consider using alternative storages like USB/CIFS/etc."
  71. DPATH="$(NG adblock_path | sed 's/\/$//')/adblock" ; mkdir -p "$DPATH"; } || DPATH="/etc"
  72.  
  73. sizeLimit=$(NG adblock_limit)
  74. setlimit() {
  75. [ $(NG adblock_limit | wc -c ) -le 1 ] && {
  76. NS adblock_limit=$(echo $(($(cat /proc/meminfo | grep MemTotal | awk '{print $2}') * $([ $DPATH == '/etc' ] && echo 650 || echo 1000) / 10)))
  77. NC
  78. logi "The nvram adblock_limit variable is now reset to the default value of $(NG adblock_limit)"
  79. }
  80. sizeLimit=$(NG adblock_limit)
  81. }
  82.  
  83. PREFIX="/tmp/adblock" ; mkdir -p "$PREFIX" && cd "$PREFIX"
  84. [ $DPATH == '/etc' ] && D=$PREFIX || D=$DPATH
  85. ENABLE=$(NG adblock_enable)
  86. FINAL="${DPATH}/dnsmasq.adblock";
  87. UNLOADED="${DPATH}/dnsmasq.adblock.unloaded"
  88. TM="$PREFIX/adblock.temp"
  89. TM1="$PREFIX/adblock.temp1"
  90. CHK_FILE="$TMP/adblock.time"
  91. RTN=0
  92. alias rtn='[ $RTN -ne 255 ] && { echo $RTN ; return; }'
  93. BLACKLIST=$(NG adblock_blacklist)
  94. WHITELIST=$(NG adblock_whitelist | only )
  95. CUSTOM=$(NG adblock_blacklist_custom | only )
  96. TRIMPERC=5
  97. ADHELPER="$TMP/adblock.helper"; touch ${ADHELPER}
  98. ADHEAD="$TMP/adblock.headers"; touch ${ADHEAD}
  99. CHGCOUNT=0; alias chgcount='CHGCOUNT=$((CHGCOUNT+1))'
  100. ERRCOUNT=0; alias erroradd='ERRCOUNT=$((ERRCOUNT+1))'
  101. VRFY="$TMP/adblock.verify"
  102. latest=0
  103. current=$(echo "$ver" | cut -c-6)
  104. UURL="https://bitbucket.org/rs232-/freshtomato-arm/downloads/adblock.rs232"
  105. extra="$(NG adblock_path | sed 's/\/$//')/adblock.extra" ; [ -s "$extra" ] && { [ $(ls -l $extra | cut -c4,7,10) != "xxx" ] && { chmod +x $extra ;} ; . "$extra"; }
  106.  
  107. checkList() { # 0=fetch_local / 1=download / 2=issues / 3=duplicated
  108. urinameh=$(echo "${4}".header)
  109. urinamel=$(echo "${4}".list)
  110. logd "[$1] checkList(A) - Header presence"
  111. [ ! -f "$PREFIX/${urinameh}" ] && { yget "$2" -O /dev/null -S --spider 2> "$PREFIX/${urinameh}"; [ $(echo $?) -gt 0 ] && {
  112. logd "[$1] checkList(A2) = Can't download the list headers"
  113. [ $DPATH != '/etc' -a -s "$DPATH/${urinameh}" -a -s "$DPATH/${urinamel}" ] && {
  114. logd "[$1] checkList(A2) = Found a stored older copy of ${urinameh}. Using it..."
  115. cp -f "$DPATH/${urinameh}" $PREFIX
  116. RTN=255
  117. } || RTN=2
  118. } || RTN=255
  119. }
  120. rtn
  121. logd "[$1] checkList(B) - Duplicated lists check"
  122. cat ${ADHEAD} 2> /dev/null | grep -Eq ${4} && { logd "[$1] checkList(B1) = The list is already downloaded. Is this perhaps a duplicate?"; RTN=3; } || RTN=255
  123. rtn
  124. logd "[$1] checkList(C) - URI Redirection"
  125. cat "$PREFIX/${urinameh}" | grep -q "Location:" && { yget $(cat "$PREFIX/${urinameh}" | grep Location: | tail -1 | awk '{print $2}') -O /dev/null -S --spider 2> "$PREFIX/${urinameh}"; RTN=255 ;} || RTN=255
  126. logd "[$1] checkList(D) - \$PATH control"
  127. [ $DPATH == '/etc' ] && { logd "[$1] checkList(D1) = Using RAM only, skipping further controls"; RTN=1; } || { RTN=255; } # Using /tmp (RAM) nothing to check
  128. rtn
  129. logd "[$1] checkList(E) - Stored list"
  130. [ ! -f "$D/${urinamel}" ] && { logd "[$1] checkList(E1) - The list is not yet downloaded, skipping further controls"; RTN=1; } || { RTN=255; }
  131. rtn
  132. logd "[$1] checkList(F) - Header content"
  133. [ $(wc -c < "$PREFIX/${urinameh}") -lt 80 -o $(grep -E 'timed out|reset|No route to host' < "$PREFIX/${urinameh}" | wc -l ) -ge 1 ] && { logd "[$1] checkList(F1) = Errors have been found in the header, skipping further controls"; RTN=1; } || { RTN=255; } # Just download if any issues with the header
  134. rtn
  135. logd "[$1] checkList(G) - ETag"
  136. # Compare ETag field
  137. [ -f $D/${urinameh} ] && { [ $(grep -i 'etag:' < "$PREFIX/${urinameh}" | tr -d '"' | awk '{print $2}' | sed 's/[^a-zA-Z0-9]//g' ) == $(grep -i 'etag:' < "$D/${urinameh}" | tr -d '"' | awk '{print $2}' | sed 's/[^a-zA-Z0-9]//g') ] && { logd "[$1] checkList(G0) = ETag confirms the list is already updated"; RTN=0; } || { RTN=255; } ;}
  138. rtn
  139. # If ETag is inconclusive look for Last-modified
  140. logd "[$1] checkList(H) - Last-Modified"
  141. grep -q 'Last-Modified' < "$PREFIX/${urinameh}" && {
  142. [ "$(grep -i 'Last-Modified' < "$PREFIX/${urinameh}" | awk '{print $3" "$4" "$5" "$6}')" != "$(grep -i 'Last-Modified' < "$D/${urinameh}" | awk '{print $3" "$4" "$5" "$6}')" ] && { logd "[$1] checkList(H1) = Last modified confirmed the list has been modified -> Forcing download"; RTN=1; } || { RTN=255; }
  143. rtn
  144. }
  145. # Else download
  146. logd "[$1] checkList(K) = None of the checks are conclusive. Forcing a download."
  147. RTN=1
  148. rtn
  149. }
  150.  
  151. checkRam() {
  152. # 0=Not-good-skip / 1=OK-proceed / 2=NoInfo
  153. urinameh=$(echo "${4}".header)
  154. freeram=$(( $(grep MemFree /proc/meminfo | awk '{print $2}') * 1024 )) # in Bits
  155. listSize=$( [ -s "$PREFIX/${urinameh}" ] && { grep -Evi 'Content-Length: 0$' "$PREFIX/${urinameh}" | grep -i 'Content-Length' | awk '{print $2}' ; } ) # in Bytes
  156. [ -z $listSize ] && listSize=0
  157. logd "[$1] checkRam(X) - list header content assessment"
  158. [ $listSize -eq 0 ] && { logd "[$1] checkRam(X0) = The list headers don't provide enough info to perform a proper check. Skipping the checkRam() and proceed"; RTN=0; } || RTN=255
  159. rtn
  160. logd "[$1] checkRam(Y) - listSize Vs sizeLimit"
  161. [ -f $TM ] && { [ $(( ( $(echo $(wc -c < $TM)) + $listSize ) * (100 + 20) / 100 )) -lt $sizeLimit ] && RTN=255 || { loge "[$1] checkRam(Y1) = listSize Vs sizeLimit = Low confidence this list would fit within the sizeLimit. Skipping it..."; RTN=1; } ; } # 20% extra is allowed
  162. rtn
  163. logd "[$1] checkRam(Z) - listSize Vs free RAM"
  164. [ -z ${listSize} ] && { logd "[$1] checkRam(Z1) - Header Content Lenght missing, unable to conclude negatively, proceed"; RTN=1; } || {
  165. [ $(( $freeram )) -gt $(( $listSize / 100 )) ] && { logd "[$1] checkRam(Z0) = The list should fit in RAM, proceeding"; RTN=0; } || { loge "[$1] checkRam(Z1) = Low confidence this list would fit in the free RAM. Skipping it..."; RTN=1; }
  166. rtn
  167. }
  168. }
  169.  
  170. download() {
  171. COUNT=0
  172. SUBLIST=0
  173. ENTRIES=0
  174. logo "Kick off"
  175. rm -rf $PREFIX/*
  176. echo "1COUNT 2URL 3uriname 4listresult 5ramresult 0" > $ADHEAD
  177.  
  178. touch ${VRFY}
  179. # Get fresh headers for all the enabled lists
  180. for i in $(echo "$BLACKLIST" | grep -Ev '^$' | tr " " "_" | tr ">" "\n"); do
  181. ENBL=$(echo "$i" | cut -d "<" -f1)
  182. URL=$(echo "$i" | cut -d "<" -f2 | sed -e 's/_$//' -e 's/^[ \t]*//')
  183. COUNT=$((COUNT+1))
  184. [ "$ENBL" -eq "1" ] && {
  185. uriname=$(echo "$URL" | md5sum | awk '{print $1}')
  186. logn "[$COUNT][$URL][$uriname] Fetching fresh list-headers"
  187. listresult=$(checkList $COUNT $URL none $uriname)
  188. logd "[$COUNT] Result of checkList($listresult) ................ 0=storage / 1=download / 2=issues / 3=duplicated"
  189. echo "$COUNT $URL $uriname $listresult" >> $ADHEAD
  190. }
  191. done
  192.  
  193. # Is there a reason to process? If so what?
  194. restb=0
  195. restw=0
  196. if [ ! -s $CHK_FILE -o $( [ -s ${ADHEAD} ] && { cat ${ADHEAD} | grep -Ev ' 0$' | wc -l; } || echo 1 ) -gt 0 ]; then
  197. logo "Clear run or change in the lists detected. Executing full run."
  198. echo "Clear run or change in the lists detected. Executing full run."
  199. rm -f ${VRFY}
  200. elif [ $(hashblack | md5sum | awk '{print $1}') != $([ -s ${CHK_FILE} ] && { cat ${CHK_FILE} | grep md5black | grep -Eo ^[a-zA-Z0-9]{32} ;} || echo 0) -o $(hashwhite | md5sum | awk '{print $1}') != $([ -s ${CHK_FILE} ] && { cat ${CHK_FILE} | grep md5white | grep -Eo ^[a-zA-Z0-9]{32} ;} || echo 0) ]; then
  201. # Modification ot the blacklist part?
  202. [ $(hashblack | md5sum | awk '{print $1}') != $([ -s ${CHK_FILE} ] && { cat ${CHK_FILE} | grep md5black | grep -Eo ^[a-zA-Z0-9]{32} ;} || echo 0) ] && {
  203. hashblack | grep -A99999 =BC+ | grep -v ^= >$TMP/adblock.nowb
  204. cat $TMP/adblock.time | grep -A99999 =BC+ | grep -B99999 =W+ | grep -v ^= >$TMP/adblock.thenb
  205. # Something removed? Is so skip
  206. # sleep 600
  207. grep -qxvFf $TMP/adblock.nowb $TMP/adblock.thenb && {
  208. restb=1
  209. } || {
  210. # Something added? Is so process in quick-run
  211. grep -qxvFf $TMP/adblock.thenb $TMP/adblock.nowb && restb=2
  212. grep -xvFf $TMP/adblock.thenb $TMP/adblock.nowb | grep -Eq '^\+' && restb=1
  213. }
  214. }
  215. # Modification ot the whitelist part?
  216. [ $(hashwhite | md5sum | awk '{print $1}') != $([ -s ${CHK_FILE} ] && { cat ${CHK_FILE} | grep md5white | grep -Eo ^[a-zA-Z0-9]{32} ;} || echo 0) ] && {
  217. hashwhite | grep -A99999 =W+ | grep -v ^= >$TMP/adblock.noww
  218. cat $TMP/adblock.time | grep -A99999 =W+ | grep -v ^= >$TMP/adblock.thenw
  219. # Something removed? Is so skip
  220. grep -qxvFf $TMP/adblock.noww $TMP/adblock.thenw && {
  221. restw=1
  222. } || {
  223. # Something added? Is so process in quick-run
  224. grep -qxvFf $TMP/adblock.thenw $TMP/adblock.noww && restw=2
  225. grep -xvFf $TMP/adblock.thenw $TMP/adblock.noww | grep -Eq '^%' && restw=1
  226. }
  227. }
  228.  
  229. # No change of sort? Skip!
  230. else
  231. logo "There's no change of config and all the enabled lists are updated. Skipping..."
  232. echo "There's no change of config and all the enabled lists are updated. Skipping..."
  233. logi "$FINAL = $(wc -l < $FINAL|number) lines in $(wc -c < $FINAL|number) Bytes."
  234. rm -f ${VRFY}
  235. adExit 5
  236. fi
  237. # Crunch the results
  238. if [ $restb -eq 1 -o $restw -eq 1 ]; then
  239. logi "Disruptive change of config detected. Executing full-run."
  240. echo "Disruptive change of config detected. Executing full-run."
  241. rm -f $TMP/adblock.now* $TMP/adblock.then* 2>/dev/null
  242. elif [ $restb -eq 2 -o $restw -eq 2 ]; then
  243. [ $restb -eq 2 ] && {
  244. for i in $(grep -xvFf $TMP/adblock.thenb $TMP/adblock.nowb); do
  245. logi "Addition in the blacklist_custom detected. Executing quick-run."
  246. echo "Addition in the blacklist_custom detected. Executing quick-run."
  247. grep -q "/$i/" $FINAL || echo "local=/$i/" >> $FINAL; done
  248. }
  249. [ $restw -eq 2 ] && {
  250. for i in $(grep -xvFf $TMP/adblock.thenw $TMP/adblock.noww); do
  251. logi "Addition in the whitelist detected. Executing quick-run."
  252. echo "Addition in the whitelist detected. Executing quick-run."
  253. sed -i "/local=\/$i\//d" $FINAL; done
  254. }
  255. rm -f ${VRFY}
  256. rm -f $TMP/adblock.now* $TMP/adblock.then* 2>/dev/null
  257. safeDnsmasqRestart 0
  258. echo "$(hashblack | md5sum | awk '{print $1}') md5black" > $CHK_FILE
  259. echo "$(hashwhite | md5sum | awk '{print $1}') md5white" >> $CHK_FILE
  260. hashblack >> $CHK_FILE
  261. hashwhite >> $CHK_FILE
  262. adExit 5
  263. fi
  264.  
  265. # If so proceed
  266. COUNT=0
  267. rm -f ${FINAL}
  268. for i in $(echo "$BLACKLIST" | grep -Ev '^$' | tr " " "_" | tr ">" "\n"); do
  269. ENBL=$(echo "$i" | cut -d "<" -f1)
  270. URL=$(echo "$i" | cut -d "<" -f2 | sed -e 's/_$//' -e 's/^[ \t]*//')
  271. COUNT=$((COUNT+1))
  272. [ "$ENBL" -eq "1" ] && {
  273. uriname=$(echo "$URL" | md5sum | awk '{print $1}')
  274. logn "[$COUNT][$URL][$uriname] Processing blacklist"
  275. listresult=$(cat ${ADHEAD} | grep $uriname | awk '{print $4}')
  276. ramresult=$(checkRam $COUNT $URL none $uriname)
  277. logd "[$COUNT] Result of checkRam($ramresult) ................ 0=OK / 1=failed"
  278. if [ $listresult -eq 0 -a $ramresult -eq 0 ]; then
  279. logi "[$COUNT][$URL] The list is already updated. No download needed. Loading from storage."
  280. elif [ $listresult -eq 0 -a $ramresult -eq 1 ]; then
  281. logw "[$COUNT][$URL] The list is already updated, but checkRam() failed. Skipping..."
  282. erroradd
  283. continue
  284. elif [ $listresult -eq 1 -a $ramresult -eq 1 ]; then
  285. logw "[$COUNT][$URL] The would require a download, but checkRam() failed. Skipping..."
  286. erroradd
  287. continue
  288. elif [ $listresult -eq 2 ]; then
  289. loge "[$COUNT][$URL] Unable to download the list headers, please check the source."
  290. erroradd
  291. continue
  292. elif [ $listresult -eq 3 ]; then
  293. logw "[$COUNT][$URL] It appears like this list is a duplicate. Skipping..."
  294. continue
  295. elif [ $listresult -eq 1 -a $ramresult -eq 0 ]; then
  296. logi "[$COUNT][$URL] checkRam() passed."
  297. logn "[$COUNT][$URL] The list is being downloaded."
  298. cat $PREFIX/${uriname}.header | grep -q "Location:" && { logi "[$COUNT][$URL] The file is redirected to a new URL. Handling this."; URL=$(cat $PREFIX/${uriname}.header | grep Location: | tail -1 | awk '{print $2}') ;}
  299. yget "$URL" -O "$PREFIX/${uriname}.list" && [ $DPATH != '/etc' ] && { cp -f "$PREFIX/${uriname}.header" "$D" ; mv -f "$PREFIX/${uriname}.list" "$D"; }
  300. usleep 200
  301. fi
  302.  
  303. [ ! -f "$DPATH/${uriname}.list" -a ! -f "$PREFIX/${uriname}.list" ] && {
  304. loge "[$COUNT][$URL] This list was not downloaded. Skipping..."
  305. erroradd
  306. } || {
  307. grep -q -E '^https?://' "$D/${uriname}.list" && {
  308. # List of lists
  309. logn "[$COUNT][$URL] Group-of-lists (List of URLs) format >> Parsing..."
  310. grep -E '^https?://' "$D/${uriname}.list" | awk '{print $1}'| while read u; do
  311. SUBLIST=$((SUBLIST+1))
  312. urinamed=$(echo "$u" | md5sum | awk '{print $1}')
  313. logn "[$COUNT][$SUBLIST][$u][$uriname] Processing black(sub)list"
  314. listresult=$(checkList $COUNT $u $SUBLIST $urinamed)
  315. ramresult=$(checkRam $COUNT $u $SUBLIST $urinamed)
  316. logd "[$COUNT][$SUBLIST] Result of checkList($listresult) ................ 0=storage / 1=download / 2=issues / 3=duplicated"
  317. logd "[$COUNT][$SUBLIST] Result of checkRam($ramresult) ................ 0=OK / 1=failed"
  318.  
  319. if [ $listresult -eq 0 -a $ramresult -eq 0 ]; then
  320. logi "[$COUNT][$SUBLIST][$u] The (sub)list is already updated. No download needed. Loading from storage."
  321. elif [ $listresult -eq 0 -a $ramresult -eq 1 ]; then
  322. logw "[$COUNT][$SUBLIST][$u] The (sub)list is already updated, but checkRam() failed. Skipping..."
  323. erroradd
  324. continue
  325. elif [ $listresult -eq 2 ]; then
  326. loge "[$COUNT][$SUBLIST][$u] Unable to download the (sub)list headers. Please verify the source. Skipping..."
  327. erroradd
  328. continue
  329. elif [ $listresult -eq 3 ]; then
  330. logw "[$COUNT][$SUBLIST][$u] It appears like this (sub)list is a duplicate. Skipping..."
  331. continue
  332. elif [ $listresult -eq 1 -a $ramresult -eq 0 ]; then
  333. logi "[$COUNT][$SUBLIST][$u] Free RAM check passed."
  334. echo "$u\n" >> $PREFIX/white.url
  335. logi "[$COUNT][$SUBLIST][$u] The (sub)list is being downloaded."
  336. yget "$u" -O "$PREFIX/${urinamed}.list" && [ $DPATH != '/etc' ] && { cp -f "$PREFIX/${urinamed}.header" "$D" ; mv -f "$PREFIX/${urinamed}.list" "$D"; }
  337. usleep 200
  338. echo "${COUNT}-${SUBLIST} $u $urinamed $listresult" >> ${ADHEAD}
  339. fi
  340.  
  341. [ ! -f "$D/${urinamed}.list" ] && {
  342. loge "[$COUNT][$SUBLIST][$u] Sublist download error! Please verify the URL"
  343. erroradd
  344. } || {
  345. ENTRIES=$(notin "$D/${urinamed}.list" | wc -l)
  346. [ $ENTRIES -le 1 ] && {
  347. logw "[$COUNT][$SUBLIST][$u] The sublist appears to be empty! Skipping..."
  348. erroradd
  349. } || {
  350. logi "[$COUNT][$SUBLIST][$u] Found $(echo $ENTRIES|number) entries"
  351. parsefile "$D/${urinamed}.list" "$u" "$COUNT" "$SUBLIST"
  352. }
  353. }
  354. done
  355. continue
  356. }
  357. ENTRIES=$(notin "$D/${uriname}.list" | wc -l)
  358. [ $ENTRIES -le 1 ] && {
  359. logw "[$COUNT][$URL] The list appears to be empty! Skipping..."
  360. erroradd
  361. } || {
  362. logi "[$COUNT][$URL] Found $(echo $ENTRIES|number) entries"
  363. parsefile "$D/${uriname}.list" "$URL" "$COUNT"
  364. }
  365. }
  366. } || {
  367. logi "[$COUNT][$URL][$uriname] Disabled."
  368. }
  369. done
  370.  
  371. # CUSTOM BLACKLIST
  372. [ $(echo $CUSTOM | wc -c) -gt 2 ] && {
  373. [ -f $TM1 ] && rm -f $TM1
  374. echo $CUSTOM | tr " " "\n" | grep -Ev '^($|#|!)' | while read i; do
  375. echo "$i" | grep -Eq '^/.*' && {
  376. [ -f $i ] && {
  377. while IFS= read -r dom || [ -n "$dom" ]; do printf '%s\n' "$dom"; done < $i | tr -d "\r" | grep -Ev '^($|#|!)' | while read m; do
  378. echo "$m" | grep -Eq '^\+' && { sed -i "s/^[a-zA-Z0-9.-]\{0,64\}\.]\{0,1\}$(echo $m | cut -c2- | domain)\|^$(echo $m | cut -c2- | domain)//g" $TM ; echo $(echo $m | sed "s/^[a-zA-Z0-9.-]\{0,64\}\.]\{0,1\}$(echo $m | domain)\|^$(echo $m | domain)//g" | domain ) >> $TM1 ; } || { echo "$m" >> $TM1 ; }
  379. done
  380. } || loge "The defined custom blacklist file $i is not accessible"
  381. } >/dev/null 2>&1 || {
  382. echo "$i" | grep -Eq '^\+' && { sed -i "s/^[a-zA-Z0-9.-]\{0,64\}\.]\{0,1\}$(echo $i | cut -c2- | domain)\|^$(echo $i | cut -c2- | domain)//g" $TM ; echo $(echo $i | sed "s/^[a-zA-Z0-9.-]\{0,64\}\.]\{0,1\}$(echo $i | domain)\|^$(echo $i | domain)//g" | domain ) >> $TM1 ; } || { echo "$i" >> $TM1 ; }
  383. } >/dev/null 2>&1
  384. done
  385.  
  386. COUNT_CUSTOM=$(wc -l < $TM1)
  387. logi "Added $(echo $COUNT_CUSTOM|number) custom-blacklisted domains"
  388. # Append custom blacklist to FINAL
  389. cat $TM1 >> $TM && rm -f $TM1
  390. }
  391.  
  392. # WHITELISTING
  393.  
  394. # Hardcoded whitelisting:
  395. logi "Whitelisting domains used in other parts of FreshTomato"
  396. # System domains:
  397. subsed="freshtomato.org groov.pl linksysinfo.org"
  398. # TTB
  399. subsed="$subsed tomatothemebase.eu"
  400. for i in $(NG "ttb_url" | tr " " "\n" | domain); do subsed="$subsed ${i}"; done
  401.  
  402. # OpenVPN/PPTP/Tinc
  403. subsed="$subsed $(NG vpn_client1_addr | domain)"
  404. subsed="$subsed $(NG vpn_client2_addr | domain)"
  405. subsed="$subsed $(NG vpn_client3_addr | domain)"
  406. subsed="$subsed $(NG pptp_client_srvip | domain)"
  407. for i in $(NG tinc_hosts | tr "<>" "\n" | domain); do subsed="$subsed ${i}"; done
  408.  
  409. # NTP & Stubby
  410. for i in $(NG ntp_server | tr " " "\n" | domain); do subsed="$subsed ${i}"; done
  411. for i in $(NG stubby_resolvers | tr ">" "\n" | domain); do subsed="$subsed ${i}"; done
  412.  
  413. # DDNS and mwan test
  414. [ $(NG ddnsx0 | grep -Eo "^[a-zA-Z0-9]*" || echo 0) == "custom" ] && subsed="$subsed $(NG ddnsx0 | domain)" || subsed="$subsed $(grep "\['"$(NG ddnsx0 | grep -Eo "^[a-zA-Z0-9]*")"'" /www/basic-ddns.asp 2>/dev/null | domain | head -1)"
  415. [ $(NG ddnsx1 | grep -Eo "^[a-zA-Z0-9]*" || echo 0) == "custom" ] && subsed="$subsed $(NG ddnsx1 | domain)" || subsed="$subsed $(grep "\['"$(NG ddnsx1 | grep -Eo "^[a-zA-Z0-9]*")"'" /www/basic-ddns.asp 2>/dev/null | domain | head -1)"
  416. [ $(NG ddnsx_ip) == "@" ] && subsed="$subsed checkip.dyndns.org dynamic.zoneedit.com ip1.dynupdate.no-ip.com myip.dnsomatic.com myip.pairnic.com ip.changeip.com"
  417. [ $(NG mwan_cktime) -ne 0 ] && { for i in $(NG mwan_ckdst | tr "," "\n" | domain); do subsed="$subsed ${i}"; done; }
  418.  
  419. # Whitelist domains from list providers defined
  420. logi "Whitelisting domains defined in Blacklist URL"
  421. for i in $(echo $BLACKLIST | tr "<" "\n" | grep -E 'https?' | grep -Eo '((([a-zA-Z]{1,2})|([0-9]{1,2})|([a-zA-Z0-9]{1,2})|([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]))\.)+[a-zA-Z]{2,6}\s*/\s*' | tr "/" " "); do
  422. subsed="$subsed ${i}"
  423. done
  424.  
  425. # Whitelist domains defined in Group-of-lists content
  426. [[ -f $PREFIX/white.url ]] && {
  427. logd "Whitelisting domains found in Group-of-lists URLs"
  428. for i in $(grep -Eo '((([a-zA-Z]{1,2})|([0-9]{1,2})|([a-zA-Z0-9]{1,2})|([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]))\.)+[a-zA-Z]{2,6}\s*/\s*' $PREFIX/white.url | tr "/" " "); do
  429. subsed="$subsed ${i}"
  430. done
  431. }
  432.  
  433. # User-defined whitelisting:
  434. [ -f $TM1 ] && rm $TM1
  435. [ $(echo $WHITELIST | wc -c) -gt 2 ] && {
  436. logi "Whitelisting user-defined domains"
  437. # Individual domains
  438. [ ! -z ${WHITELIST+1} ] && for i in $(echo "$WHITELIST" | tr " " "\n" | grep -Ev '^($|#|!)' | grep -Ev '^/'); do subsed="$subsed ${i}"; done
  439. # User defined whitelist file
  440. [ ! -z ${WHITELIST+1} ] && for i in $(echo "$WHITELIST" | tr " " "\n" | grep -Ev '^($|#|!)' | grep -E '^/'); do if [[ -f ${i} ]]; then while IFS= read -r dom || [ -n "$dom" ]; do printf '%s\n' "$dom"; done < $i | grep -Ev '^($|#|!)' | tr -d "\r" >> $TM1 ; else loge "The defined whitelist file $i is not accessible"; erroradd ;fi done
  441. [ -s $TM1 ] && for i in $(cat $TM1); do subsed="$subsed ${i}"; done
  442. }
  443.  
  444. # Remove references to localhost
  445. subsed="$subsed localhost" # localhost to be fixed, used to be: "^address=\/localhost\/.*"
  446. [ $LOGL -eq 7 ] && echo "$subsed" > $TMP/adblock.subsed
  447. # Whitelisting phase A = Removing whitelisted domains (full match) and formatting the file for dnsmasq
  448. sed -i -e "/$(echo \"$subsed\" | sed 's/ /\\|^/g')/d" -e '/^$/d' -e 's/.*/local=\/&\//' $TM 2>/dev/null
  449. # sed -i -e "/$(echo $subsed | tr ' ' '\n' | grep -Ev '^%' | tr '\n' ' ' | sed 's/ /\\|^/g')/d" -e '/^$/d' -e "s/.*/local=\/&\//" $TM 2>/dev/null
  450. # Whitelisting phase B = Add exceptions for whitelisted subdomains whose parent domain is blacklisted
  451. whitish=$(echo \"$subsed\" | tr ' ' '\n' | grep -E '^[0-9a-z]|^%[0-9a-z]' | sed 's/^%//' | grep -E '^[^.]+\.([^.]+\.)+[^.]*$' | sort -u | while read k; do for p in $(w=$(echo "$k" | grep -Eo '\.\w.*+' | cut -c2-50) && grep "$w" $TM | grep -Eo $w | sort -u ); do [ ! -z $k ] && { echo "$k";} ; done ;done)
  452. [ $LOGL -eq 7 ] && echo "$whitish" >$TMP/adblock.whitish
  453. echo "${whitish}" | grep -vq ^$ && { echo "${whitish}" | tr " " "\n" | grep -v ^$ | while read l; do echo server=/*."$l"/# >> $TM ; done ;}
  454. # Whitelisting phase C = Handle strict whitelisted domains (don't allow any subdomain resolution)
  455. whitis=$(echo \"$subsed\" | tr ' ' '\n' | grep -v ^$ | grep -E '^%' | domain | while read l; do echo "$l"; done ;)
  456. [ $LOGL -eq 7 ] && echo "$whitis" >$TMP/adblock.whitis
  457. echo "${whitis}" | grep -vq ^$ && { echo "${whitis}" | tr ' ' '\n' | while read l; do echo server=/*."$l"/# >> $TM ; done ;}
  458.  
  459. # DE-DUPLICATION
  460. logn "Removing duplicates"
  461. pred=$(wc -l < $TM)
  462. [ $DPATH != '/etc' ] && {
  463. # Let's use external storage to halve the RAM needed for deduplication
  464. mv -f $TM $D
  465. awk '!seen[$0]++' $D/adblock.temp > $TM
  466. rm -f $D/adblock.temp
  467. } || {
  468. # No external storage available? No problem we'll use what we have
  469. awk '!seen[$0]++' $TM > $TM1 && mv -f $TM1 $TM
  470. }
  471. redun=$(($pred - $(wc -l < $TM) ))
  472. logi "Deduplication efficiency = $(printf "%.2f" $(( 10**2 * $redun * 100 / $pred ))e-2)"%" / $redun lines removed."
  473. # Applying sizeLimit
  474. # Trim down to the hard limit (trim from the top) the adblock file
  475. [ $(wc -c < $TM) -gt $sizeLimit ] && {
  476. logw "️$(wc -c < $TM ) bytes are too much. Please consider defining fewer and/or smaller lists of domains."
  477. logn "Trimming down $TM to the hardcoded limit of $(echo $sizeLimit | number) Bytes before proceeding."
  478. TRIM=$(( $(wc -l < $TM) - $(tail -c $sizeLimit < $TM | wc -l) +1 ))
  479. vi $TM -c ":1,${TRIM}d" -c ":wq"
  480. }
  481.  
  482. # Cleaning after myself
  483. [ $DPATH != '/etc' ] && cp -fp ${ADHEAD} ${D}
  484. mv -f $TM $FINAL
  485. rm -rf $PREFIX/*
  486. # Final verification
  487. [ -s "$FINAL" -a "$ENTRIES" -gt 0 ] || [ "$COUNT_CUSTOM" -ne 0 ] && {
  488. logi "$FINAL is now populated with $(wc -l < $FINAL | number) lines in $(wc -c < $FINAL | number) Bytes"
  489. echo "$(hashblack | md5sum | awk '{print $1}') md5black" > $CHK_FILE
  490. echo "$(hashwhite | md5sum | awk '{print $1}') md5white" >> $CHK_FILE
  491. hashblack >> $CHK_FILE
  492. hashwhite >> $CHK_FILE
  493. cru d adblockDL
  494. }
  495. }
  496.  
  497. parsefile() {
  498. [ -n "$4" ] && S="[$4]"
  499. if [ $(notin "$1" | head -500 | grep -iE '<html|<head|<body' | wc -l ) -gt 0 ]; then
  500. # Skip loop if CheckHTML is matched
  501. loge "[$3]$S[$2] List content not understood (HTML?). Skipping..."
  502. erroradd
  503. continue
  504. elif [ $(notin "$1" | head -500 | grep -iE '^\[.*]' | wc -l ) -gt 0 ]; then
  505. # Skip loop if Content is in Easylist/Adblock-Plus format
  506. loge "[$3]$S[$2] Detected Easylist format (unsupported). Skipping..."
  507. erroradd
  508. continue
  509. elif [ $(notin "$1" | head -500 | grep -E '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' | wc -l ) -gt 0 ]; then
  510. # Skip loop if IP-only is matched
  511. loge "[$3]$S[$2] List content not understood (IP-only?). Skipping..."
  512. erroradd
  513. continue
  514. elif [ $(notin "$1" | head -500 | domain | wc -l ) -gt 0 ]; then
  515. # Extract domains only
  516. logi "[$3]$S[$2] Extracting domains..."
  517. notin $1 | domain >> $TM
  518. else
  519. loge "[$3]$S[$2] List content not understood (unknown data). Skipping..."
  520. erroradd
  521. fi
  522. }
  523.  
  524. cronAdd() {
  525. cru l | grep -q adblockJob || {
  526. MINS=$((2 + $RANDOM % 56)) # Between 02 and 58min for each hour
  527. HOUR=$((3 + $RANDOM % 2)) # Between 03:02 and 05:58
  528. cru a adblockJob "$MINS $HOUR * * * /usr/sbin/adblock update"
  529. logi "Added cron job for automatic updates"
  530. }
  531. }
  532.  
  533. cronDel() {
  534. cru l | grep -q adblockJob && {
  535. cru d adblockJob
  536. logi "Removed cron job for updates"
  537. }
  538. }
  539.  
  540. countdownDnsmasq() {
  541. c=0; while [ "$(ps | grep '[d]nsmasq.*async$' | awk '{print $2}')" != "nobody" -a $c -lt 10 ]; do
  542. c=$((c+1)); sleep 2
  543. done
  544. [ ! -z "$(ps | grep '[d]nsmasq.*async$' | awk '{print $2}')" -a "$(ps | grep '[d]nsmasq.*async$' | awk '{print $2}')" == "nobody" ] && echo 0 || echo 1 ;
  545. }
  546.  
  547. safeDnsmasqRestart() {
  548. [ "$1" -eq 0 ] && { # Run only for update
  549. logi "Checking $FINAL syntax"
  550. # Case A = $FINAL syntax issue detected, log and exclude adblock until next reboot
  551. [ -s $FINAL ] && {
  552. dnsmasq --test -C $FINAL &>$TMP/adblock.dnsmasq.test && logi "No syntax errors found in $FINAL" || {
  553. NS adblock_enable=0
  554. dnsrestart
  555. loge "Syntax error found in $FINAL. Adblock has been temporarily excluded from /etc/dnsmasq.conf to prevent dnsmasq issues. More information on this error can be found in $TMP/adblock.dnsmasq.test"
  556. erroradd
  557. return 1
  558. }
  559. }
  560. }
  561. SIZE=$(wc -l < $FINAL)
  562. TRIM=$(echo $((( $SIZE / 100 ) * $TRIMPERC ))) # 5% of the entry filesize
  563. # Case B = dnsmasq restart correctly, e.g. ignore the other conditions and exit
  564. logi "Invoking safeDnsmasqRestart()"
  565. dnsrestart
  566. # Case C = dnsmasq didn't change ownership to nobody within 20 secs. Attempt a file trim:
  567. [ $(countdownDnsmasq) -eq 1 ] && {
  568. i=0; while [ ! -z "$(ps | grep '[d]nsmasq.*async$' | awk '{print $2}')" -a "$(ps | grep '[d]nsmasq.*async$' | awk '{print $2}')" != "nobody" -a $i -lt 10 ]; do
  569. # Attempts the trim maximum 10 times (up to 50% of the file)
  570. i=$((i+1))
  571. SIZEE=$(wc -l < $FINAL)
  572. LINES=$((SIZEE-TRIM))
  573. logw "Dnsmasq cannot handle $(echo $SIZEE | number) lines, they are still too many."
  574. logn "Trimming down $FINAL by $(echo $TRIMPERC)% to $(echo $LINES | number) lines"
  575. mv $FINAL "$FINAL.recovery"
  576. vi "$FINAL.recovery" -c ":1,${TRIM}d" -c ":wq"
  577. mv "$FINAL.recovery" $FINAL
  578. dnsrestart
  579. [ $(countdownDnsmasq) -eq 1 ] && continue || {
  580. sizeLimit=$(wc -c < $FINAL)
  581. NS adblock_limit=${sizeLimit}
  582. NC
  583. logi "safeDnsmasqRestart() successfully trimmed down $FINAL from $(echo $SIZE|number) to $(wc -l < $FINAL|number) lines. Now it should work."
  584. return 0
  585. }
  586. done
  587. # Case D = Shit happens; like for Case A, log and exclude adblock as a whole
  588. [ $(countdownDnsmasq) -eq 1 ] && { # this is run only if 10x trim is not good enough
  589. NS adblock_enable=0
  590. dnsrestart
  591. loge "safeDnsmasqRestart(). Something unexpected happened. Dnsmasq cannot run with adblock enabled. Adblock has been temporarily disabled."
  592. erroradd
  593. return
  594. }
  595. } || logi "safeDnsmasqRestart() completed smoothly with $FINAL = $(wc -l < $FINAL|number) lines in $(wc -c < $FINAL|number) Bytes."; return
  596. }
  597.  
  598. upgrade_check() {
  599. latest=$(yget -q -O - "$UURL" | grep -E '^ver=' | cut -c6-11)
  600. echo "$latest"
  601. }
  602.  
  603. upgrade() {
  604. latest=$(upgrade_check)
  605. [[ "$latest" != "$current" ]] && {
  606. logo "New version detected. Upgrading..."
  607. cat <<EOF > $TMP/upgrade_dblck.sh
  608. #!/bin/sh
  609. export PATH=/bin:/usr/bin:/sbin:/usr/sbin:/home/root:
  610. USERAGENT="Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/109.0"
  611. alias yget="wget --no-check-certificate -T 15 -q -U \"$USERAGENT\" --header \"Cache-Control: no-cache\""
  612. adblock stop
  613. mount | grep -q /usr/sbin/adblock && umount /usr/sbin/adblock
  614. [ -s "$TMP/new_adblock" ] && rm -f "$TMP/new_adblock" &>/dev/null
  615. yget "$UURL" -O- | tr -d "\r" > $TMP/new_adblock
  616. chmod +x $TMP/new_adblock
  617. mount --bind $TMP/new_adblock /usr/sbin/adblock
  618. echo "Upgrade completed. Now restarting from scratch..."
  619. adblock clear
  620. adblock update
  621. EOF
  622. chmod +x $TMP/upgrade_dblck.sh
  623. exec $TMP/upgrade_dblck.sh
  624. }
  625. }
  626.  
  627. adExit() {
  628. rm -rf $PREFIX/*
  629. rm -f $pidfile
  630. if [ $1 -eq 0 ]; then
  631. [ $DPATH != '/etc' ] && {
  632. rm -f /etc/dnsmasq.adblock
  633. ln -s $FINAL /etc/dnsmasq.adblock 2>/dev/null
  634. }
  635. safeDnsmasqRestart $1
  636. elif [ $1 -eq 1 ]; then
  637. [ -s $FINAL ] && mv -f $FINAL $UNLOADED
  638. [ $DPATH != '/etc' ] && rm -f /etc/dnsmasq.adblock
  639. rm -f $CHK_FILE
  640. dnsrestart
  641. for process in $(ps | grep [a]dblock | grep -v "status\|$PID" | awk '{print $1}'); do (kill -9 $process) &>/dev/null ; done
  642. elif [ $1 -eq 4 ]; then
  643. [ $DPATH != '/etc' ] && rm -rf $DPATH/*
  644. rm -fR $TMP/*
  645. rm -f /etc/dnsmasq.adblock
  646. dnsrestart
  647. fi
  648. [ $ERRCOUNT -gt 0 ] && logo "$ERRCOUNT error/s were experienced."
  649. runtime=$(date -d@$(( $(date +%s) - $pre)) -u +%H"h "%M"m "%Ss)
  650. echo "errors: ${ERRCOUNT}" > $ADHELPER
  651. echo "runtime: ${runtime}" >> $ADHELPER
  652. logo "Exiting $@ - Execution time: ${runtime}"
  653. exit $@
  654. }
  655.  
  656. # STARTS HERE --------------------------------------------------------------------------------
  657.  
  658. # Skip execution (and stop adblock if running) if internal DNS is disabled
  659. [ $(NG dhcpd_dmdns) -eq 0 -a $ENABLE -eq 1 ] && {
  660. loge "Internal DNS is disabled! Adblock/DNS-filtering is enabled but cannot run. Exiting..."
  661. echo "Internal DNS is disabled! Adblock/DNS-filtering is enabled but cannot run. Exiting..."
  662. erroradd
  663. cronDel
  664. adExit 2
  665. }
  666.  
  667. if [ "$1" == "status" ]; then
  668. [ ! -z $sizeLimit ] && max=$(echo $sizeLimit | number ) || max="Calculated at the next run"
  669. echo -e "
  670. ┌────────────────── FreshTomato ────────────────────┐
  671. │ │
  672. │ ${white}Adblock ${ver:0:6} ${black} │
  673. │ │
  674. ├───── Dnsmasq ─────────────────────────────────────┤
  675.  
  676. Running = $([ -f "/var/run/dnsmasq.pid" ] && echo "yes" || echo "${red}no${black}")
  677. Owner = $([ $(ps | grep '[d]nsmasq.*async$' | awk '{print $2}') == "root" ] && echo "${red}root${black}" || echo "nobody" )
  678. Restarts today = $(grep -E $(date +%b)" "+$(date +%d|sed 's/^0*//') /var/log/messages | grep -E '.*dnsmasq\[.*exiting' | wc -l )
  679. Restart time = $([ -f $DNS_TIME ] && cat $DNS_TIME || echo "N/A")
  680. Mapped adblock = $(grep -q 'conf-file=/etc/dnsmasq.adblock' /etc/dnsmasq.conf && echo "yes" || echo "${red}no${black}")
  681.  
  682. ├────── Adblock ────────────────────────────────────┤
  683.  
  684. Calls today = $(grep -E $(date +%b)" "+$(date +%d|sed 's/^0*//') /var/log/messages | grep "Kick off" | wc -l )
  685. Activity = $([ -f ${pidfile} ] && { [ -f ${VRFY} ] && echo "${white}Checking...${black}" || echo "${white}Running...${black}" ;} || echo "Idle" )
  686. Last trace = $([ $LOGL -eq 7 -a $(ls -1tr $TMP/adblock.debug.* 2>/dev/null | tail -1 | wc -l ) -gt 0 ] && echo $(ls -1tr $TMP/adblock.debug.* | tail -1) )
  687. Hold-time = $([ -s $CHK_FILE -a -s $FINAL ] && { HOLD_LEFT=$(( ${hold} - ($(date +%s) - $(date -r "$FINAL" +%s)) /60 )) ; [ "$HOLD_LEFT" -le ${hold} -a "$HOLD_LEFT" -gt 0 -a $(hashblack | md5sum | awk '{print $1}') == $(cat ${CHK_FILE} | grep md5black | grep -Eo ^[a-zA-Z0-9]{32}) ] && echo -e "${white}On${black} ~ ${HOLD_LEFT}min left" || echo "off" ;} || echo "off" )
  688.  
  689. ├──── Blockfile ────────────────────────────────────┤"
  690. if [ -s "$FINAL" ]; then echo -e "
  691. State = Loaded
  692. Destination = $DPATH
  693. References = $(wc -l < $FINAL| number ) Domains
  694. File size = $(wc -c < $FINAL| number ) Bytes
  695. Maximum size = $(echo $max) Bytes
  696. File date = $(ls -lah $FINAL | awk '{print $8" on "$7" "$6}')
  697. "
  698. elif [ -s "$UNLOADED" ]; then echo -e "
  699. State = ${grey}Parked${black}
  700. Destination = $DPATH
  701. References = $(wc -l < $UNLOADED| number) Domains
  702. File size = $(ls -l $UNLOADED | awk '{ print $5}' | number ) Bytes
  703. Maximum size = $max Bytes
  704. File date = $(ls -lah $UNLOADED | awk '{print $8" on "$7" "$6}')
  705. "
  706. elif [ -f "$TM" ]; then echo -e "
  707. State = ${white}Loading...${black}
  708. Destination = $DPATH
  709. References = $(wc -l < $TM| number) Domains
  710. File size = $(ls -l $TM | awk '{ print $5}' | number ) Bytes
  711. Maximum size = $max Bytes
  712. File date = $(ls -lah $TM | awk '{print $8" on "$7" "$6}')
  713. "
  714. fi
  715. echo " └───────────────────────────────────────────────────┘
  716. "
  717. exit
  718. elif [ "$1" == "status-gui" ]; then
  719. restarts=$(grep -E $(date +%b)" "+$(date +%d|sed 's/^0*//') /var/log/messages | grep -E '.*dnsmasq\[.*exiting' | wc -l )
  720. [ ! -z $sizeLimit ] && max=$(echo $sizeLimit | number ) || max="Calculated at the next run"
  721. ramt=$(grep 'MemTotal:' /proc/meminfo | awk '{print $2}')
  722. ramu=$(free | grep buffer | awk '{print $3}')
  723. ramc=$(grep -E '^Cached:' /proc/meminfo | awk '{print $2}')
  724. ramb=$(grep 'Buffers:' /proc/meminfo | awk '{print $2}')
  725. rampu=$(( $ramu * 100 / $ramt ))
  726. rampc=$(( $ramc * 100 / $ramt ))
  727. rampb=$(( $ramb * 100 / $ramt ))
  728. echo -e "Version: ${ver:0:6}<br>
  729. System Load = $(cat /proc/loadavg | awk '{print "<b>"$1" / "$2" / "$3"</b>"}')<br>
  730. Ram Used/Cache/Buffer / Total = <b>${rampu}% ~ $(echo $ramu | number)</b>/$(echo $ramc | number)/$(echo $ramb | number)<b> / $(echo $ramt | number) KBytes</b><br>
  731. <div class=\"progress-container\" style=\"width:400px;float:left;display:flex;flex:1\">
  732. <div class=\"progress-bar\" style=\"background-color:#005691;width: ${rampu}%\"></div>
  733. <div class=\"progress-bar\" style=\"background-color:#CDA5F3;width: ${rampc}%\"></div>
  734. <div class=\"progress-bar\" style=\"background-color:#74CDC1;width: ${rampb}%\"></div></div><br>
  735. Dnsmasq running = $(echo $([ -f "/var/run/dnsmasq.pid" ] && echo "<b>Yes 🆗</b>" || echo "<b>no ⛔</b>"))<br>
  736. Dnsmasq restarts today = $(echo "<b> $restarts </b>")<br>
  737. Dnsmasq owner = $(ps | grep -q '[d]nsmasq.*async$' && [ $(ps | grep '[d]nsmasq.*async$' | awk '{print $2}') == "root" ] && echo "<b>root ️⛔</b> <img src=\"spin.gif\" heigh=\"8px\" width=\"8px\">" || echo "<b>nobody 🆗</b>" )<br>
  738. Dnsmasq restart time = $([ -f $DNS_TIME ] && echo \<b\>$(cat $DNS_TIME)\</b\> || echo "<b>N/A"\</b\>)<br>
  739. Adblock calls today = <b>$(grep -E $(date +%b)" "+$(date +%d|sed 's/^0*//') /var/log/messages | grep "Kick off" | wc -l )</b><br>
  740. Adblock config loaded = $(echo $(grep -q 'conf-file=/etc/dnsmasq.adblock' /etc/dnsmasq.conf && echo "<b>Yes 🆗</b>" || echo "<b>No ⛔</b>"))<br>
  741. Adblock script activity = $(echo $([ -f "/var/run/adblock.pid" ] && { [ -f ${VRFY} ] && echo "👁️ <b>Checking...<img src=\"spin.gif\" heigh=\"8px\" width=\"8px\"></b>" || echo "🌀 <b>Loading... $([ -s $TM ] && { wc -l < $TM | number ;}) domains / $([ -s $TM ] && { wc -c < $TM | number ;} ) Bytes <img src=\"spin.gif\" heigh=\"8px\" width=\"8px\"></b>" ;} || echo "<b>idle</b>"))<br>"
  742. [ -s "$FINAL" -a $(grep 'conf-file=/etc/dnsmasq.adblock' /etc/dnsmasq.conf | wc -l) -eq 1 ] && {
  743. filp=$(($(wc -c < $FINAL) * 100 / $([ $(echo $sizeLimit | wc -c 2>/dev/null ) -gt 0 ] && echo $sizeLimit || echo 99999999)))
  744. lre=$(grep 'error' $ADHELPER | awk '{print $2}')
  745. echo "Last run errors = <b>$lre"
  746. [ $lre -gt 0 ] && echo " ⚠️"
  747. echo -e "</b><br>
  748. Last run processing time = <b>$(grep 'runtime' $ADHELPER | cut -d: -f2)</b><br>
  749. Blockfile references = $(echo \<b\>$(wc -l < $FINAL| number) Domains\</b\> )<br>
  750. Blockfile date = $(echo \<b\>$(ls -lah $FINAL | awk '{print $8" on "$7" "$6}'))</b><br>
  751. Blockfile size/limit = <b>${filp}% ~ $(wc -c < $FINAL| number) / $(echo $max | number) Bytes</b><br>
  752. <div class=\"progress-wrapper\"><div class=\"progress-container\" style=\"width:400px\"><div class=\"progress-bar\" style=\"background-color:#005691;width: ${filp}%\"></div></div></div><br>"
  753. }
  754. [ $LOGL -eq 7 ] && { echo -e "✏️ Running in trace mode" ; [ $(ls -1tr $TMP/adblock.debug.* 2>/dev/null | tail -1 | wc -l) -gt 0 ] && { echo ", output redirected to <code>$(ls -1tr $TMP/adblock.debug.* | tail -1)</code><br>"; } ;}
  755. [ -s $CHK_FILE -a -s $FINAL ] && { HOLD_LEFT=$(( $hold - ($(date +%s) - $(date -r "$FINAL" +%s)) /60 )) ; [ "$HOLD_LEFT" -le $hold -a "$HOLD_LEFT" -gt 0 -a $(hashblack | md5sum | awk '{print $1}') == $(cat ${CHK_FILE} | grep md5black | grep -Eo ^[a-zA-Z0-9]{32}) ] && echo -e "⏲️ ${hold}min hold-time is active. ${HOLD_LEFT}min left<br>" ;}
  756. exit
  757. elif [ "$1" == "reset" ]; then
  758. nvram unset adblock_limit
  759. setlimit
  760. exit
  761. elif [ "$1" == "clear" -o "$1" == "clean" ]; then
  762. logi "Clearing up all the file relevant to Adblock/DNS-filtering from the filesystem."
  763. echo "Clearing up all the file relevant to Adblock/DNS-Filtering from the filesystem."
  764. adExit 4
  765. elif [ "$1" == "test" ]; then
  766. [ $# -eq 2 -a $(echo $2 | domain | wc -l) -gt 0 ] && {
  767. dom=$(echo $2 | domain)
  768. int=$(nslookup $dom 127.0.0.1 2>/dev/null | grep -A999 ^$ | grep Address || echo "${grey}Unresolvable")
  769. ext=$(nslookup $dom 1.1.1.1 2>/dev/null | grep -A999 ^$ | grep Address || echo "${grey}Unresolvable")
  770. [ "$ext" != "${grey}Unresolvable" -a "$int" == "${grey}Unresolvable" ] && int=$(echo "${red}Blocked")
  771. if [ $(grep -E "^server=/(\.)?$dom/" $FINAL | wc -l ) -gt 0 ]; then
  772. blo="${green}$(grep -E "^server=/(\.)?$dom/" $FINAL)"
  773. elif [ $(grep -E "^local=/(\.)?$dom/" $FINAL | wc -l ) -gt 0 ]; then
  774. blo="${red}$(grep -E "^local=/(\.)?$dom/" $FINAL)"
  775. else
  776. blo="${grey}Not found"
  777. fi
  778. echo -en "
  779. ─────────────────────────────────── adblock test ──
  780. ── dnsmasq answer ─────────────────────────────────${green}
  781. $int${black}
  782. ── cloudflare answer ──────────────────────────────${white}
  783. $ext${black}
  784. ── Blockfile ref: $(grep -E "/(\.)?$dom/" $FINAL | wc -l) $FINAL
  785. $blo${black}
  786. ───────────────────────────────────────────────────
  787. "
  788. echo -e "───────────────────────────────── test completed ──
  789. "
  790. } || echo -e "Please provide an indivudual domain to be tested e.g.: ${white}adblock test example.com${black}"; exit
  791. elif [ "$1" == "help" ]; then
  792. echo -e "
  793. ┌────────────────── FreshTomato ────────────────────┐
  794. │ │
  795. │ ${white}Adblock ${ver:0:6} ${black} │
  796. │ │
  797. ├───────────────────────────────────────────────────┤
  798. │ │
  799. │ - Supported command line options - │
  800. │ │
  801. │ ${white}help${black} This screen │
  802. │ ${white}status${black} General running info │
  803. │ │
  804. │ ${white}start${black} Same as no parameter: will load │
  805. │ ${white}stop${black} Will unload the script │
  806. │ ${white}update${black} Update lists while script is running │
  807. │ ${white}upgrade${black} Upgrades the script to latest version │
  808. │ │
  809. │ ${white}test example.com${black} Verify domain resolution │
  810. │ │
  811. │ ${white}reset${black} Resets the maximum filesize │
  812. │ ${white}clear${black} Remove any relevant file found │
  813. │ ${white}trace${black} Displays the very last trace file │
  814. │ ${white}snapshot${black} Stores info into $TMP/debug.adblock │
  815. │ │
  816. │ ${white}enable${black} Enable adblock │
  817. │ ${white}disable${black} Disable adblock │
  818. │ │
  819. └───────────────────────────────────────────────────┘
  820. "
  821. exit
  822. elif [ "$1" == "upgrade" ]; then
  823. [ $# -eq 2 ] && { [ $2 == "silent" ] && {
  824. upgrade
  825. logi "Silent upgrade running..."
  826. exit
  827. }; }
  828. latest=$(upgrade_check)
  829. [[ "$latest" != "$current" ]] && {
  830. echo -e "Current script version: ${yellow}$current${black} / Latest version: ${green}$latest${black}"
  831. read -n1 -p ""$'Do you want to perform an upgrade?\ny/n\n' -s ans
  832. [ $ans == "y" ] && upgrade || exit
  833. } || echo -e "Already on the latest version = ${white}$latest${black}"
  834. exit
  835. elif [ "$1" == "trace" ]; then
  836. [ $(ls -1t $TMP/adblock.debug.* 2>/dev/null | wc -l ) -gt 0 ] && {
  837. echo $(ls -1t $TMP/adblock.debug.* | head -n 1)
  838. read -n1 -p "press c for cat | l for less | m for more | n for nano | v for vi | any other key to quit"$'\n' -s ans
  839. if [[ -z $ans ]]; then
  840. exit
  841. elif [[ $ans == "c" ]]; then
  842. cat < $(ls -1t $TMP/adblock.debug.* | head -n 1)
  843. elif [[ $ans == "l" ]]; then
  844. less < $(ls -1t $TMP/adblock.debug.* | head -n 1)
  845. elif [[ $ans == "m" ]]; then
  846. more < $(ls -1t $TMP/adblock.debug.* | head -n 1)
  847. elif [[ $ans == "n" ]]; then
  848. nano $(ls -1t $TMP/adblock.debug.* | head -n 1)
  849. elif [[ $ans == "v" ]]; then
  850. vi $(ls -1t $TMP/adblock.debug.* | head -n 1)
  851. else
  852. exit
  853. fi
  854. }
  855. exit
  856. elif [ "$1" == "stop" ]; then
  857. cronDel
  858. logo "Stopping Adblock/DNS-filtering..."
  859. echo "Stopping Adblock/DNS-filtering..."
  860. adExit 1
  861. elif [ "$1" == "enable" ]; then
  862. logo "️ Enabled Adblock/DNS-filtering..."
  863. NS adblock_enable=1 ; NC
  864. echo -e "Adblock has been enabled (adblock set adblock_enable=1)"
  865. exit
  866. elif [ "$1" == "disable" ]; then
  867. logo "Disabled Adblock/DNS-filtering..."
  868. NS adblock_enable=0 ; NC
  869. echo -e "Adblock has been disabled (adblock set adblock_enable=0)"
  870. exit
  871. elif [ "$1" == "snapshot" ]; then
  872. now=$(date +%s)
  873. echo -e "" > $TMP/adblock.snapshot.$now
  874. (
  875. echo -e "\n---/ ls -l $TMP/adblock/ "
  876. ls -l $TMP/adblock/
  877. echo -e "\n--- ls -lp /etc/dnsmasq*"
  878. ls -lp /etc/dnsmasq*
  879. echo -e "\n--- ls -lp $TMP/adbloc*"
  880. ls -lp $TMP/adbloc*
  881. echo -e "\n--- cat $TMP/adblock.time"
  882. cat $TMP/adblock.time
  883. echo -e "\n--- Current config/lists"
  884. echo -e $(hashblack)
  885. echo -e $(hashwhite)
  886. echo -e "\n--- ls -lp $TMP/dnsmasq*"
  887. ls -lp $TMP/dnsmasq*
  888. [ $PATH != '/etc' ] && echo -e "\n--- ls -l $DPATH/*"; ls -l $DPATH/*
  889. echo -e "\n--- ls -l /var/run/ | grep -E '*adblock.pid$|*dnsmasq.pid$'"
  890. ls -l /var/run/ | grep -E '.*adblock.pid$|.*dnsmasq.pid$'
  891. ) >> $TMP/adblock.snapshot.$now 2>/dev/null
  892.  
  893. echo -e "Debug output saved to file. Use cat $TMP/adblock.snapshot.$now to view"
  894. logo "Snapshot taken and saved in $TMP/adblock.snapshot.$now"
  895. exit
  896. elif [ "$1" == "update" -o "$1" == "start" -o $# -eq 0 ]; then
  897. if [ "$ENABLE" -eq "1" ]; then {
  898. [ ! -f $pidfile ] && echo $PID > $pidfile
  899. while [ $(date +%Y) -lt 2022 ]; do { sleep 5; pre=$(date +%s); } done
  900. [ -s "$FINAL" ] && {
  901. HOLD_LEFT=$(( $hold - ($(date +%s) - $(date -r "$FINAL" +%s)) /60))
  902. [ "$HOLD_LEFT" -lt $hold -a "$HOLD_LEFT" -gt 0 -a $(hashblack | md5sum | awk '{print $1}') == $([ -s "$CHK_FILE" ] && { grep 'md5black' "${CHK_FILE}" | grep -Eo ^[a-zA-Z0-9]{32} ;} || echo "0") -a $(hashwhite | md5sum | awk '{print $1}') == $([ -s "$CHK_FILE" ] && { cat ${CHK_FILE} | grep md5white | grep -Eo ^[a-zA-Z0-9]{32} ;} || echo "0") -a $( [ -s ${ADHEAD} ] && { cat ${ADHEAD} | grep -Ev ' 0$' | wc -l; } || echo 1 ) -eq 0 ] && {
  903. logw "The last update was performed less then ${hold}min ago (${HOLD_LEFT}min left) and no modification to the config have been detected since. Skipping script execution for now..."
  904. echo "The last update was performed less then ${hold}min ago (${HOLD_LEFT}min left) and no modification to the config have been detected since. Skipping script execution for now..."
  905. adExit 5
  906. }
  907. }
  908. # Tweak kernel parameter for memory allocation
  909. [ $(cat /proc/sys/vm/overcommit_ratio) -le 90 ] && echo 90 > /proc/sys/vm/overcommit_ratio
  910. setlimit
  911. days=$(( 60 * 60 * 24 * 15 )) #15 days
  912. [ $DPATH != '/etc' ] && {
  913. el=$(echo "$BLACKLIST" | grep -Ev '^$' | tr " " "_" | tr ">" "\n" | grep ^1 | cut -d "<" -f2 | sed -e 's/_$//' -e 's/^[ \t]*//' | while read line; do echo $line | md5sum | awk '{print $1}' ;done)
  914. ls -1 $DPATH | grep -v "adblock\|$el" | while read line; do
  915. [ $(($(date +%s) - $days)) -gt $(date -r $DPATH/$line +%s) ] && {
  916. rm -fr $DPATH/$line &>/dev/null
  917. logi "Removing unused (and 15+ days old) file $DPATH/$line"
  918. }
  919. done
  920. }
  921. [ "$1" == "update" ] && {
  922. logn "Updating lists"
  923. rm -f ${UNLOADED}
  924. download
  925. } || {
  926. [ -s $UNLOADED ] && { mv $UNLOADED $FINAL ; logn "Using saved version of the blockfile for quick start-up" ; } || download
  927. }
  928. cronAdd
  929. }
  930. elif [ "$ENABLE" -eq "0" ]; then
  931. logw "Adblock/DNS-filtering is disabled! Exiting..."
  932. echo "Adblock/DNS-filtering is disabled! Exiting..."
  933. adExit 3
  934. fi
  935. else
  936. echo -e " ${white}$1${black} = parameter not understood. Typo?"
  937. exit
  938. fi
  939. adExit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement