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.

371 lines
11 KiB

  1. #!/bin/sh /etc/rc.common
  2. # Copyright (c) 2015-2021 Dirk Brenken (dev@brenken.org)
  3. # This is free software, licensed under the GNU General Public License v3.
  4. # set (s)hellcheck exceptions
  5. # shellcheck disable=1091,2010,2016,2034,2039,2059,2086,2091,2129,2143,2154,2181,2183,2188
  6. START=30
  7. USE_PROCD=1
  8. if [ -n "$(type -t extra_command)" ]
  9. then
  10. extra_command "suspend" "Suspend adblock processing"
  11. extra_command "resume" "Resume adblock processing"
  12. extra_command "query" "<domain> Query active blocklists and backups for a specific domain"
  13. extra_command "report" "[[<cli>|<mail>|<gen>|<json>] [<count>] [<search>]] Print DNS statistics with an optional search parameter"
  14. 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"
  15. extra_command "timer" "[<add> <tasks> <hour> [<minute>] [<weekday>]]|[<remove> <line no.>] List/Edit cron update intervals"
  16. extra_command "version" "Print version information"
  17. else
  18. EXTRA_COMMANDS="status suspend resume query report list timer version"
  19. EXTRA_HELP=" status Service status
  20. suspend Suspend adblock processing
  21. resume Resume adblock processing
  22. query <domain> Query active blocklists and backups for a specific domain
  23. report [[<cli>|<mail>|<gen>|<json>] [<count>] [<search>]] Print DNS statistics with an optional search parameter
  24. 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
  25. timer [<add> <tasks> <hour> [<minute>] [<weekday>]]|[<remove> <line no.>] List/Edit cron update intervals
  26. version Print version information"
  27. fi
  28. adb_init="/etc/init.d/adblock"
  29. adb_script="/usr/bin/adblock.sh"
  30. adb_pidfile="/var/run/adblock.pid"
  31. if [ -s "${adb_pidfile}" ] && { [ "${action}" = "start" ] || [ "${action}" = "stop" ] || \
  32. [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "report" ] || \
  33. [ "${action}" = "suspend" ] || [ "${action}" = "resume" ] || [ "${action}" = "query" ] || \
  34. { [ "${action}" = "list" ] && [ -n "${1}" ]; }; }
  35. then
  36. exit 0
  37. fi
  38. version()
  39. {
  40. rc_procd "${adb_script}" version
  41. }
  42. boot()
  43. {
  44. [ -s "${adb_pidfile}" ] && > "${adb_pidfile}"
  45. rc_procd start_service
  46. }
  47. start_service()
  48. {
  49. if [ "$("${adb_init}" enabled; printf "%u" ${?})" -eq 0 ]
  50. then
  51. if [ "${action}" = "boot" ]
  52. then
  53. if [ -n "$(uci_get adblock global adb_trigger)" ]
  54. then
  55. return 0
  56. fi
  57. fi
  58. procd_open_instance "adblock"
  59. procd_set_param command "${adb_script}" "${@}"
  60. procd_set_param pidfile "${adb_pidfile}"
  61. procd_set_param nice "$(uci_get adblock global adb_nice "0")"
  62. procd_set_param stdout 1
  63. procd_set_param stderr 1
  64. procd_close_instance
  65. fi
  66. }
  67. reload_service()
  68. {
  69. rc_procd start_service reload
  70. }
  71. stop_service()
  72. {
  73. rc_procd "${adb_script}" stop
  74. }
  75. restart()
  76. {
  77. rc_procd start_service restart
  78. }
  79. suspend()
  80. {
  81. rc_procd start_service suspend
  82. }
  83. resume()
  84. {
  85. rc_procd start_service resume
  86. }
  87. query()
  88. {
  89. rc_procd "${adb_script}" query "${1}"
  90. }
  91. report()
  92. {
  93. rc_procd "${adb_script}" report "${1:-"cli"}" "${2}" "${3}"
  94. }
  95. list()
  96. {
  97. local src_archive src_file src_enabled enabled name sha_list utc_list action="${1}"
  98. if [ "${action%_*}" = "add" ] || [ "${action%_*}" = "remove" ]
  99. then
  100. shift
  101. for name in "${@}"
  102. do
  103. case "${action}" in
  104. "add")
  105. if [ -z "$(uci_get adblock global adb_sources | grep -Fo "${name}")" ]
  106. then
  107. uci_add_list adblock global adb_sources "${name}"
  108. printf "%s\n" "::: adblock source '${name}' added to config"
  109. fi
  110. ;;
  111. "remove")
  112. if [ -n "$(uci_get adblock global adb_sources | grep -Fo "${name}")" ]
  113. then
  114. uci_remove_list adblock global adb_sources "${name}"
  115. printf "%s\n" "::: adblock source '${name}' removed from config"
  116. fi
  117. ;;
  118. "add_sha")
  119. if [ -z "$(uci_get adblock global adb_sha_sources | grep -Fo "${name}")" ]
  120. then
  121. uci_add_list adblock global adb_sha_sources "${name}"
  122. printf "%s\n" "::: adblock shallalist '${name}' added to config"
  123. fi
  124. ;;
  125. "remove_sha")
  126. if [ -n "$(uci_get adblock global adb_sha_sources | grep -Fo "${name}")" ]
  127. then
  128. uci_remove_list adblock global adb_sha_sources "${name}"
  129. printf "%s\n" "::: adblock shallalist '${name}' removed from config"
  130. fi
  131. ;;
  132. "add_utc")
  133. if [ -z "$(uci_get adblock global adb_utc_sources | grep -Fo "${name}")" ]
  134. then
  135. uci_add_list adblock global adb_utc_sources "${name}"
  136. printf "%s\n" "::: adblock utcapitole '${name}' added to config"
  137. fi
  138. ;;
  139. "remove_utc")
  140. if [ -n "$(uci_get adblock global adb_utc_sources | grep -Fo "${name}")" ]
  141. then
  142. uci_remove_list adblock global adb_utc_sources "${name}"
  143. printf "%s\n" "::: adblock utcapitole '${name}' removed from config"
  144. fi
  145. ;;
  146. "add_eng")
  147. if [ -z "$(uci_get adblock global adb_eng_sources | grep -Fo "${name}")" ]
  148. then
  149. uci_add_list adblock global adb_eng_sources "${name}"
  150. printf "%s\n" "::: adblock energized '${name}' added to config"
  151. fi
  152. ;;
  153. "remove_eng")
  154. if [ -n "$(uci_get adblock global adb_eng_sources | grep -Fo "${name}")" ]
  155. then
  156. uci_remove_list adblock global adb_eng_sources "${name}"
  157. printf "%s\n" "::: adblock energized '${name}' removed from config"
  158. fi
  159. ;;
  160. "add_stb")
  161. if [ -z "$(uci_get adblock global adb_stb_sources | grep -Fo "${name}")" ]
  162. then
  163. uci_add_list adblock global adb_stb_sources "${name}"
  164. printf "%s\n" "::: adblock stevenblack '${name}' added to config"
  165. fi
  166. ;;
  167. "remove_stb")
  168. if [ -n "$(uci_get adblock global adb_stb_sources | grep -Fo "${name}")" ]
  169. then
  170. uci_remove_list adblock global adb_stb_sources "${name}"
  171. printf "%s\n" "::: adblock stevenblack '${name}' removed from config"
  172. fi
  173. ;;
  174. esac
  175. done
  176. if [ -n "$(uci -q changes adblock)" ]
  177. then
  178. uci_commit adblock
  179. "${adb_init}" start
  180. fi
  181. else
  182. src_archive="$(uci_get adblock global adb_srcarc "/etc/adblock/adblock.sources.gz")"
  183. src_file="$(uci_get adblock global adb_srcfile "/tmp/adb_sources.json")"
  184. src_enabled="$(uci -q show adblock.global.adb_sources)"
  185. if [ -r "${src_archive}" ]
  186. then
  187. zcat "${src_archive}" > "${src_file}"
  188. else
  189. printf "%s\n" "::: adblock source archive '${src_archive}' not found"
  190. fi
  191. if [ -r "${src_file}" ]
  192. then
  193. src_enabled="${src_enabled#*=}"
  194. src_enabled="${src_enabled//\'}"
  195. printf "%s\n" "::: Available adblock sources"
  196. printf "%s\n" ":::"
  197. printf "%-25s%-10s%-7s%-21s%s\n" " Name" "Enabled" "Size" "Focus" "Info URL"
  198. printf "%s\n" " -------------------------------------------------------------------"
  199. json_load_file "${src_file}"
  200. json_get_keys keylist
  201. for key in ${keylist}
  202. do
  203. json_select "${key}"
  204. json_get_var size "size"
  205. json_get_var focus "focus"
  206. json_get_var descurl "descurl"
  207. json_get_var url "url"
  208. json_get_var rule "rule"
  209. if [ -n "${url}" ] && [ -n "${rule}" ]
  210. then
  211. if [ -n "$(printf "%s" "${src_enabled}" | grep -Fo "${key}")" ]
  212. then
  213. enabled="x"
  214. else
  215. enabled=" "
  216. fi
  217. src_enabled="${src_enabled/${key}}"
  218. printf " + %-21s%-10s%-7s%-21s%s\n" "${key:0:20}" "${enabled}" "${size:0:3}" "${focus:0:20}" "${descurl:0:50}"
  219. else
  220. src_enabled="${src_enabled} ${key}"
  221. fi
  222. json_select ..
  223. done
  224. sha_list="$(uci_get adblock global adb_sha_sources "-")"
  225. utc_list="$(uci_get adblock global adb_utc_sources "-")"
  226. eng_list="$(uci_get adblock global adb_eng_sources "-")"
  227. stb_list="$(uci_get adblock global adb_stb_sources "-")"
  228. printf "%s\n" " ---------------------------------------------------------------------------"
  229. printf " * %s\n" "Configured shallalist categories: ${sha_list// /, }"
  230. printf " * %s\n" "Configured utcapitole categories: ${utc_list// /, }"
  231. printf " * %s\n" "Configured energized variants: ${eng_list// /, }"
  232. printf " * %s\n" "Configured stevenblack variants: ${stb_list// /, }"
  233. if [ -n "${src_enabled// }" ]
  234. then
  235. printf "%s\n" " ---------------------------------------------------------------------------"
  236. printf "%s\n" " Sources without valid configuration"
  237. printf "%s\n" " ---------------------------------------------------------------------------"
  238. for key in ${src_enabled}
  239. do
  240. printf " - %s\n" "${key:0:20}"
  241. done
  242. fi
  243. else
  244. printf "%s\n" "::: adblock source file '${src_file}' not found"
  245. fi
  246. fi
  247. }
  248. status()
  249. {
  250. status_service
  251. }
  252. status_service()
  253. {
  254. local key keylist value idxval values rtfile
  255. rtfile="$(uci_get adblock global adb_rtfile "/tmp/adb_runtime.json")"
  256. json_load_file "${rtfile}" >/dev/null 2>&1
  257. json_get_keys keylist
  258. if [ -n "${keylist}" ]
  259. then
  260. printf "%s\n" "::: adblock runtime information"
  261. for key in ${keylist}
  262. do
  263. json_get_var value "${key}" >/dev/null 2>&1
  264. if [ "${key%_*}" = "active" ]
  265. then
  266. printf " + %-15s : " "${key}"
  267. json_select "${key}" >/dev/null 2>&1
  268. values=""
  269. index=1
  270. while json_get_type type "${index}" && [ "${type}" = "object" ]
  271. do
  272. json_get_values idxval "${index}" >/dev/null 2>&1
  273. if [ "${index}" = "1" ]
  274. then
  275. values="${idxval}"
  276. else
  277. values="${values}, ${idxval}"
  278. fi
  279. index=$((index+1))
  280. done
  281. 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}')"
  282. printf "%s\n" "${values:-"-"}"
  283. json_select ".."
  284. else
  285. printf " + %-15s : %s\n" "${key}" "${value:-"-"}"
  286. fi
  287. done
  288. else
  289. printf "%s\n" "::: no adblock runtime information available"
  290. fi
  291. }
  292. timer()
  293. {
  294. local cron_file cron_content cron_lineno action="${1:-"list"}" cron_tasks="${2}" hour="${3}" minute="${4:-0}" weekday="${5:-"*"}"
  295. cron_file="/etc/crontabs/root"
  296. if [ -s "${cron_file}" ] && [ "${action}" = "list" ]
  297. then
  298. awk '{print NR "> " $0}' "${cron_file}"
  299. elif [ "${action}" = "add" ]
  300. then
  301. hour="${hour//[[:alpha:]]/}"
  302. minute="${minute//[[:alpha:]]/}"
  303. if [ -n "${cron_tasks}" ] && [ -n "${hour}" ] && [ -n "${minute}" ] && [ -n "${weekday}" ] && \
  304. [ "${hour}" -ge 0 ] && [ "${hour}" -le 23 ] && \
  305. [ "${minute}" -ge 0 ] && [ "${minute}" -le 59 ]
  306. then
  307. printf "%02d %02d %s\n" "${minute}" "${hour}" "* * ${weekday} ${adb_init} ${cron_tasks}" >> "${cron_file}"
  308. /etc/init.d/cron restart
  309. fi
  310. elif [ -s "${cron_file}" ] && [ "${action}" = "remove" ]
  311. then
  312. cron_tasks="${cron_tasks//[[:alpha:]]/}"
  313. cron_lineno="$(awk 'END{print NR}' "${cron_file}")"
  314. cron_content="$(awk '{print $0}' "${cron_file}")"
  315. if [ "${cron_tasks:-"0"}" -le "${cron_lineno:-"1"}" ] && [ -n "${cron_content}" ]
  316. then
  317. printf "%s\n" "${cron_content}" | awk "NR!~/^${cron_tasks}$/" > "${cron_file}"
  318. /etc/init.d/cron restart
  319. fi
  320. fi
  321. }
  322. service_triggers()
  323. {
  324. local iface delay
  325. iface="$(uci_get adblock global adb_trigger)"
  326. delay="$(uci_get adblock global adb_triggerdelay "5")"
  327. PROCD_RELOAD_DELAY=$((delay*1000))
  328. if [ -z "${iface}" ]
  329. then
  330. . "/lib/functions/network.sh"
  331. network_find_wan iface
  332. if [ -n "${iface}" ]
  333. then
  334. uci_set adblock global adb_trigger "${iface}"
  335. uci_commit "adblock"
  336. fi
  337. fi
  338. if [ -n "${iface}" ]
  339. then
  340. procd_add_interface_trigger "interface.*.up" "${iface}" "${adb_init}" "start"
  341. fi
  342. procd_add_reload_trigger "adblock"
  343. }