You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
10 KiB

  1. #!/bin/sh /etc/rc.common
  2. # Copyright (c) 2015-2022 Dirk Brenken (dev@brenken.org)
  3. # This is free software, licensed under the GNU General Public License v3.
  4. # disable (s)hellcheck in release
  5. # shellcheck disable=all
  6. START=30
  7. USE_PROCD=1
  8. if [ -n "$(type -t extra_command)" ]; then
  9. extra_command "suspend" "Suspend adblock processing"
  10. extra_command "resume" "Resume adblock processing"
  11. extra_command "query" "<domain> Query active blocklists and backups for a specific domain"
  12. extra_command "report" "[[<cli>|<mail>|<gen>|<json>] [<count>] [<search>]] Print DNS statistics with an optional search parameter"
  13. extra_command "list" "[<add>|<add_sha>|<add_utc>|<add_eng>|<add_stb>|<remove>|<remove_sha>|<remove_utc>|<remove_eng>|<remove_stb>] <source(s)> List/Edit available sources"
  14. extra_command "timer" "[<add> <tasks> <hour> [<minute>] [<weekday>]]|[<remove> <line no.>] List/Edit cron update intervals"
  15. else
  16. EXTRA_COMMANDS="status suspend resume query report list timer version"
  17. EXTRA_HELP=" status Service status
  18. suspend Suspend adblock processing
  19. resume Resume adblock processing
  20. query <domain> Query active blocklists and backups for a specific domain
  21. report [[<cli>|<mail>|<gen>|<json>] [<count>] [<search>]] Print DNS statistics with an optional search parameter
  22. list [<add>|<add_sha>|<add_utc>|<add_eng>|<add_stb>|<remove>|<remove_sha>|<remove_utc>|<remove_eng>|<remove_stb>] <source(s)> List/Edit available sources
  23. timer [<add> <tasks> <hour> [<minute>] [<weekday>]]|[<remove> <line no.>] List/Edit cron update intervals"
  24. fi
  25. adb_init="/etc/init.d/adblock"
  26. adb_script="/usr/bin/adblock.sh"
  27. adb_pidfile="/var/run/adblock.pid"
  28. if [ -s "${adb_pidfile}" ] && { [ "${action}" = "start" ] || [ "${action}" = "stop" ] ||
  29. [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "report" ] ||
  30. [ "${action}" = "suspend" ] || [ "${action}" = "resume" ] || [ "${action}" = "query" ] ||
  31. { [ "${action}" = "list" ] && [ -n "${1}" ]; }; }; then
  32. exit 0
  33. fi
  34. boot() {
  35. [ -s "${adb_pidfile}" ] && : >"${adb_pidfile}"
  36. rc_procd start_service
  37. }
  38. start_service() {
  39. if "${adb_init}" enabled; then
  40. if [ "${action}" = "boot" ]; then
  41. [ -n "$(uci_get adblock global adb_trigger)" ] && return 0
  42. fi
  43. procd_open_instance "adblock"
  44. procd_set_param command "${adb_script}" "${@}"
  45. procd_set_param pidfile "${adb_pidfile}"
  46. procd_set_param nice "$(uci_get adblock global adb_nice "0")"
  47. procd_set_param stdout 1
  48. procd_set_param stderr 1
  49. procd_close_instance
  50. fi
  51. }
  52. reload_service() {
  53. rc_procd start_service reload
  54. }
  55. stop_service() {
  56. rc_procd "${adb_script}" stop
  57. }
  58. restart() {
  59. rc_procd start_service restart
  60. }
  61. suspend() {
  62. rc_procd start_service suspend
  63. }
  64. resume() {
  65. rc_procd start_service resume
  66. }
  67. query() {
  68. rc_procd "${adb_script}" query "${1}"
  69. }
  70. report() {
  71. rc_procd "${adb_script}" report "${1:-"cli"}" "${2}" "${3}"
  72. }
  73. list() {
  74. local src_archive src_file src_enabled enabled name utc_list size focus descurl action="${1}"
  75. if [ "${action%_*}" = "add" ] || [ "${action%_*}" = "remove" ]; then
  76. shift
  77. for name in "${@}"; do
  78. case "${action}" in
  79. "add")
  80. if ! uci_get adblock global adb_sources | grep -q "${name}"; then
  81. uci_add_list adblock global adb_sources "${name}"
  82. printf "%s\n" "::: adblock source '${name}' added to config"
  83. fi
  84. ;;
  85. "remove")
  86. if uci_get adblock global adb_sources | grep -q "${name}"; then
  87. uci_remove_list adblock global adb_sources "${name}"
  88. printf "%s\n" "::: adblock source '${name}' removed from config"
  89. fi
  90. ;;
  91. "add_utc")
  92. if ! uci_get adblock global adb_utc_sources | grep -q "${name}"; then
  93. uci_add_list adblock global adb_utc_sources "${name}"
  94. printf "%s\n" "::: adblock utcapitole '${name}' added to config"
  95. fi
  96. ;;
  97. "remove_utc")
  98. if uci_get adblock global adb_utc_sources | grep -q "${name}"; then
  99. uci_remove_list adblock global adb_utc_sources "${name}"
  100. printf "%s\n" "::: adblock utcapitole '${name}' removed from config"
  101. fi
  102. ;;
  103. "add_eng")
  104. if ! uci_get adblock global adb_eng_sources | grep -q "${name}"; then
  105. uci_add_list adblock global adb_eng_sources "${name}"
  106. printf "%s\n" "::: adblock energized '${name}' added to config"
  107. fi
  108. ;;
  109. "remove_eng")
  110. if uci_get adblock global adb_eng_sources | grep -q "${name}"; then
  111. uci_remove_list adblock global adb_eng_sources "${name}"
  112. printf "%s\n" "::: adblock energized '${name}' removed from config"
  113. fi
  114. ;;
  115. "add_stb")
  116. if ! uci_get adblock global adb_stb_sources | grep -q "${name}"; then
  117. uci_add_list adblock global adb_stb_sources "${name}"
  118. printf "%s\n" "::: adblock stevenblack '${name}' added to config"
  119. fi
  120. ;;
  121. "remove_stb")
  122. if uci_get adblock global adb_stb_sources | grep -q "${name}"; then
  123. uci_remove_list adblock global adb_stb_sources "${name}"
  124. printf "%s\n" "::: adblock stevenblack '${name}' removed from config"
  125. fi
  126. ;;
  127. esac
  128. done
  129. [ -n "$(uci -q changes adblock)" ] && { uci_commit adblock; "${adb_init}" start; }
  130. else
  131. src_archive="$(uci_get adblock global adb_srcarc "/etc/adblock/adblock.sources.gz")"
  132. src_file="$(uci_get adblock global adb_srcfile "/tmp/adb_sources.json")"
  133. src_enabled="$(uci -q show adblock.global.adb_sources)"
  134. [ -r "${src_archive}" ] && zcat "${src_archive}" >"${src_file}" || printf "%s\n" "::: adblock source archive '${src_archive}' not found"
  135. if [ -r "${src_file}" ]; then
  136. src_enabled="${src_enabled#*=}"
  137. src_enabled="${src_enabled//\'}"
  138. printf "%s\n" "::: Available adblock sources"
  139. printf "%s\n" ":::"
  140. printf "%-25s%-10s%-7s%-21s%s\n" " Name" "Enabled" "Size" "Focus" "Info URL"
  141. printf "%s\n" " -------------------------------------------------------------------"
  142. json_load_file "${src_file}"
  143. json_get_keys keylist
  144. for key in ${keylist}; do
  145. json_select "${key}"
  146. json_get_var size "size"
  147. json_get_var focus "focus"
  148. json_get_var descurl "descurl"
  149. json_get_var url "url"
  150. json_get_var rule "rule"
  151. if [ -n "${url}" ] && [ -n "${rule}" ]; then
  152. if printf "%s" "${src_enabled}" | grep -q "${key}"; then
  153. enabled="x"
  154. else
  155. enabled=" "
  156. fi
  157. src_enabled="${src_enabled/${key}}"
  158. printf " + %-21s%-10s%-7s%-21s%s\n" "${key:0:20}" "${enabled}" "${size:0:3}" "${focus:0:20}" "${descurl:0:50}"
  159. else
  160. src_enabled="${src_enabled} ${key}"
  161. fi
  162. json_select ..
  163. done
  164. utc_list="$(uci_get adblock global adb_utc_sources "-")"
  165. eng_list="$(uci_get adblock global adb_eng_sources "-")"
  166. stb_list="$(uci_get adblock global adb_stb_sources "-")"
  167. printf "%s\n" " ---------------------------------------------------------------------------"
  168. printf " * %s\n" "Configured utcapitole categories: ${utc_list// /, }"
  169. printf " * %s\n" "Configured energized variants: ${eng_list// /, }"
  170. printf " * %s\n" "Configured stevenblack variants: ${stb_list// /, }"
  171. if [ -n "${src_enabled// }" ]; then
  172. printf "%s\n" " ---------------------------------------------------------------------------"
  173. printf "%s\n" " Sources with invalid configuration"
  174. printf "%s\n" " ---------------------------------------------------------------------------"
  175. for key in ${src_enabled}; do
  176. printf " - %s\n" "${key:0:20}"
  177. done
  178. fi
  179. else
  180. printf "%s\n" "::: adblock source file '${src_file}' not found"
  181. fi
  182. fi
  183. }
  184. status() {
  185. status_service
  186. }
  187. status_service() {
  188. local key keylist value idxval values type rtfile
  189. rtfile="$(uci_get adblock global adb_rtfile "/tmp/adb_runtime.json")"
  190. json_load_file "${rtfile}" >/dev/null 2>&1
  191. json_get_keys keylist
  192. if [ -n "${keylist}" ]; then
  193. printf "%s\n" "::: adblock runtime information"
  194. for key in ${keylist}; do
  195. json_get_var value "${key}" >/dev/null 2>&1
  196. if [ "${key%_*}" = "active" ]; then
  197. printf " + %-15s : " "${key}"
  198. json_select "${key}" >/dev/null 2>&1
  199. values=""
  200. index="1"
  201. while json_get_type type "${index}" && [ "${type}" = "object" ]; do
  202. json_get_values idxval "${index}" >/dev/null 2>&1
  203. if [ "${index}" = "1" ]; then
  204. values="${idxval}"
  205. else
  206. values="${values}, ${idxval}"
  207. fi
  208. index="$((index + 1))"
  209. done
  210. values="$(printf "%s" "${values}" | awk '{NR=1;max=98;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max)}else{printf"%-22s%s\n","",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}')"
  211. printf "%s\n" "${values:-"-"}"
  212. json_select ".."
  213. else
  214. printf " + %-15s : %s\n" "${key}" "${value:-"-"}"
  215. fi
  216. done
  217. else
  218. printf "%s\n" "::: no adblock runtime information available"
  219. fi
  220. }
  221. timer() {
  222. local cron_file cron_content cron_lineno action="${1:-"list"}" cron_tasks="${2}" hour="${3}" minute="${4:-0}" weekday="${5:-"*"}"
  223. cron_file="/etc/crontabs/root"
  224. if [ -s "${cron_file}" ] && [ "${action}" = "list" ]; then
  225. awk '{print NR "> " $0}' "${cron_file}"
  226. elif [ -x "/etc/init.d/cron" ] && [ "${action}" = "add" ]; then
  227. hour="${hour//[[:alpha:]]/}"
  228. minute="${minute//[[:alpha:]]/}"
  229. if [ -n "${cron_tasks}" ] && [ -n "${hour}" ] && [ -n "${minute}" ] && [ -n "${weekday}" ] &&
  230. [ "${hour}" -ge 0 ] && [ "${hour}" -le 23 ] &&
  231. [ "${minute}" -ge 0 ] && [ "${minute}" -le 59 ]; then
  232. printf "%02d %02d %s\n" "${minute}" "${hour}" "* * ${weekday} ${adb_init} ${cron_tasks}" >>"${cron_file}"
  233. /etc/init.d/cron restart
  234. fi
  235. elif [ -x "/etc/init.d/cron" ] && [ -s "${cron_file}" ] && [ "${action}" = "remove" ]; then
  236. cron_tasks="${cron_tasks//[[:alpha:]]/}"
  237. cron_lineno="$(awk 'END{print NR}' "${cron_file}")"
  238. cron_content="$(awk '{print $0}' "${cron_file}")"
  239. if [ "${cron_tasks:-"0"}" -le "${cron_lineno:-"1"}" ] && [ -n "${cron_content}" ]; then
  240. printf "%s\n" "${cron_content}" | awk "NR!~/^${cron_tasks}$/" >"${cron_file}"
  241. /etc/init.d/cron restart
  242. fi
  243. fi
  244. }
  245. service_triggers() {
  246. local iface delay
  247. iface="$(uci_get adblock global adb_trigger)"
  248. delay="$(uci_get adblock global adb_triggerdelay "5")"
  249. PROCD_RELOAD_DELAY="$((delay * 1000))"
  250. [ -n "${iface}" ] && procd_add_interface_trigger "interface.*.up" "${iface}" "${adb_init}" "start"
  251. procd_add_reload_trigger "adblock"
  252. }