diff --git a/adsorber.conf b/adsorber.conf old mode 100644 new mode 100755 index aba91d3..44e7aa4 --- a/adsorber.conf +++ b/adsorber.conf @@ -1,5 +1,4 @@ -#!/bin/bash -## Config file for Adsorber v0.2.3 +## Config file for Adsorber v0.3.0 # # To reset the config file just delete it and run 'adsorber.sh install', a new # config file will be created. @@ -8,7 +7,7 @@ # Don't hesitate to create issues and pull-requests. -## PRIMARY_LIST +## primary_list # Defines what list (either whitelist or blacklist) has the priority. # # For example: if 'blacklist' is set, the blacklist will overwrite @@ -18,26 +17,26 @@ # Possible values: whitelist, blacklist # Default value: blacklist -PRIMARY_LIST=blacklist +primary_list=blacklist -## USE_PARTIAL_MATCHING +## use_partial_matching # Defines whether the WHITELIST includes sub-domains or not. # # For example: You white listed the domain wholesome-ads.com, if the value # is set to 'true' all it's sub-domains like annoying.wholesome-ads.com will be # also allowed. To disable this set the value to 'false'. # -# Note: if you set PRIMARY_LIST to blacklist you still can block it's +# Note: if you set primary_list to blacklist you still can block it's # specific sub-domains or top-level domain in the blacklist. # # Possible values: true, false # Default value: true -USE_PARTIAL_MATCHING=true +use_partial_matching=true -## IGNORE_DOWNLOAD_ERROR +## ignore_download_error # If set to false, we'll only apply the hosts file if all hosts sources # could be reached. # @@ -48,10 +47,10 @@ USE_PARTIAL_MATCHING=true # Possible values: true, false # Default value: true -IGNORE_DOWNLOAD_ERROR=true +ignore_download_error=true -## HTTP_PROXY, HTTPS_PROXY ## +## http_proxy, https_proxy ## # Specify what proxy server should be used when fetching the host domains. # This will set or overwrite the environment variables of # 'http_proxy' and 'https_proxy'. @@ -59,29 +58,41 @@ IGNORE_DOWNLOAD_ERROR=true # Possible value: address:port (e.g proxy:8080, 127.0.0.1:9050) # Default value: Null (not set) -HTTP_PROXY= -HTTPS_PROXY= +http_proxy= +https_proxy= -## HOSTS_FILE_PATH -# HOSTS_FILE_PATH is used to set the path to the systems hosts file. +## hosts_file_path +# hosts_file_pat is used to set the path to the systems hosts file. # Change if your system uses an other file or path. # # Default value: /etc/hosts -HOSTS_FILE_PATH=/etc/hosts +hosts_file_path=/etc/hosts -## HOSTS_FILE_BACKUP_PATH ## -# HOSTS_FILE_BACKUP_PATH is used to set the filename and the path to the +## hosts_file_backup_path ## +# hosts_file_backup_path is used to set the filename and the path to the # backup of the hosts file to be created by Adsorber in the install process. # To simply create a new backup run 'adsorber.sh install' # # Default value: /etc/hosts.original -HOSTS_FILE_BACKUP_PATH=/etc/hosts.original +hosts_file_backup_path=/etc/hosts.original -## CRONTAB_DIR_PATH +## hosts_file_previous_enable, hosts_file_previous_path ## +# Info goes here +# +# Possible values for 'hosts_file_previous_enable': true, false +# Default value for 'hosts_file_previous_enable': true +# +# Default value for 'hosts_file_previous_path': /etc/hosts.previous + +hosts_file_previous_enable=true +hosts_file_previous_path=/etc/hosts.previous + + +## crontab_dir_path # This defines the directory in which we'll set the crontab. # Used to create a scheduler which supplies the hosts file regulary with # new ad-domains. @@ -90,25 +101,25 @@ HOSTS_FILE_BACKUP_PATH=/etc/hosts.original # with setting another directory, for example /etc/cron/daily to update the # hosts file daily. # -# Possible value: /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, -# /etc/cron.monthly, or any other directory which it's contents will be +# Possible value: /etc/cron.hourly/, /etc/cron.daily/, /etc/cron.weekly/, +# /etc/cron.monthly/, or any other directory which it's contents will be # executed as a script regulary. # -# Default value: /etc/cron.weekly +# Default value: /etc/cron.weekly/ -CRONTAB_DIR_PATH=/etc/cron.weekly +crontab_dir_path=/etc/cron.weekly/ -## SYSTEMD_DIR_PATH +## systemd_dir_path # This defines the directory in which we'll place the systemd files. # Used to create a scheduler which supplies the hosts file regulary with # new ad-domains. Change if your system has an other path. # # In the default setting it'll update once a week. To change this behavior you # need to change adsorber.timer's 'OnCalendar' setting to another period. -# The file can be found at SYSTEMD_DIR_PATH, to change it before placement go +# The file can be found at systemd_dir_path, to change it before placement go # into the scripts root directory and edit bin/systemd/adsorber.timer # -# Default value: /etc/systemd/system +# Default value: /etc/systemd/system/ -SYSTEMD_DIR_PATH=/etc/systemd/system +systemd_dir_path=/etc/systemd/system/ diff --git a/adsorber.sh b/adsorber.sh index a1afb3e..298844b 100755 --- a/adsorber.sh +++ b/adsorber.sh @@ -1,30 +1,28 @@ -#!/bin/bash +#!/bin/sh # Author: stablestud <adsorber@stablestud.org> # Repository: https://github.com/stablestud/adsorber # License: MIT, https://opensource.org/licenses/MIT -readonly TMP_DIR_PATH="/tmp/adsorber" -readonly SCRIPT_DIR_PATH="$(cd "$(dirname "${0}")" && pwd)" -readonly SOURCELIST_FILE_PATH="${SCRIPT_DIR_PATH}/sources.list" +readonly tmp_dir_path="/tmp/adsorber" +readonly script_dir_path="$(cd "$(dirname "${0}")" && pwd)" +readonly sourcelist_file_path="${script_dir_path}/sources.list" -readonly VERSION="0.2.3" +readonly version="0.3.0" -readonly OPERATION="${1}" - -# For better error messages, from http://wiki.bash-hackers.org/scripting/debuggingtips#making_xtrace_more_useful: -export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' +readonly operation="${1}" if [ "${#}" -ne 0 ]; then shift fi +readonly options="${*}" checkRoot() { - if [ "${UID}" -ne 0 ]; then - echo "This script must be run as root." 1>&2 + if [ "$(id -g)" -ne 0 ]; then + echo "This activity must be run as root." 1>&2 exit 126 fi @@ -34,11 +32,11 @@ checkRoot() checkForWrongParameters() { - if [ "${WRONG_OPERATION}" != "" ] || [ "${#WRONG_OPTION[@]}" -ne 0 ]; then + if [ -n "${wrong_operation}" ] || [ -n "${wrong_option}" ]; then showUsage fi - if [ "${OPTION_HELP}" == "true" ]; then + if [ "${option_help}" = "true" ]; then showSpecificHelp fi @@ -48,16 +46,16 @@ checkForWrongParameters() showUsage() { - if [ "${WRONG_OPERATION}" != "" ]; then - echo "Adsorber: Invalid operation: '${WRONG_OPERATION}'" 1>&2 + if [ -n "${wrong_operation}" ]; then + echo "Adsorber: Invalid operation: '${wrong_operation}'" 1>&2 fi - if [ "${WRONG_OPTION}" != "" ]; then - echo "Adsorber: Invalid option: ${WRONG_OPTION[*]}" 1>&2 + if [ -n "${wrong_option}" ]; then + echo "Adsorber: Invalid option: '${wrong_option}'" 1>&2 fi - echo "Usage: ${0} [install|remove|update|revert] {options}" 1>&2 - echo "Try --help for more information." 1>&2 + echo "Usage: ${0} <install|update|restore|revert|remove> [<options>]" + echo "Try --help for more information." exit 127 } @@ -65,7 +63,7 @@ showUsage() showHelp() { - echo "Usage: ${0} [OPERATION] {options}" + echo "Usage: ${0} <operation> [<options>]" echo "" echo "A(d)sorber blocks ads by 'absorbing' and dumbing them into void." echo " (with the help of the hosts file)" @@ -73,13 +71,14 @@ showHelp() echo "Operations:" echo " install - setup necessary things needed for Adsorber" echo " e.g., create backup file of hosts file," - echo " create scheduler which updates the host file once a week." + echo " create scheduler which updates the host file once a week" echo " update - update hosts file with newest ad servers" - echo " revert - revert hosts file to its original state" - echo " (it does not remove the schedule, so this should be used temporary)" + echo " restore - restore hosts file to its original state" + echo " (it does not remove the schedule, this should be used temporary)" + echo " revert - reverts the hosts file to the lastest applied host file." echo " remove - completely remove changes made by Adsorber" echo " e.g., remove scheduler (if set)" - echo " revert hosts file (if not already done)" + echo " restore hosts file to its original state" echo " version - show version of this shell script" echo " help - show this help" echo "" @@ -90,7 +89,8 @@ showHelp() echo " -y, --yes, --assume-yes - answer all prompts with 'yes'" echo " -f, --force - force the update if no /etc/hosts backup" echo " has been created (dangerous)" - echo "" + echo " -h, --help - show specific help of specified operations" + echo echo "Documentation: https://github.com/stablestud/adsorber" echo "If you encounter any issues please report them to the Github repository." @@ -100,64 +100,84 @@ showHelp() showSpecificHelp() { - case "${OPERATION}" in + case "${operation}" in install ) - echo -e "${UWHITE}adsorber.sh install {options}${COLOUR_RESET}:" - echo "" + printf "%badsorber.sh install [<options>]%b:\n" "${uwhite}" "${prefix_reset}" + echo echo "You should run this command first." - echo "" + echo echo "The command will:" echo " - backup your /etc/hosts file to /etc/hosts.original" echo " (if not other specified in adsorber.conf)" echo " - install a scheduler which updates your hosts file with ad-server domains" echo " once a week. (either systemd, cronjob or none)" echo " - install the newest ad-server domains in your hosts file." - echo "" - echo "Possible options are:" - echo " -s, --systemd - use Systemd ..." - echo " -c, --cronjob - use Cronjob as scheduler" - echo " -ns, --no-scheduler - skip scheduler creation" - echo " -y, --yes, --assume-yes - answer all prompts with 'yes'" + echo + echo "Possible options:" + echo " -s, --systemd - use Systemd ..." + echo " -c, --cronjob - use Cronjob as scheduler" + echo " -ns, --no-scheduler - skip scheduler creation" + echo " -y, --yes, --assume-yes - answer all prompts with 'yes'" + echo " -h, --help - show this help screen" ;; update ) - echo -e "${UWHITE}adsorber.sh update {options}${COLOUR_RESET}:" - echo "" + printf "%badsorber.sh update [<options>]%b:\n" "${uwhite}" "${prefix_reset}" + echo echo "To keep the hosts file up-to-date." - echo "" + echo echo "The command will:" echo " - install the newest ad-server domains in your hosts file." - echo "" - echo "Possible option:" + echo + echo "Possible options:" echo " -f, --force - force the update if no /etc/hosts backup" echo " has been created (dangerous)" + echo " -h, --help - show this help screen" ;; - revert ) - echo -e "${UWHITE}adsorber.sh revert {options}${COLOUR_RESET}:" - echo "" + restore ) + printf "%badsorber.sh restore [<options>]%b:\n" "${uwhite}" "${prefix_reset}" + echo echo "To restore the hosts file temporary, without removing the backup." - echo "" + echo echo "The command will:" echo " - copy /etc/hosts.original to /etc/hosts, overwriting the modified /etc/hosts by adsorber." - echo "" + echo echo "Important: If you have a scheduler installed it'll re-apply ad-server domains to your hosts" echo "file when triggered." echo "For this reason this command is used to temporary disable Adsorber." echo "(e.g. when it's blocking some sites you need access for a short period of time)" - echo "" - echo "To re-apply run 'asdorber.sh update'" + echo + echo "To re-apply run 'adsorber.sh update'" + echo + echo "Possible option:" + echo " -h, --help - show this help screen" + ;; + revert ) + printf "%badsorber.sh revert [<options>]%b:\n" "${uwhite}" "${prefix_reset}" + echo + echo "To revert to the last hosts file, good use if the" + echo "current host file was corrupted." + echo + echo "The command will:" + echo " - copy /etc/hosts.previous to /etc/hosts, overwriting the current host file." + echo + echo "To get the latest ad-domains run 'adsorber.sh update'" + echo + echo "Possible option:" + echo " -h, --help - show this help screen" ;; remove ) - echo -e "${UWHITE}adsorber remove {options}${COLOUR_RESET}:" - echo "" + printf "%badsorber remove [<options>]%b:\n" "${uwhite}" "${prefix_reset}" + echo echo "To completely remove changes made by Adsorber." - echo "" + echo echo "The command will:" echo " - remove all schedulers (systemd, cronjob)" echo " - restore the hosts file to it's original state" echo " - remove all leftovers" - echo "" - echo "Possible option:" + echo + echo "Possible options:" echo " -y, --yes, --assume-yes - answer all prompts with 'yes'" + echo " -h, --help - show this help screen" ;; esac @@ -167,7 +187,7 @@ showSpecificHelp() showVersion() { - echo "A(d)sorber ${VERSION}" + echo "A(d)sorber ${version}" echo "" echo " License MIT" echo " Copyright (c) 2017 stablestud <adsorber@stablestud.org>" @@ -183,14 +203,14 @@ showVersion() duplicateOption() { - if [ "${1}" == "scheduler" ]; then - echo "Adsorber: Duplicate option for scheduler: '${option}'" + if [ "${1}" = "scheduler" ]; then + echo "Adsorber: Duplicate option for scheduler: '${option}'" 1>&2 echo "You may only select one:" echo " -s, --systemd - use Systemd ..." echo " -c, --cron - use Cronjob as scheduler (use with 'install')" echo " -ns, --no-scheduler - skip scheduler creation (use with 'install')" else - echo "Adsorber: Duplicate option: '${option}'" + echo "Adsorber: Duplicate option: '${option}'" 1>&2 showUsage fi @@ -200,13 +220,13 @@ duplicateOption() sourceFiles() { - . "${SCRIPT_DIR_PATH}/bin/install.sh" - . "${SCRIPT_DIR_PATH}/bin/remove.sh" - . "${SCRIPT_DIR_PATH}/bin/update.sh" - . "${SCRIPT_DIR_PATH}/bin/revert.sh" - . "${SCRIPT_DIR_PATH}/bin/config.sh" - . "${SCRIPT_DIR_PATH}/bin/colours.sh" - + . "${script_dir_path}/bin/install.sh" + . "${script_dir_path}/bin/remove.sh" + . "${script_dir_path}/bin/update.sh" + . "${script_dir_path}/bin/restore.sh" + . "${script_dir_path}/bin/revert.sh" + . "${script_dir_path}/bin/config.sh" + . "${script_dir_path}/bin/colours.sh" return 0 } @@ -217,34 +237,36 @@ for option in "${@}"; do case "${option}" in -[Ss] | --systemd ) - readonly REPLY_TO_SCHEDULER_PROMPT="systemd" 2>/dev/null || duplicateOption "scheduler" + readonly reply_to_scheduler_prompt="systemd" 2>/dev/null || duplicateOption "scheduler" ;; -[Cc] | --cron ) - readonly REPLY_TO_SCHEDULER_PROMPT="cronjob" 2>/dev/null || duplicateOption "scheduler" + readonly reply_to_scheduler_prompt="cronjob" 2>/dev/null || duplicateOption "scheduler" ;; -[Nn][Ss] | --no-scheduler ) - readonly REPLY_TO_SCHEDULER_PROMPT="no-scheduler" 2>/dev/null || duplicateOption "scheduler" + readonly reply_to_scheduler_prompt="no-scheduler" 2>/dev/null || duplicateOption "scheduler" ;; -[Yy] | --[Yy][Ee][Ss] | --assume-yes ) - readonly REPLY_TO_PROMPT="yes" 2>/dev/null || duplicateOption + readonly reply_to_prompt="yes" 2>/dev/null || duplicateOption ;; -[Ff] | --force ) - readonly REPLY_TO_FORCE_PROMPT="yes" 2>/dev/null || duplicateOption + readonly reply_to_force_prompt="yes" 2>/dev/null || duplicateOption ;; "" ) : # Do nothing ;; -[Hh] | --help | help ) - readonly OPTION_HELP="true" 2>/dev/null + readonly option_help="true" 2>/dev/null ;; * ) - WRONG_OPTION+=("'${option}'") + wrong_option="${option}" 2>/dev/null ;; esac done -case "${OPERATION}" in +config_Copy + +case "${operation}" in install ) checkForWrongParameters checkRoot @@ -264,6 +286,12 @@ case "${OPERATION}" in config update ;; + restore ) + checkForWrongParameters + checkRoot + config + restore + ;; revert ) checkForWrongParameters checkRoot @@ -280,11 +308,11 @@ case "${OPERATION}" in showUsage ;; * ) - readonly WRONG_OPERATION="${OPERATION}" + readonly wrong_operation="${operation}" showUsage ;; esac -echo -e "${PREFIX_TITLE}Finished successfully.${COLOUR_RESET}" +printf "%bFinished successfully.%b\n" "${prefix_title}" "${prefix_reset}" exit 0 diff --git a/bin/colours.sh b/bin/colours.sh index 5a25724..c7a7639 100755 --- a/bin/colours.sh +++ b/bin/colours.sh @@ -1,16 +1,16 @@ -#!/bin/bash +#!/bin/sh # Author: stablestud <adsorber@stablestud.org> # Repository: https://github.com/stablestud/adsorber # License: MIT, https://opensource.org/licenses/MIT -readonly PREFIX=" " -readonly PREFIX_FATAL="\033[0;91mE " # 'E' in intensity red -readonly PREFIX_INFO="\033[0;97m " # Intensity white -readonly PREFIX_INPUT=" " -readonly PREFIX_TITLE="\033[1;37m" # Bold white -readonly PREFIX_WARNING="- " -readonly COLOUR_RESET='\033[0m' # Default colour +readonly prefix=" " +readonly prefix_fatal="\033[0;91mE " # 'E' in intensity red +readonly prefix_info="\033[0;97m " # Intensity white +readonly prefix_input="> " +readonly prefix_title="\033[1;37m" # Bold white +readonly prefix_warning="- " +readonly prefix_reset='\033[0m' # Default colour # Regular Colors #readonly BLACK='\033[0;30m' # Black @@ -34,13 +34,13 @@ readonly COLOUR_RESET='\033[0m' # Default colour # Underline #readonly UBLACK='\033[4;30m' # Black -#readonly URRED='\033[4;31m' # Red +#readonly URRED='\033[4;31m' # Red #readonly UGREEn='\033[4;32m' # Green #readonly UYELLOW='\033[4;33m' # Yellow #readonly UBLUE='\033[4;34m' # Blue #readonly UPURPLE='\033[4;35m' # Purple #readonly UCYAN='\033[4;36m' # Cyan -readonly UWHITE='\033[4;37m' # White +readonly uwhite='\033[4;37m' # White # Background #readonly BG_BLACK='\033[40m' # Black diff --git a/bin/components/hosts_header b/bin/components/hosts_header index e1c7775..c679357 100755 --- a/bin/components/hosts_header +++ b/bin/components/hosts_header @@ -1,6 +1,7 @@ -# This file has been edited by Adsorber. -# -# To make any changes to this file please edit #@${HOSTS_FILE_BACKUP_PATH}#@ +# This file has been edited by Adsorber v#@version@# at #@date@# +# Currently Adsorber is blocking #@blocked@# domain(s). +# +# To make any changes to this file please edit #@hosts_file_backup_path@# # and run './adsorber.sh update' to apply your changes. # Or else your changes will be overwritten by Adsorber once a week. # diff --git a/bin/components/hosts_title b/bin/components/hosts_title index 6fdaae5..92ce02c 100755 --- a/bin/components/hosts_title +++ b/bin/components/hosts_title @@ -1 +1,2 @@ -# Following domains are generated by Adsorber and are blocking advertisements: + +# Following #@blocked@# domain(s) were inserted by Adsorber and are blocking advertisement: diff --git a/bin/config.sh b/bin/config.sh index c05b1ba..b4846cb 100755 --- a/bin/config.sh +++ b/bin/config.sh @@ -1,102 +1,91 @@ -#!/bin/bash +#!/bin/sh # Author: stablestud # Repository: https://github.com/stablestud/adsorber # License: MIT, https://opensource.org/licenses/MIT -# The following variables are declared in adsorber.conf, adsorber.sh or bin/config.sh. +# The following variables are declared globally. # If you run this file independently following variables need to be set: # ---variable:-------- ---default value:------------ ----declared in:------------ -# COLOUR_RESET \033[0m bin/colours.sh -# PREFIX ' ' (two spaces) bin/colours.sh -# PREFIX_TITLE \033[1;37m bin/colours.sh -# PREFIX_WARNING '- ' bin/colours.sh -# PRIMARY_LIST blacklist bin/config.sh, adsorber.conf -# SCRIPT_DIR_PATH script root directory adsorber.sh +# prefix ' ' (two spaces) bin/colours.sh +# prefix_reset \033[0m bin/colours.sh +# prefix_title \033[1;37m bin/colours.sh +# prefix_warning '- ' bin/colours.sh +# primary_list blacklist bin/config.sh, adsorber.conf +# script_dir_path script root directory adsorber.sh # (e.g., /home/user/Downloads/adsorber) -# SOURCELIST_FILE_PATH SCRIPT_DIR_PATH/sources.list adsorber.sh -# (e.g., /home/user/Downloads/absorber/sources.list) -# TMP_DIR_PATH /tmp/adsorber adsorber.sh -# USE_PARTIAL_MATCHING true bin/config.sh, adsorber.conf -# VERSION 0.2.2 or similar adsorber.sh +# tmp_dir_path /tmp/adsorber adsorber.sh +# use_partial_matching true bin/config.sh, adsorber.conf +# version 0.2.2 or similar adsorber.sh # The following functions are defined in different files. # If you run this file independently following functions need to be emulated: -# ---function:----- ---function defined in:--- -# cleanUp bin/remove.sh -# errorCleanUp bin/remove.sh +# ---function:----- ---function defined in:--- +# remove_ErrorCleanUp bin/remove.sh -SETTING_STRING[0]="PRIMARY_LIST" -SETTING_STRING[1]="USE_PARTIAL_MATCHING" -SETTING_STRING[2]="IGNORE_DOWNLOAD_ERROR" -SETTING_STRING[3]="HTTP_PROXY" -SETTING_STRING[4]="HTTPS_PROXY" -SETTING_STRING[5]="HOSTS_FILE_PATH" -SETTING_STRING[6]="HOSTS_FILE_BACKUP_PATH" -SETTING_STRING[7]="CRONTAB_DIR_PATH" -SETTING_STRING[8]="SYSTEMD_DIR_PATH" - -readonly SETTING_STRING - - -configCreateTmpDir() +config_CreateTmpDir() { - if [ ! -d "${TMP_DIR_PATH}" ]; then - mkdir "${TMP_DIR_PATH}" + if [ ! -d "${tmp_dir_path}" ]; then + mkdir "${tmp_dir_path}" else - echo "${PREFIX}Removing previous tmp folder ..." - rm -rf "${TMP_DIR_PATH}" - mkdir "${TMP_DIR_PATH}" + echo "${prefix}Removing previous tmp folder ..." + rm -rf "${tmp_dir_path}" + mkdir "${tmp_dir_path}" fi return 0 } -copySourceList() +config_CopySourceList() { - if [ ! -f "${SCRIPT_DIR_PATH}/sources.list" ] || [ ! -s "${SCRIPT_DIR_PATH}/sources.list" ]; then - cp "${SCRIPT_DIR_PATH}/bin/default/default-sources.list" "${SCRIPT_DIR_PATH}/sources.list" \ - && echo "${PREFIX}Created sources.list: to add new host sources edit this file." + if [ ! -f "${script_dir_path}/sources.list" ] || [ ! -s "${script_dir_path}/sources.list" ]; then + cp "${script_dir_path}/bin/default/default-sources.list" "${script_dir_path}/sources.list" \ + && echo "${prefix_warning}Created sources.list: to add new host sources edit this file." + chown --reference="${script_dir_path}/adsorber.sh" "${script_dir_path}/sources.list" + chmod --reference="${script_dir_path}/adsorber.sh" "${script_dir_path}/sources.list" fi return 0 } -copyWhiteList() +config_CopyWhiteList() { - if [ ! -f "${SCRIPT_DIR_PATH}/whitelist" ] || [ ! -s "${SCRIPT_DIR_PATH}/whitelist" ]; then - cp "${SCRIPT_DIR_PATH}/bin/default/default-whitelist" "${SCRIPT_DIR_PATH}/whitelist" \ - && echo "${PREFIX}Created whitelist: to allow specific domains edit this file." + if [ ! -f "${script_dir_path}/whitelist" ] || [ ! -s "${script_dir_path}/whitelist" ]; then + cp "${script_dir_path}/bin/default/default-whitelist" "${script_dir_path}/whitelist" \ + && echo "${prefix_warning}Created whitelist: to allow specific domains edit this file." + chown --reference="${script_dir_path}/adsorber.sh" "${script_dir_path}/whitelist" + chmod --reference="${script_dir_path}/adsorber.sh" "${script_dir_path}/whitelist" fi return 0 } -copyBlackList() +config_CopyBlackList() { - if [ ! -f "${SCRIPT_DIR_PATH}/blacklist" ] || [ ! -s "${SCRIPT_DIR_PATH}/blacklist" ]; then - cp "${SCRIPT_DIR_PATH}/bin/default/default-blacklist" "${SCRIPT_DIR_PATH}/blacklist" \ - && echo "${PREFIX}Created blacklist: to block additional domains edit this file." + if [ ! -f "${script_dir_path}/blacklist" ] || [ ! -s "${script_dir_path}/blacklist" ]; then + cp "${script_dir_path}/bin/default/default-blacklist" "${script_dir_path}/blacklist" \ + && echo "${prefix_warning}Created blacklist: to block additional domains edit this file." + chown --reference="${script_dir_path}/adsorber.sh" "${script_dir_path}/blacklist" + chmod --reference="${script_dir_path}/adsorber.sh" "${script_dir_path}/blacklist" fi return 0 } -copyConfig() +config_CopyConfig() { - if [ -s "${SCRIPT_DIR_PATH}/adsorber.conf" ]; then - cp "${SCRIPT_DIR_PATH}/adsorber.conf" "${TMP_DIR_PATH}/config" - else - echo -e "${PREFIX_FATAL}No config file found. Creating default.${COLOUR_RESET}" 1>&2 - echo "${PREFIX}Please re-run the command to continue." - sed "s|@.*|# Config file for Adsorber v${VERSION}|g" "${SCRIPT_DIR_PATH}/bin/default/default-adsorber.conf" > "${SCRIPT_DIR_PATH}/adsorber.conf" + if [ ! -s "${script_dir_path}/adsorber.conf" ] || [ ! -f "${script_dir_path}/adsorber.conf" ]; then + printf "%bNo config file found. Creating default.%b\n" "${prefix_fatal}" "${prefix_reset}" 1>&2 + echo "${prefix_warning}Please re-run the command to continue." + sed "s|@.*|# Config file for Adsorber v${version}|g" "${script_dir_path}/bin/default/default-adsorber.conf" > "${script_dir_path}/adsorber.conf" + chown --reference="${script_dir_path}/adsorber.sh" "${script_dir_path}/adsorber.conf" + chmod --reference="${script_dir_path}/adsorber.sh" "${script_dir_path}/adsorber.conf" - errorCleanUp exit 126 fi @@ -104,66 +93,144 @@ copyConfig() } -filterConfig() +config_Copy() { - local i - - for i in "${SETTING_STRING[@]}"; do - # keep only lines starting with value out of SETTING_STRING - sed -n "/^${i}/p" "${TMP_DIR_PATH}/config" \ - >> "${TMP_DIR_PATH}/config-filtered" - done + config_CopySourceList + config_CopyWhiteList + config_CopyBlackList + config_CopyConfig return 0 } -readConfig() +config_FilterConfig() { - local line + cp "${script_dir_path}/adsorber.conf" "${tmp_dir_path}/config" \ + || { + printf "%bCouldn't process config file.%b\n" "${prefix_fatal}" "${prefix_reset}" 1>&2 + remove_ErrorCleanUp + exit 126 + } + + { + sed -n "/^primary_list=/p" "${tmp_dir_path}/config" + sed -n "/^use_partial_matching=/p" "${tmp_dir_path}/config" + sed -n "/^ignore_download_error=/p" "${tmp_dir_path}/config" + sed -n "/^http_proxy=/p" "${tmp_dir_path}/config" + sed -n "/^https_proxy=/p" "${tmp_dir_path}/config" + sed -n "/^hosts_file_path=/p" "${tmp_dir_path}/config" + sed -n "/^hosts_file_backup_path=/p" "${tmp_dir_path}/config" + sed -n "/^hosts_file_previous_enable=/p" "${tmp_dir_path}/config" + sed -n "/^hosts_file_previous_path=/p" "${tmp_dir_path}/config" + sed -n "/^crontab_dir_path=/p" "${tmp_dir_path}/config" + sed -n "/^systemd_dir_path=/p" "${tmp_dir_path}/config" + } > "${tmp_dir_path}/config-filtered" + + return 0 +} + +config_ReadConfig() +{ while read -r line; do - readonly "${line}" - done < "${TMP_DIR_PATH}/config-filtered" + case "${line}" in + http_proxy* ) + readonly "set_${line}" + if [ -n "$set_http_proxy" ]; then + export "${line}" + fi + ;; + https_proxy* ) + readonly "set_${line}" + if [ -n "$set_https_proxy" ]; then + export "${line}" + fi + ;; + * ) + readonly "${line}" + ;; + esac + done < "${tmp_dir_path}/config-filtered" return 0 } -isVariableSet() +config_IsVariableSet() { - if [ -z "${HOSTS_FILE_PATH}" ] || [ -z "${HOSTS_FILE_BACKUP_PATH}" ] || [ -z "${CRONTAB_DIR_PATH}" ] || [ -z "${SYSTEMD_DIR_PATH}" ]; then - echo -e "${PREFIX_FATAL}Missing setting(s) in adsorber.conf." 1>&2 - echo "${PREFIX}Please delete adsorber.conf and run '${0} install' to create a new config file." 1>&2 - errorCleanUp + if [ -z "${hosts_file_path}" ] || [ -z "${hosts_file_backup_path}" ] || [ -z "${crontab_dir_path}" ] || [ -z "${systemd_dir_path}" ] || [ -z "${hosts_file_previous_path}" ] || [ -z "${hosts_file_previous_enable}" ]; then + printf "%bMissing setting(s) in adsorber.conf.%b\n" "${prefix_fatal}" "${prefix_reset}" 1>&2 + printf "%bPlease delete adsorber.conf and run '%s install' to create a new config file.%b\n" "${prefix_fatal}" "${0}" "${prefix_reset}" 1>&2 + remove_ErrorCleanUp exit 127 fi - if [ -z "${PRIMARY_LIST}" ]; then - echo -e "${PREFIX_WARNING}PRIMARY_LIST not set in adsorber.conf. Using default value: blacklist" 1>&2 - readonly PRIMARY_LIST="blacklist" + if [ -z "${primary_list}" ]; then + printf "%bprimary_list not set in adsorber.conf. Using default value: blacklist\n" "${prefix_warning}" 1>&2 + readonly primary_list="blacklist" fi - if [ -z "${USE_PARTIAL_MATCHING}" ]; then - echo -e "${PREFIX_WARNING}USE_PARTIAL_MATCHING not set in adsorber.conf. Using default value: true" 1>&2 - readonly USE_PARTIAL_MATCHING="true" + if [ -z "${use_partial_matching}" ]; then + printf "%buse_partial_matching not set in adsorber.conf. Using default value: true\n" "${prefix_warning}" 1>&2 + readonly use_partial_matching="true" fi - if [ -z "${IGNORE_DOWNLOAD_ERROR}" ]; then - echo -e "${PREFIX_WARNING}IGNORE_DOWNLOAD_ERROR not set in adsorber.conf. Using default value: false" 1>&2 - readonly IGNORE_DOWNLOAD_ERROR="false" + if [ -z "${ignore_download_error}" ]; then + printf "%bignore_download_error not set in adsorber.conf. Using default value: false\n" "${prefix_warning}" 1>&2 + readonly ignore_download_error="false" fi return 0 } -isVariableValid() +config_IsVariableValid() { # TODO: Check if proxy is valid ( with ping ) - if [ ! -f "${HOSTS_FILE_PATH}" ]; then - echo -e "${PREFIX_FATAL}Wrong HOSTS_FILE_PATH set in adsorber.conf. Can't access: ${HOSTS_FILE_PATH}" 1>&2 - errorCleanUp + + if [ "${primary_list}" != "blacklist" ] && [ "${primary_list}" != "whitelist" ]; then + printf "%bWrong 'primary_list' set in adsorber.conf. Choose either 'blacklist' or 'whitelist'%b\n" "${prefix_fatal}" "${prefix_reset}" 1>&2 + wrongVariable="true" + fi + + if [ "${use_partial_matching}" != "true" ] && [ "${use_partial_matching}" != "false" ]; then + printf "%bWrong 'use_partial_matching' set in adsorber.conf. Possible options: 'true' or 'false'%b\n" "${prefix_fatal}" "${prefix_reset}" 1>&2 + wrongVariable="true" + fi + + if [ "${ignore_download_error}" != "true" ] && [ "${ignore_download_error}" != "false" ]; then + printf "%bWrong 'ignore_download_error' set in adsorber.conf. Possible options: 'true' or 'false'%b\n" "${prefix_fatal}" "${prefix_reset}" 1>&2 + wrongVariable="true" + fi + + if [ ! -f "${hosts_file_path}" ]; then + printf "%bWrong 'hosts_file_path' set in adsorber.conf. Can't access: %s%b\n" "${prefix_fatal}" "${hosts_file_path}" "${prefix_reset}" 1>&2 + wrongVariable="true" + fi + + if [ ! -d "$(dirname "${hosts_file_backup_path}")" ]; then + printf "%bWrong 'hosts_file_backup_path' set in adsorber.conf. Can't access: %s%b\n" "${prefix_fatal}" "$(dirname "${hosts_file_backup_path}")" "${prefix_reset}" 1>&2 + wrongVariable="true" + fi + + if [ "${hosts_file_previous_enable}" != "true" ] && [ "${hosts_file_previous_enable}" != "false" ]; then + printf "%bWrong 'hosts_file_previous_enable' set in adsorber.conf. Possible options: 'true' or 'false'%b\n" "${prefix_fatal}" "${prefix_reset}" 1>&2 + wrongVariable="true" + fi + + if [ ! -d "$(dirname "${hosts_file_previous_path}")" ]; then + printf "%bWrong 'hosts_file_previous_path' set in adsorber.conf. Can't access: %s%b\n" "${prefix_fatal}" "$(dirname "${hosts_file_previous_path}")" "${prefix_reset}" 1>&2 + wrongVariable="true" + fi + + if [ ! -d "$(dirname "${tmp_dir_path}")" ]; then + printf "%bWrong 'tmp_dir_path' set in adsorber.conf. Can't access: %s%b\n" "${prefix_fatal}" "$(dirname "${tmp_dir_path}")" "${prefix_reset}" 1>&2 + wrongVariable="true" + fi + + if [ -n "${wrongVariable}" ]; then # When wrongVariable is set then ... + remove_ErrorCleanUp exit 126 fi @@ -171,19 +238,22 @@ isVariableValid() } -printVariables() +config_PrintVariables() { - echo -e " - PRIMARY_LIST: ${PRIMARY_LIST}" - echo -e " - USE_PARTIAL_MATCHING: ${USE_PARTIAL_MATCHING}" - echo -e " - IGNORE_DOWNLOAD_ERROR: ${IGNORE_DOWNLOAD_ERROR}" - echo -e " - HTTP_PROXY: ${HTTP_PROXY}" - echo -e " - HTTPS_PROXY: ${HTTPS_PROXY}" - echo -e " - HOSTS_FILE_PATH:: ${HOSTS_FILE_PATH}" - echo -e " - HOSTS_FILE_BACKUP_PATH: ${HOSTS_FILE_BACKUP_PATH}" - echo -e " - CRONTAB_DIR_PATH: ${CRONTAB_DIR_PATH}" - echo -e " - SYSTEMD_DIR_PATH: ${SYSTEMD_DIR_PATH}" - echo -e " - TMP_DIR_PATH: ${TMP_DIR_PATH}" - echo -e " - SCRIPT_DIR_PATH: ${SCRIPT_DIR_PATH}" + echo " Invoked with: ${0} ${operation} ${options}" + echo " - primary_list: ${primary_list}" + echo " - use_partial_matching: ${use_partial_matching}" + echo " - ignore_download_error: ${ignore_download_error}" + echo " - http_proxy: ${http_proxy}" + echo " - https_proxy: ${https_proxy}" + echo " - hosts_file_path: ${hosts_file_path}" + echo " - hosts_file_backup_path: ${hosts_file_backup_path}" + echo " - hosts_file_previous_enable: ${hosts_file_previous_enable}" + echo " - hosts_file_previous_path: ${hosts_file_previous_path}" + echo " - crontab_dir_path: ${crontab_dir_path}" + echo " - systemd_dir_path: ${systemd_dir_path}" + echo " - tmp_dir_path: ${tmp_dir_path}" + echo " - script_dir_path: ${script_dir_path}" return 0 } @@ -191,17 +261,17 @@ printVariables() config() { - echo -e "${PREFIX_TITLE}Reading configuration ... ${COLOUR_RESET}" - configCreateTmpDir - copySourceList - copyWhiteList - copyBlackList - copyConfig - filterConfig - readConfig - isVariableSet - isVariableValid - #printVariables # used for debugging + printf "%b" "${prefix_title}Reading configuration ... ${prefix_reset}\n" + config_CreateTmpDir + config_CopySourceList + config_CopyWhiteList + config_CopyBlackList + config_CopyConfig + config_FilterConfig + config_ReadConfig + config_IsVariableSet + config_IsVariableValid + #config_PrintVariables # used for debugging return 0 } diff --git a/bin/cron/80adsorber b/bin/cron/80adsorber index b874288..43a9f50 100755 --- a/bin/cron/80adsorber +++ b/bin/cron/80adsorber @@ -1,6 +1,6 @@ -#!/bin/bash +#!/bin/sh # -# A(d)sorber's cron file +# A(d)sorber v#@version@# crontab file # Updates the hosts file once a week. # # For more information: https://github.com/stablestud/adsorber @@ -9,4 +9,4 @@ # adsorber.sh install --cron: # This file is going to be copied into /etc/cron.weekly/ if not other specified. -#@/some/path/adsorber.sh update # line will be overwritten by script (DO NOT EDIT)#@ +#@/some/path/adsorber.sh update@# diff --git a/bin/default/default-adsorber.conf b/bin/default/default-adsorber.conf index 91e5a76..d0eb648 100755 --- a/bin/default/default-adsorber.conf +++ b/bin/default/default-adsorber.conf @@ -1,4 +1,3 @@ -#!/bin/bash #@ Config file for Adsorber v?.?.? (DO NOT EDIT, WILL BE OVERWRITTEN BY SCRIPT)@ # # To reset the config file just delete it and run 'adsorber.sh install', a new @@ -8,7 +7,7 @@ # Don't hesitate to create issues and pull-requests. -## PRIMARY_LIST +## primary_list # Defines what list (either whitelist or blacklist) has the priority. # # For example: if 'blacklist' is set, the blacklist will overwrite @@ -18,26 +17,26 @@ # Possible values: whitelist, blacklist # Default value: blacklist -PRIMARY_LIST=blacklist +primary_list=blacklist -## USE_PARTIAL_MATCHING +## use_partial_matching # Defines whether the WHITELIST includes sub-domains or not. # # For example: You white listed the domain wholesome-ads.com, if the value # is set to 'true' all it's sub-domains like annoying.wholesome-ads.com will be # also allowed. To disable this set the value to 'false'. # -# Note: if you set PRIMARY_LIST to blacklist you still can block it's +# Note: if you set primary_list to blacklist you still can block it's # specific sub-domains or top-level domain in the blacklist. # # Possible values: true, false # Default value: true -USE_PARTIAL_MATCHING=true +use_partial_matching=true -## IGNORE_DOWNLOAD_ERROR +## ignore_download_error # If set to false, we'll only apply the hosts file if all hosts sources # could be reached. # @@ -48,10 +47,10 @@ USE_PARTIAL_MATCHING=true # Possible values: true, false # Default value: true -IGNORE_DOWNLOAD_ERROR=true +ignore_download_error=true -## HTTP_PROXY, HTTPS_PROXY ## +## http_proxy, https_proxy ## # Specify what proxy server should be used when fetching the host domains. # This will set or overwrite the environment variables of # 'http_proxy' and 'https_proxy'. @@ -59,29 +58,41 @@ IGNORE_DOWNLOAD_ERROR=true # Possible value: address:port (e.g proxy:8080, 127.0.0.1:9050) # Default value: Null (not set) -HTTP_PROXY= -HTTPS_PROXY= +http_proxy= +https_proxy= -## HOSTS_FILE_PATH -# HOSTS_FILE_PATH is used to set the path to the systems hosts file. +## hosts_file_path +# hosts_file_pat is used to set the path to the systems hosts file. # Change if your system uses an other file or path. # # Default value: /etc/hosts -HOSTS_FILE_PATH=/etc/hosts +hosts_file_path=/etc/hosts -## HOSTS_FILE_BACKUP_PATH ## -# HOSTS_FILE_BACKUP_PATH is used to set the filename and the path to the +## hosts_file_backup_path ## +# hosts_file_backup_path is used to set the filename and the path to the # backup of the hosts file to be created by Adsorber in the install process. # To simply create a new backup run 'adsorber.sh install' # # Default value: /etc/hosts.original -HOSTS_FILE_BACKUP_PATH=/etc/hosts.original +hosts_file_backup_path=/etc/hosts.original -## CRONTAB_DIR_PATH +## hosts_file_previous_enable, hosts_file_previous_path ## +# Info goes here +# +# Possible values for 'hosts_file_previous_enable': true, false +# Default value for 'hosts_file_previous_enable': true +# +# Default value for 'hosts_file_previous_path': /etc/hosts.previous + +hosts_file_previous_enable=true +hosts_file_previous_path=/etc/hosts.previous + + +## crontab_dir_path # This defines the directory in which we'll set the crontab. # Used to create a scheduler which supplies the hosts file regulary with # new ad-domains. @@ -90,25 +101,25 @@ HOSTS_FILE_BACKUP_PATH=/etc/hosts.original # with setting another directory, for example /etc/cron/daily to update the # hosts file daily. # -# Possible value: /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, -# /etc/cron.monthly, or any other directory which it's contents will be +# Possible value: /etc/cron.hourly/, /etc/cron.daily/, /etc/cron.weekly/, +# /etc/cron.monthly/, or any other directory which it's contents will be # executed as a script regulary. # -# Default value: /etc/cron.weekly +# Default value: /etc/cron.weekly/ -CRONTAB_DIR_PATH=/etc/cron.weekly +crontab_dir_path=/etc/cron.weekly/ -## SYSTEMD_DIR_PATH +## systemd_dir_path # This defines the directory in which we'll place the systemd files. # Used to create a scheduler which supplies the hosts file regulary with # new ad-domains. Change if your system has an other path. # # In the default setting it'll update once a week. To change this behavior you # need to change adsorber.timer's 'OnCalendar' setting to another period. -# The file can be found at SYSTEMD_DIR_PATH, to change it before placement go +# The file can be found at systemd_dir_path, to change it before placement go # into the scripts root directory and edit bin/systemd/adsorber.timer # -# Default value: /etc/systemd/system +# Default value: /etc/systemd/system/ -SYSTEMD_DIR_PATH=/etc/systemd/system +systemd_dir_path=/etc/systemd/system/ diff --git a/bin/default/default-blacklist b/bin/default/default-blacklist index b119151..6437a3c 100755 --- a/bin/default/default-blacklist +++ b/bin/default/default-blacklist @@ -1,6 +1,6 @@ # Blacklist -# Use to manually block domains. I's content will be added to /etc/hosts. -# By default the blacklist overwrites the whitelist. This can be changed in adsorber.conf. +# Use to manually block domains. It's contents will be added to the hosts file. +# By default the blacklist overwrites the whitelist. This can be changed in adsorber.conf # # Entries must begin with either 127.0.0.1 or 0.0.0.0 diff --git a/bin/default/default-whitelist b/bin/default/default-whitelist index d888638..fad217e 100755 --- a/bin/default/default-whitelist +++ b/bin/default/default-whitelist @@ -4,7 +4,7 @@ # # Note: the whitelist uses partial matching. Means if you allow adserver.tld # all its subdomains like ad1.adserver.tld also will be allowed. -# (Can be changed in adsorber.conf by editing USE_PARTIAL_MATCHING) +# (Can be changed in adsorber.conf by editing 'use_partial_matching') # # Entries must begin with either 127.0.0.1 or 0.0.0.0 diff --git a/bin/install.sh b/bin/install.sh index baec5b2..99e5abb 100755 --- a/bin/install.sh +++ b/bin/install.sh @@ -1,116 +1,120 @@ -#!/bin/bash +#!/bin/sh # Author: stablestud <adsorber@stablestud.org> # Repository: https://github.com/stablestud/adsorber # License: MIT, https://opensource.org/licenses/MIT -# The following variables are declared in adsorber.conf, adsorber.sh or bin/config.sh. +# The following variables are declared globally. # If you run this file independently following variables need to be set: # ---variable:------------- ---default value:---- ---defined in:-------------- -# CRONTAB_DIR_PATH /etc/cron.weekly bin/config.sh, adsorber.conf -# COLOUR_RESET \033[0m bin/colours.sh -# HOSTS_FILE_PATH /etc/hosts bin/config.sh, adsorber.sh -# HOSTS_FILE_BACKUP_PATH /etc/hosts.original bin/config.sh, adsorber.sh -# PREFIX ' ' (two spaces) bin/colours.sh -# PREFIX_INPUT ' ' (two spaces) bin/colours.sh -# PREFIX_FATAL '\033[0;91mE ' bin/colours.sh -# PREFIX_TITLE \033[1;37m bin/colours.sh -# PREFIX_WARNING '- ' bin/colours.sh -# REPLY_TO_PROMPT Null (not set) bin/install.sh, adsorber.sh -# REPLY_TO_SCHEDULER_PROMPT Null (not set) bin/install.sh, adsorber.sh -# SCRIPT_DIR_PATH script root directory adsorber.sh +# crontab_dir_path /etc/cron.weekly bin/config.sh, adsorber.conf +# hosts_file_path /etc/hosts bin/config.sh, adsorber.conf +# hosts_file_backup_path /etc/hosts.original bin/config.sh, adsorber.conf +# prefix ' ' (two spaces) bin/colours.sh +# prefix_input ' ' (two spaces) bin/colours.sh +# prefix_fatal '\033[0;91mE ' bin/colours.sh +# prefix_reset \033[0m bin/colours.sh +# prefix_title \033[1;37m bin/colours.sh +# prefix_warning '- ' bin/colours.sh +# reply_to_prompt Null (not set) bin/install.sh, adsorber.sh +# reply_to_scheduler_prompt Null (not set) bin/install.sh, adsorber.sh +# script_dir_path script root directory adsorber.sh # (e.g., /home/user/Downloads/adsorber) -# SYSTEMD_DIR_PATH /etc/systemd/system bin/config.sh, adsorber.conf +# systemd_dir_path /etc/systemd/system bin/config.sh, adsorber.conf +# version 0.2.2 or similar adsorber.sh # The following functions are defined in different files. # If you run this file independently following functions need to be emulated: -# ---function:----- ---function defined in:--- -# cleanUp bin/remove.sh -# errorCleanUp bin/remove.sh -# removeSystemd bin/remove.sh +# ---function:----- ---function defined in:--- +# remove_ErrorCleanUp bin/remove.sh +# remove_Systemd bin/remove.sh -backupHostsFile() +install_BackupHostsFile() { - if [ ! -f "${HOSTS_FILE_BACKUP_PATH}" ]; then - cp "${HOSTS_FILE_PATH}" "${HOSTS_FILE_BACKUP_PATH}" \ - && echo "${PREFIX}Successfully created backup of ${HOSTS_FILE_PATH} to ${HOSTS_FILE_BACKUP_PATH}." - readonly BACKEDUP="true" + if [ ! -f "${hosts_file_backup_path}" ]; then + cp "${hosts_file_path}" "${hosts_file_backup_path}" \ + && echo "${prefix}Successfully created backup of ${hosts_file_path} to ${hosts_file_backup_path}." + readonly backedup="true" else - echo "${PREFIX}Backup already exist, no need to backup." + echo "${prefix}Backup already exist, no need to backup." fi return 0 } -installCronjob() +install_Cronjob() { - echo "${PREFIX}Installing cronjob ..." + echo "${prefix}Installing cronjob ..." - if [ ! -d "${CRONTAB_DIR_PATH}" ]; then - echo -e "${PREFIX_FATAL}Wrong CRONTAB_DIR_PATH set. Can't access: ${CRONTAB_DIR_PATH}.${COLOUR_RESET}" 1>&2 - errorCleanUp + if [ ! -d "${crontab_dir_path}" ]; then + printf "%bWrong crontab_dir_path set. Can't access: %s.%b\n" "${prefix_fatal}" "${crontab_dir_path}" "${prefix_reset}" 1>&2 + remove_ErrorCleanUp exit 126 fi - # Replace the @ place holder line with SCRIPT_DIR_PATH and copy the content to cron's directory - sed "s|^#@.\+#@$|${SCRIPT_DIR_PATH}\/adsorber\.sh update|g" "${SCRIPT_DIR_PATH}/bin/cron/80adsorber" > "${CRONTAB_DIR_PATH}/80adsorber" - chmod u=rwx,g=rx,o=rx "${CRONTAB_DIR_PATH}/80adsorber" + # Replace the @ place holder line with script_dir_path and copy the content to cron's directory + sed "s|#@version@#|${version}|g" "${script_dir_path}/bin/cron/80adsorber" \ + | sed "s|^#@\/some\/path\/adsorber\.sh update@#$|${script_dir_path}\/adsorber\.sh update|g" \ + > "${crontab_dir_path}/80adsorber" + chmod u=rwx,g=rx,o=rx "${crontab_dir_path}/80adsorber" - readonly INSTALLED_SCHEDULER="cronjob" + readonly installed_scheduler="cronjob" return 0 } -installSystemd() +install_Systemd() { - if [ ! -d "${SYSTEMD_DIR_PATH}" ]; then - echo -e "${PREFIX_FATAL}Wrong SYSTEMD_DIR_PATH set. Can't access: ${SYSTEMD_DIR_PATH}.${COLOUR_RESET}" 1>&2 - errorCleanUp + if [ ! -d "${systemd_dir_path}" ]; then + printf "%bWrong systemd_dir_path set. Can't access: %s.%b\n" "${prefix_fatal}" "${systemd_dir_path}" "${prefix_reset}" 1>&2 + remove_ErrorCleanUp exit 126 fi # Remove systemd service if already installed (requires remove.sh) - if [ -f "${SYSTEMD_DIR_PATH}/adsorber.service" ] || [ -f "${SYSTEMD_DIR_PATH}/adsorber.timer" ]; then - echo "${PREFIX}Removing previous installed systemd service ..." - removeSystemd + if [ -f "${systemd_dir_path}/adsorber.service" ] || [ -f "${systemd_dir_path}/adsorber.timer" ]; then + echo "${prefix}Removing previous installed systemd service ..." + remove_Systemd fi - echo "${PREFIX}Installing systemd service ..." + echo "${prefix}Installing systemd service ..." - # Replace the @ place holder line with SCRIPT_DIR_PATH and copy to its systemd directory - sed "s|^#@ExecStart.\+#@$|ExecStart=${SCRIPT_DIR_PATH}\/adsorber\.sh update|g" "${SCRIPT_DIR_PATH}/bin/systemd/adsorber.service" > "${SYSTEMD_DIR_PATH}/adsorber.service" - cp "${SCRIPT_DIR_PATH}/bin/systemd/adsorber.timer" "${SYSTEMD_DIR_PATH}/adsorber.timer" + # Replace the @ place holder line with script_dir_path and copy to its systemd directory + sed "s|^#@ExecStart=\/some\/path\/adsorber\.sh update@#$|ExecStart=${script_dir_path}\/adsorber\.sh update|g" "${script_dir_path}/bin/systemd/adsorber.service" \ + > "${systemd_dir_path}/adsorber.service" + cp "${script_dir_path}/bin/systemd/adsorber.timer" "${systemd_dir_path}/adsorber.timer" - chmod u=rwx,g=rx,o=rx "${SYSTEMD_DIR_PATH}/adsorber.service" "${SYSTEMD_DIR_PATH}/adsorber.timer" + chmod u=rwx,g=rx,o=rx "${systemd_dir_path}/adsorber.service" "${systemd_dir_path}/adsorber.timer" # Enable the systemd service systemctl daemon-reload \ - && systemctl enable adsorber.timer | printf "%s" "${PREFIX}" \ - && systemctl start adsorber.timer || echo -e "${PREFIX_WARNING}Couldn't start systemd service." 1>&2 + && systemctl enable adsorber.timer | printf "%s" "${prefix}" \ + && systemctl start adsorber.timer || printf "%bCouldn't start systemd service.\n" "${prefix_warning}" 1>&2 - readonly INSTALLED_SCHEDULER="systemd" + readonly installed_scheduler="systemd" return 0 } -promptInstall() +install_Prompt() { - if [ -z "${REPLY_TO_PROMPT}" ]; then - read -r -p "${PREFIX_INPUT}Do you really want to install Adsorber? [Y/n]: " REPLY_TO_PROMPT + if [ -z "${reply_to_prompt}" ]; then + printf "%bDo you really want to install Adsorber? [Y/n]: %b" "${prefix_input}" "${prefix_reset}" + read -r reply_to_prompt fi - case "${REPLY_TO_PROMPT}" in + case "${reply_to_prompt}" in [Yy] | [Yy][Ee][Ss] ) return 0 ;; * ) - echo -e "${PREFIX_WARNING}Installation cancelled." 1>&2 - errorCleanUp + printf "%bInstallation cancelled.\n" "${prefix_warning}" 1>&2 + remove_ErrorCleanUp exit 130 ;; esac @@ -119,21 +123,22 @@ promptInstall() } -promptScheduler() +install_PromptScheduler() { - if [ -z "${REPLY_TO_SCHEDULER_PROMPT}" ]; then - read -r -p "${PREFIX_INPUT}What scheduler should be used to update hosts file automatically? [(S)ystemd/(C)ron/(N)one]: " REPLY_TO_SCHEDULER_PROMPT + if [ -z "${reply_to_scheduler_prompt}" ]; then + printf "%bWhat scheduler should be used to update the host file automatically? [(S)ystemd/(C)ron/(N)one]: %b" "${prefix_input}" "${prefix_reset}" + read -r reply_to_scheduler_prompt fi - case "${REPLY_TO_SCHEDULER_PROMPT}" in + case "${reply_to_scheduler_prompt}" in [Ss] | [Ss]ystemd | [Ss][Yy][Ss] ) - installSystemd + install_Systemd ;; [Cc] | [Cc]ron | [Cc]ron[Jj]ob | [Cc]ron[Tt]ab ) - installCronjob + install_Cronjob ;; * ) - echo "${PREFIX}Skipping scheduler creation ..." + echo "${prefix}Skipping scheduler creation ..." ;; esac @@ -141,12 +146,19 @@ promptScheduler() } +install_command() +{ + + return 0 +} + + install() { - echo -e "${PREFIX_TITLE}Installing Adsorber ...${COLOUR_RESET}" - promptInstall - backupHostsFile - promptScheduler + printf "%bInstalling Adsorber ...%b\n" "${prefix_title}" "${prefix_reset}" + install_Prompt + install_BackupHostsFile + install_PromptScheduler return 0 } diff --git a/bin/remove.sh b/bin/remove.sh index 7b165a2..1eab7c5 100755 --- a/bin/remove.sh +++ b/bin/remove.sh @@ -1,110 +1,111 @@ -#!/bin/bash +#!/bin/sh # Author: stablestud <adsorber@stablestud.org> # Repository: https://github.com/stablestud/adsorber # License: MIT, https://opensource.org/licenses/MIT -# The following variables are declared in adsorber.conf, adsorber.sh or bin/config.sh. +# The following variables are declared globally. # If you run this file independently following variables need to be set: # ---variable:------- ---default value:---- ---defined in:-------------- -# BACKEDUP Null (not set) bin/install.sh -# CRONTAB_DIR_PATH /etc/cron.weekly bin/config.sh, adsorber.conf -# COLOUR_RESET \033[0m bin/colours.sh -# HOSTS_FILE_BACKUP_PATH /etc/hosts.original bin/config.sh, adsorber.conf -# INSTALLED_SCHEDULER Null (not set) bin/install.sh -# PREFIX ' ' (two spaces) bin/colours.sh -# PREFIX_INPUT ' ' (two spaces) bin/colours.sh -# PREFIX_TITLE \033[1;37m bin/colours.sh -# PREFIX_WARNING '- ' bin/colours.sh -# REPLY_TO_PROMPT Null (not set) bin/install.sh, adsorber.sh -# SCRIPT_DIR_PATH script root directory adsorber.sh -# (e.g., /home/user/Downloads/adsorber) -# SYSTEMD_DIR_PATH /etc/systemd/system bin/config.sh, adsorber.conf - - -errorCleanUp() +# backedup Null (not set) bin/install.sh +# crontab_dir_path /etc/cron.weekly bin/config.sh, adsorber.conf +# hosts_file_backup_path /etc/hosts.original bin/config.sh, adsorber.conf +# installed_scheduler Null (not set) bin/install.sh +# prefix ' ' (two spaces) bin/colours.sh +# prefix_input ' ' (two spaces) bin/colours.sh +# prefix_reset \033[0m bin/colours.sh +# prefix_title \033[1;37m bin/colours.sh +# prefix_warning '- ' bin/colours.sh +# reply_to_prompt Null (not set) bin/install.sh, adsorber.sh +# systemd_dir_path /etc/systemd/system bin/config.sh, adsorber.conf + + +remove_ErrorCleanUp() { - echo "${PREFIX_WARNING}Cleaning up ..." + printf "%bCleaning up ...\n" "${prefix_warning}" - # Remove scheduler if installed - case "${INSTALLED_SCHEDULER}" in + # Remove scheduler if installed in the same run + case "${installed_scheduler}" in cronjob ) - removeCronjob + remove_Cronjob ;; systemd ) - removeSystemd + remove_Systemd ;; esac - if [ "${BACKEDUP}" == "true" ]; then - rm -f "${HOSTS_FILE_BACKUP_PATH}" + if [ "${backedup}" = "true" ]; then + rm "${hosts_file_backup_path}" fi - rm -rf "${TMP_DIR_PATH}" 2>/dev/null 1>&2 + if [ -d "${tmp_dir_path}" ]; then + rm -r "${tmp_dir_path}" + fi return 0 } -cleanUp() +remove_CleanUp() { - echo "${PREFIX}Cleaning up ..." - - rm -rf "${TMP_DIR_PATH}" 2>/dev/null 1>&2 + echo "${prefix}Cleaning up ..." + rm -r "${tmp_dir_path}" return 0 } -removeSystemd() + +remove_Systemd() { - if [ -f "${SYSTEMD_DIR_PATH}/adsorber.service" ] || [ -f "${SYSTEMD_DIR_PATH}/adsorber.timer" ]; then + if [ -f "${systemd_dir_path}/adsorber.service" ] || [ -f "${systemd_dir_path}/adsorber.timer" ]; then systemctl stop adsorber.timer 2>/dev/null - systemctl disable adsorber.timer | ( printf "%s" "${PREFIX}" && cat ) + systemctl disable adsorber.timer | ( printf "%b" "${prefix}" && cat ) # Add "${prefix} to the output stream" systemctl stop adsorber.service 2>/dev/null 1>&2 systemctl disable adsorber.service 2>/dev/null 1>&2 # The service is not enabled by default - rm "${SYSTEMD_DIR_PATH}/adsorber.timer" "${SYSTEMD_DIR_PATH}/adsorber.service" \ + rm "${systemd_dir_path}/adsorber.timer" "${systemd_dir_path}/adsorber.service" \ || { - echo -e "${PREFIX_WARNING}Couldn't remove systemd service files at ${SYSTEMD_DIR_PATH}." 1>&2 + printf "%bCouldn't remove systemd service files at %s\n." "${prefix_warning}" "${systemd_dir_path}" 1>&2 return 1 } systemctl daemon-reload else - echo "${PREFIX}Systemd service not installed. Skipping ..." 1>&2 + echo "${prefix}Systemd service not installed. Skipping ..." fi return 0 } -removeCronjob() +remove_Cronjob() { - if [ -f "${CRONTAB_DIR_PATH}/80adsorber" ]; then - rm "${CRONTAB_DIR_PATH}/80adsorber" \ - && echo "${PREFIX}Removed Adsorber's cronjob." + if [ -f "${crontab_dir_path}/80adsorber" ]; then + rm "${crontab_dir_path}/80adsorber" \ + && echo "${prefix}Removed Adsorber's cronjob." else - echo "${PREFIX}Cronjob not installed. Skipping ..." 1>&2 + echo "${prefix}Cronjob not installed. Skipping ..." fi return 0 } -promptRemove() +remove_Prompt() { - if [ -z "${REPLY_TO_PROMPT}" ]; then - read -r -p "${PREFIX_INPUT}Do you really want to remove Adsorber? [Y/n] " REPLY_TO_PROMPT + if [ -z "${reply_to_prompt}" ]; then + printf "%bDo you really want to remove Adsorber? [Y/n] %b" "${prefix_input}" "${prefix_reset}" + read -r reply_to_prompt fi - case "${REPLY_TO_PROMPT}" in + case "${reply_to_prompt}" in [Yy] | [Yy][Ee][Ss] ) - return 0 + : # Do nothing ;; * ) - echo -e "${PREFIX_WARNING}Remove cancelled." 1>&2 - errorCleanUp + printf "%bRemove cancelled.\n" "${prefix_warning}" 1>&2 + remove_ErrorCleanUp exit 130 ;; esac @@ -113,15 +114,15 @@ promptRemove() } -removeHostsFile() +remove_HostsFile() { - if [ -f "${HOSTS_FILE_BACKUP_PATH}" ]; then - mv "${HOSTS_FILE_BACKUP_PATH}" "${HOSTS_FILE_PATH}" \ - && echo "${PREFIX}Successfully restored ${HOSTS_FILE_PATH}" + if [ -f "${hosts_file_backup_path}" ]; then + mv "${hosts_file_backup_path}" "${hosts_file_path}" \ + && echo "${prefix}Successfully restored ${hosts_file_path}" else - echo -e "${PREFIX_FATAL}Can not restore hosts file. Original hosts file does not exist.${COLOUR_RESET}" 1>&2 - echo "${PREFIX}Maybe already removed?" 1>&2 - errorCleanUp + printf "%bCan not restore hosts file. Original hosts file does not exist.%b\n" "${prefix_fatal}" "${prefix_reset}" 1>&2 + echo "${prefix}Maybe already removed?" 1>&2 + remove_ErrorCleanUp exit 1 fi @@ -129,14 +130,28 @@ removeHostsFile() } +remove_PreviousHostsFile() +{ + if [ -f "${hosts_file_previous_path}" ]; then + rm "${hosts_file_previous_path}" \ + && echo "${prefix}Removed previous hosts file." + else + echo "${prefix}Previous hosts file does not exist. Ignoring ..." + fi + + return 0 +} + + remove() { - echo -e "${PREFIX_TITLE}Removing Adsorber ...${COLOUR_RESET}" - promptRemove - removeSystemd - removeCronjob - removeHostsFile - cleanUp + printf "%bRemoving Adsorber ...%b\n" "${prefix_title}" "${prefix_reset}" + remove_Prompt + remove_Systemd + remove_Cronjob + remove_HostsFile + remove_PreviousHostsFile + remove_CleanUp return 0 } diff --git a/bin/restore.sh b/bin/restore.sh new file mode 100755 index 0000000..e858b67 --- /dev/null +++ b/bin/restore.sh @@ -0,0 +1,49 @@ +#!/bin/sh + +# Author: stablestud <adsorber@stablestud.org> +# Repository: https://github.com/stablestud/adsorber +# License: MIT, https://opensource.org/licenses/MIT + +# The following variables are declared globally. +# If you run this file independently following variables need to be set: +# ---variable:---------- ---default value:-- ---declared in:------------- +# hosts_file_path /etc/hosts bin/config.sh, adsorber.conf +# hosts_file_backup_path /etc/hosts.original bin/config.sh, adsorber.conf +# prefix ' ' (two spaces) bin/colours.sh +# prefix_reset \033[0m bin/colours.sh +# prefix_title \033[1;37m bin/colours.sh +# prefix_warning '- ' bin/colours.sh + +# The following functions are defined in different files. +# If you run this file independently following functions need to be emulated: +# ---function:----- ---function defined in:--- +# remove_CleanUp bin/remove.sh +# remove_ErrorCleanUp bin/remove.sh + + +restore_HostsFile() +{ + if [ -f "${hosts_file_backup_path}" ]; then + cp "${hosts_file_backup_path}" "${hosts_file_path}" \ + && { + printf "%bSuccessfully restored %s.\n" "${prefix}" "${hosts_file_path}" + printf "%bTo reapply please run './adsorber.sh update'.\n" "${prefix}" + } + else + printf "%bCan't restore hosts file. Original hosts file does not exist.%b\n" "${prefix_fatal}" "${prefix_reset}" 1>&2 + remove_ErrorCleanUp + exit 1 + fi + + return 0 +} + + +restore() +{ + printf "%bRestoring %s ...%b\n" "${prefix_title}" "${hosts_file_path}" "${prefix_reset}" + restore_HostsFile + remove_CleanUp + + return 0 +} diff --git a/bin/revert.sh b/bin/revert.sh index 974abff..49799a0 100755 --- a/bin/revert.sh +++ b/bin/revert.sh @@ -1,47 +1,49 @@ -#!/bin/bash +#!/bin/sh # Author: stablestud <adsorber@stablestud.org> # Repository: https://github.com/stablestud/adsorber # License: MIT, https://opensource.org/licenses/MIT -# The following variables are declared in adsorber.conf, adsorber.sh or bin/config.sh. +# The following variables are declared globally. # If you run this file independently following variables need to be set: # ---variable:---------- ---default value:-- ---declared in:------------- -# COLOUR_RESET \033[0m bin/colours.sh -# HOSTS_FILE_PATH /etc/hosts adsorber.conf, bin/config.sh -# HOSTS_FILE_BACKUP_PATH /etc/hosts.original adsorber.conf, bin/config.sh -# PREFIX ' ' (two spaces) bin/colours.sh -# PREFIX_TITLE \033[1;37m bin/colours.sh -# PREFIX_WARNING '- ' bin/colours.sh +# hosts_file_path /etc/hosts bin/config.sh, adsorber.conf +# hosts_file_previous_path /etc/hosts.previous bin/config.sh, adsorber.conf +# prefix_reset \033[0m bin/colours.sh +# prefix_title \033[1;37m bin/colours.sh # The following functions are defined in different files. # If you run this file independently following functions need to be emulated: -# ---function:----- ---function defined in:--- -# cleanUp bin/remove.sh -# errorCleanUp bin/remove.sh +# ---function:----- ---function defined in:--- +# remove_CleanUp bin/remove.sh +# remove_ErrorCleanUp bin/remove.sh - -revertHostsFile() +revert_HostsFile() { - if [ -f "${HOSTS_FILE_BACKUP_PATH}" ]; then - cp "${HOSTS_FILE_BACKUP_PATH}" "${HOSTS_FILE_PATH}" \ - && echo "${PREFIX}Successfully reverted ${HOSTS_FILE_PATH}." \ - && echo "${PREFIX}To reapply please run './adsorber.sh update'." + if [ -f "${hosts_file_previous_path}" ]; then + cp "${hosts_file_previous_path}" "${hosts_file_path}" \ + || { + printf "%bCouldn't revert %s.%b" "${prefix_fatal}" "${hosts_file_path}" "${prefix_reset}" + remove_ErrorCleanUp + exit 1 + } + sed -n -i '/^## This was the hosts file/{n; $p; x; d}; x; 1!p; ${x;p;}' "${hosts_file_path}" # Remove previous host file notice in hosts file and also the line before + + printf "%bSuccessfully reverted %s.\n" "${prefix}" "${hosts_file_path}" else - echo -e "${PREFIX_FATAL}Can not restore hosts file. Original hosts file does not exist.${COLOUR_RESET}" 1>&2 - errorCleanUp + printf "%bCan't revert hosts file. Previous hosts file does not exist.%b\n" "${prefix_fatal}" "${prefix_reset}" 1>&2 + remove_ErrorCleanUp exit 1 fi - - return 0 + + return 0; } - revert() { - echo -e "${PREFIX_TITLE}Reverting ${HOSTS_FILE_PATH} ...${COLOUR_RESET}" - revertHostsFile - cleanUp - - return 0 + printf "%bReverting %s with %s ...%b\n" "${prefix_title}" "${hosts_file_path}" "${hosts_file_previous_path}" "${prefix_reset}" + revert_HostsFile + remove_CleanUp + + return 0; } diff --git a/bin/systemd/adsorber.service b/bin/systemd/adsorber.service index 8a5cd37..7445d3a 100755 --- a/bin/systemd/adsorber.service +++ b/bin/systemd/adsorber.service @@ -1,9 +1,9 @@ [Unit] Description=Adsorber service to update the hosts file periodically. -Documentation=https://github.com/stablestud/Adsorber +Documentation=https://github.com/stablestud/adsorber After=network.target [Service] Type=oneshot User=root -#@ExecStart=/some/path/adsorber.sh update - line will be overwritten by script (DO NOT EDIT)#@ +#@ExecStart=/some/path/adsorber.sh update@# diff --git a/bin/systemd/adsorber.timer b/bin/systemd/adsorber.timer index ee727e3..bc6f201 100755 --- a/bin/systemd/adsorber.timer +++ b/bin/systemd/adsorber.timer @@ -1,6 +1,6 @@ [Unit] Description=Timer that runs the Adsorber service weekly. -Documentation=https://github.com/stablestud/Adsorber +Documentation=https://github.com/stablestud/adsorber Requires=network-online.target [Timer] diff --git a/bin/update.sh b/bin/update.sh index 0a62e66..5d5a001 100755 --- a/bin/update.sh +++ b/bin/update.sh @@ -1,56 +1,60 @@ -#!/bin/bash +#!/bin/sh # Author: stablestud <adsorber@stablestud.org> # Repository: https://github.com/stablestud/adsorber # License: MIT, https://opensource.org/licenses/MIT -# The following variables are declared in adsorber.conf, adsorber.sh or bin/config.sh. +# The following variables are declared globally. # If you run this file independently following variables need to be set: -# ---variable:---------- ---default value:----------- ---declared in:------------- -# COLOUR_RESET \033[0m bin/colours.sh -# HOSTS_FILE_PATH /etc/hosts bin/config.sh, adsorber.conf -# HOSTS_FILE_BACKUP_PATH /etc/hosts.original bin/config.sh, adsorber.conf -# IGNORE_DOWNLOAD_ERROR true bin/config.sh, adsorber.conf -# PREFIX ' ' (two spaces) bin/colours.sh -# PREFIX_FATAL '\033[0;91mE ' bin/colours.sh -# PREFIX_INFO '\033[0;97m ' bin/colours.sh -# PREFIX_INPUT ' ' (two spaces) bin/colours.sh -# PREFIX_TITLE \033[1;37m bin/colours.sh -# PREFIX_WARNING '- ' bin/colours.sh -# PRIMARY_LIST blacklist bin/config.sh, adsorber.conf -# HTTP_PROXY Null (not set) bin/config.sh, adsorber.conf -# HTTPS_PROXY Null (not set) bin/config.sh, adsorber.conf -# REPLY_TO_FORCE_PROMPT Null (not set) bin/install.sh -# SCRIPT_DIR_PATH script root directory adsorber.sh +# ---variable:---------- ---default value:----------- ---declared in:------------- +# hosts_file_path /etc/hosts bin/config.sh, adsorber.conf +# hosts_file_backup_path /etc/hosts.original bin/config.sh, adsorber.conf +# ignore_download_error true bin/config.sh, adsorber.conf +# prefix ' ' (two spaces) bin/colours.sh +# prefix_fatal '\033[0;91mE ' bin/colours.sh +# prefix_info '\033[0;97m ' bin/colours.sh +# prefix_input ' ' (two spaces) bin/colours.sh +# prefix_reset \033[0m bin/colours.sh +# prefix_title \033[1;37m bin/colours.sh +# prefix_warning '- ' bin/colours.sh +# primary_list blacklist bin/config.sh, adsorber.conf +# http_proxy Null (not set) bin/config.sh, adsorber.conf +# https_proxy Null (not set) bin/config.sh, adsorber.conf +# hosts_file_previous_enable true bin/config.sh, adsorber.conf +# hosts_file_previous_path /etc/hosts.previous bin/config.sh, adsorber.conf +# reply_to_force_prompt Null (not set) bin/install.sh, adsorber.sh +# script_dir_path script root directory adsorber.sh # (e.g., /home/user/Downloads/adsorber) -# SOURCELIST_FILE_PATH SCRIPT_DIR_PATH/sources.list adsorber.sh +# sourcelist_file_path script_dir_path/sources.list adsorber.sh # (e.g., /home/user/Downloads/absorber/sources.list) -# TMP_DIR_PATH /tmp/adsorber adsorber.sh -# USE_PARTIAL_MATCHING true bin/config.sh, adsorber.conf +# tmp_dir_path /tmp/adsorber adsorber.sh +# use_partial_matching true bin/config.sh, adsorber.conf +# version 0.2.2 or similar adsorber.sh # The following functions are defined in different files. # If you run this file independently following functions need to be emulated: -# ---function:----- ---function defined in:--- -# cleanUp bin/remove.sh -# errorCleanUp bin/remove.sh +# ---function:----- ---function defined in:--- +# remove_CleanUp bin/remove.sh +# remove_ErrorCleanUp bin/remove.sh -checkBackupExist() +update_CheckBackupExist() { - if [ ! -f "${HOSTS_FILE_BACKUP_PATH}" ]; then + if [ ! -f "${hosts_file_backup_path}" ]; then - if [ -z "${REPLY_TO_FORCE_PROMPT}" ]; then - echo -e "${PREFIX_FATAL}Backup of ${HOSTS_FILE_PATH} does not exist. To backup run '${0} install'.${COLOUR_RESET}" 1>&2 - read -r -p "${PREFIX_INPUT}Ignore issue and continue? (May break your system, not recommended) [YES/n]: " REPLY_TO_FORCE_PROMPT + if [ -z "${reply_to_force_prompt}" ]; then + printf "%bBackup of %s does not exist. To backup run '%s install'.%b\n" "${prefix_fatal}" "${hosts_file_path}" "${0}" "${prefix_reset}" 1>&2 + printf "%bIgnore issue and continue? (May break your system, not recommended) [YES/n]: %b" "${prefix_input}" "${prefix_reset}" + read -r reply_to_force_prompt fi - case "${REPLY_TO_FORCE_PROMPT}" in + case "${reply_to_force_prompt}" in [Yy][Ee][Ss] ) return 0 ;; * ) - echo -e "${PREFIX_WARNING}Aborted." 1>&2 - errorCleanUp + printf "%bAborted.\n" "${prefix_warning}" 1>&2 + remove_ErrorCleanUp exit 130 ;; esac @@ -60,40 +64,40 @@ checkBackupExist() } -createTmpDir() +update_CreateTmpDir() { - if [ ! -d "${TMP_DIR_PATH}" ]; then - mkdir "${TMP_DIR_PATH}" - elif [ ! -s "${TMP_DIR_PATH}/config-filtered" ]; then - echo "${PREFIX}Removing previous tmp folder ..." - rm -rf "${TMP_DIR_PATH}" - mkdir "${TMP_DIR_PATH}" + if [ ! -d "${tmp_dir_path}" ]; then + mkdir "${tmp_dir_path}" + elif [ ! -s "${tmp_dir_path}/config-filtered" ]; then + echo "${prefix}Removing previous tmp folder ..." + rm -rf "${tmp_dir_path}" + mkdir "${tmp_dir_path}" fi return 0 } -readSourceList() +update_ReadSourceList() { - if [ ! -s "${SOURCELIST_FILE_PATH}" ]; then + if [ ! -s "${sourcelist_file_path}" ]; then - if [ ! -s "${SCRIPT_DIR_PATH}/blacklist" ]; then - echo -e "${PREFIX_FATAL}Missing 'sources.list' and blacklist. To fix run '${0} install'.${COLOUR_RESET}" 1>&2 + if [ ! -s "${script_dir_path}/blacklist" ]; then + printf "%bMissing 'sources.list' and blacklist. To fix run '%s install'.%b\n" "${prefix_fatal}" "${0}" "${prefix_reset}" 1>&2 exit 127 fi - echo "${PREFIX}No sources to fetch from, ignoring ..." + echo "${prefix}No sources to fetch from, ignoring ..." 1>&2 return 1 else # Only read sources with http(s) at the beginning # Remove inline # comments - sed -n '/^\s*http.*/p' "${SOURCELIST_FILE_PATH}" \ + sed -n '/^\s*http.*/p' "${sourcelist_file_path}" \ | sed 's/\s\+#.*//g' \ - > "${TMP_DIR_PATH}/sourceslist-filtered" + > "${tmp_dir_path}/sourceslist-filtered" - if [ ! -s "${TMP_DIR_PATH}/sourceslist-filtered" ]; then - echo "${PREFIX}No hosts set in sources.list, ignoring ..." + if [ ! -s "${tmp_dir_path}/sourceslist-filtered" ]; then + echo "${prefix}No hosts set in sources.list, ignoring ..." return 1 fi @@ -103,108 +107,102 @@ readSourceList() } -readWhiteList() +update_ReadWhiteList() { - if [ ! -f "${SCRIPT_DIR_PATH}/whitelist" ]; then - echo "${PREFIX}Whitelist does not exist, ignoring ..." 1>&2 + if [ ! -f "${script_dir_path}/whitelist" ]; then + echo "${prefix}Whitelist does not exist, ignoring ..." 1>&2 return 1 else - cp "${SCRIPT_DIR_PATH}/whitelist" "${TMP_DIR_PATH}/whitelist" + cp "${script_dir_path}/whitelist" "${tmp_dir_path}/whitelist" - filterDomains "whitelist" "whitelist-filtered" - sortDomains "whitelist-filtered" "whitelist-sorted" + update_FilterDomains "whitelist" "whitelist-filtered" + update_SortDomains "whitelist-filtered" "whitelist-sorted" fi return 0 } -readBlackList() +update_ReadBlackList() { - if [ ! -f "${SCRIPT_DIR_PATH}/blacklist" ]; then - echo "${PREFIX}Blacklist does not exist, ignoring ..." 1>&2 + if [ ! -f "${script_dir_path}/blacklist" ]; then + echo "${prefix}Blacklist does not exist, ignoring ..." 1>&2 return 1 else - cp "${SCRIPT_DIR_PATH}/blacklist" "${TMP_DIR_PATH}/blacklist" + cp "${script_dir_path}/blacklist" "${tmp_dir_path}/blacklist" - filterDomains "blacklist" "blacklist-filtered" - sortDomains "blacklist-filtered" "blacklist-sorted" + update_FilterDomains "blacklist" "blacklist-filtered" + update_SortDomains "blacklist-filtered" "blacklist-sorted" fi return 0 } -setProxy() +update_FetchSources() { - if [ ! -z "${HTTP_PROXY}" ]; then - echo "${PREFIX}Using HTTP proxy: [${HTTP_PROXY}]" - export http_proxy="${HTTP_PROXY}" - fi + total_count=0 + successful_count=0 - if [ ! -z "${HTTPS_PROXY}" ]; then - echo "${PREFIX}Using HTTPS proxy: [${HTTPS_PROXY}]" - export https_proxy="${HTTPS_PROXY}" + if [ -n "${http_proxy}" ]; then + echo "${prefix}Using HTTP proxy: ${http_proxy}" fi - return 0; -} - - -fetchSources() -{ - local total_count=0 - local successful_count=0 - local domain + if [ -n "${https_proxy}" ]; then + echo "${prefix}Using HTTPS proxy: ${https_proxy}" + fi while read -r domain; do - (( total_count++ )) + total_count=$((total_count+1)) - echo -e "${PREFIX_INFO}Getting${COLOUR_RESET}: ${domain}" + printf "%bGetting%b: %s\n" "${prefix_info}" "${prefix_reset}" "${domain}" # Is wget installed? If yes download the hosts files. - if [ "$(type -fP wget)" ]; then - printf "%s" "${PREFIX}" + if command -v wget 2>/dev/null 1>&2; then + printf "%s" "${prefix}" - if wget "${domain}" --show-progress -L --timeout=30 -t 1 -nv -O - >> "${TMP_DIR_PATH}/fetched"; then - (( successful_count++ )) + if wget "${domain}" --show-progress -L --timeout=30 -t 1 -nv -O - >> "${tmp_dir_path}/fetched"; then + successful_count=$((successful_count+1)) else - echo -e "${PREFIX_WARNING}wget couldn't fetch: ${domain}" 1>&2 + printf "%bwget couldn't fetch: %s\n" "${prefix_warning}" "${domain}" 1>&2 fi - # Is curl installed? If yes download the hosts files. - elif [ "$(type -fP curl)" ]; then - if curl "${domain}" -sS -L --connect-timeout 30 --fail --retry 1 >> "${TMP_DIR_PATH}/fetched"; then - (( successful_count++ )) + # Is curl installed? If yes download the hosts files. + elif command -v curl 2>/dev/null 1>&2; then + if curl "${domain}" -sS -L --connect-timeout 30 --fail --retry 1 >> "${tmp_dir_path}/fetched"; then + successful_count=$((successful_count+1)) else - echo -e "${PREFIX_WARNING}Curl couldn't fetch ${domain}" 1>&2 + printf "%bCurl couldn't fetch %s\n" "${prefix_warning}" "${domain}" 1>&2 fi else - echo -e "${PREFIX_FATAL}Neither curl nor wget installed. Can't continue.${COLOUR_RESET}" 1>&2 - errorCleanUp + printf "%bNeither curl nor wget installed. Can't continue.%b\n" "${prefix_fatal}" "${prefix_reset}" 1>&2 + remove_ErrorCleanUp exit 2 fi - done < "${TMP_DIR_PATH}/sourceslist-filtered" + done < "${tmp_dir_path}/sourceslist-filtered" if [ "${successful_count}" -eq 0 ]; then - echo -e "${PREFIX_WARNING}Nothing to apply [${successful_count}/${total_count}]." 1>&2 + printf "%bNothing to apply [%d/%d].\n" "${prefix_warning}" "${successful_count}" "${total_count}" 1>&2 return 1 - elif [ "${IGNORE_DOWNLOAD_ERROR}" == "false" ] && [ ! "${successful_count}" == "${total_count}" ]; then - echo -e "${PREFIX_WARNING}Couldn't fetch all hosts sources [${successful_count}/${total_count}]. Aborting ..." - errorCleanUp + elif [ "${ignore_download_error}" = "false" ] && [ "${successful_count}" -ne "${total_count}" ]; then + printf "%bCouldn't fetch all hosts sources [%d/%d]. Aborting ...\n" "${prefix_warning}" "${successful_count}" "${total_count}" 1>&2 + remove_ErrorCleanUp exit 1 else - echo -e "${PREFIX_INFO}Successfully fetched ${successful_count} out of ${total_count} hosts sources.${COLOUR_RESET}" + printf "%bSuccessfully fetched %d out of %d hosts sources.%b\n" "${prefix_info}" "${successful_count}" "${total_count}" "${prefix_reset}" fi + unset total_count + unset successful_count + return 0 } -filterDomains() +update_FilterDomains() { - local input_file="${1}" - local output_file="${2}" + input_file="${1}" + output_file="${2}" # - replace OSX '\r' and MS-DOS '\r\n' with Unix '\n' (linebreak) # - replace 127.0.0.1 and 127.0.1.1 with 0.0.0.0 @@ -212,93 +210,93 @@ filterDomains() # - remove inline '#' comments # - replace tabs and multiple spaces with one space # - remove domains without a dot (e.g localhost , loopback , ip6-allnodes , etc...) - # - remove domains that are redirecting to *.local - sed 's/\r/\n/g' "${TMP_DIR_PATH}/${input_file}" \ + # - remove domains that are ending with *.local + sed 's/\r/\n/g' "${tmp_dir_path}/${input_file}" \ | sed 's/^\s*127\.0\.[01]\.1/0\.0\.0\.0/g' \ | sed -n '/^\s*0\.0\.0\.0\s\+.\+/p' \ | sed 's/\s\+#.*//g' \ | sed 's/[[:blank:]]\+/ /g' \ | sed -n '/^0\.0\.0\.0\s.\+\..\+/p' \ | sed -n '/\.local\s*$/!p' \ - > "${TMP_DIR_PATH}/${output_file}" + > "${tmp_dir_path}/${output_file}" + + unset input_file + unset output_file return 0 } -sortDomains() +update_SortDomains() { - local input_file="${1}" - local output_file="${2}" + input_file="${1}" + output_file="${2}" # Sort the domains by alphabet and also remove duplicates - sort "${TMP_DIR_PATH}/${input_file}" -f -u -o "${TMP_DIR_PATH}/${output_file}" + sort "${tmp_dir_path}/${input_file}" -f -u -o "${tmp_dir_path}/${output_file}" + + unset input_file + unset output_file return 0 } -applyWhiteList() +update_ApplyWhiteList() { - local domain - - if [ ! -s "${TMP_DIR_PATH}/whitelist-sorted" ]; then - echo "${PREFIX}Whitelist is empty, ignoring ..." + if [ ! -s "${tmp_dir_path}/whitelist-sorted" ]; then + echo "${prefix}Whitelist is empty, ignoring ..." return 1 else - echo "${PREFIX}Applying whitelist ..." + echo "${prefix}Applying whitelist ..." - sed -i 's/^0\.0\.0\.0\s\+//g' "${TMP_DIR_PATH}/whitelist-sorted" - cp "${TMP_DIR_PATH}/cache" "${TMP_DIR_PATH}/applied-whitelist" + sed -i 's/^0\.0\.0\.0\s\+//g' "${tmp_dir_path}/whitelist-sorted" + cp "${tmp_dir_path}/cache" "${tmp_dir_path}/applied-whitelist" while read -r domain; do - if [ "${USE_PARTIAL_MATCHING}" == "true" ]; then + if [ "${use_partial_matching}" = "true" ]; then # Filter out domains from whitelist, also for sub-domains - sed -i "/\.*${domain}$/d" "${TMP_DIR_PATH}/applied-whitelist" - elif [ "${USE_PARTIAL_MATCHING}" == "false" ]; then - # Filter out domains from whitelist, ignoring sub-domains - sed -i "/\s\+${domain}$/d" "${TMP_DIR_PATH}/applied-whitelist" + sed -i "/\.*${domain}$/d" "${tmp_dir_path}/applied-whitelist" else - echo -e "${PREFIX_FATAL}Wrong USE_PARTIAL_MATCHING set, either set it to 'true' or 'false'.${COLOUR_RESET}" 1>&2 - errorCleanUp - exit 127 + # Filter out domains from whitelist, ignoring sub-domains + sed -i "/\s\+${domain}$/d" "${tmp_dir_path}/applied-whitelist" fi - done < "${TMP_DIR_PATH}/whitelist-sorted" + done < "${tmp_dir_path}/whitelist-sorted" - cp "${TMP_DIR_PATH}/applied-whitelist" "${TMP_DIR_PATH}/cache" + cp "${tmp_dir_path}/applied-whitelist" "${tmp_dir_path}/cache" fi return 0 } -mergeBlackList() +update_MergeBlackList() { - if [ ! -s "${TMP_DIR_PATH}/blacklist-sorted" ]; then - echo "${PREFIX}Blacklist is empty, ignoring ..." + if [ ! -s "${tmp_dir_path}/blacklist-sorted" ]; then + echo "${prefix}Blacklist is empty, ignoring ..." return 1 else - echo "${PREFIX}Applying blacklist ..." + echo "${prefix}Applying blacklist ..." - cat "${TMP_DIR_PATH}/cache" "${TMP_DIR_PATH}/blacklist-sorted" >> "${TMP_DIR_PATH}/merged-blacklist" + cat "${tmp_dir_path}/cache" "${tmp_dir_path}/blacklist-sorted" >> "${tmp_dir_path}/merged-blacklist" - filterDomains "merged-blacklist" "merged-blacklist-filtered" - sortDomains "merged-blacklist-filtered" "merged-blacklist-sorted" + update_FilterDomains "merged-blacklist" "merged-blacklist-filtered" + update_SortDomains "merged-blacklist-filtered" "merged-blacklist-sorted" - cp "${TMP_DIR_PATH}/merged-blacklist-sorted" "${TMP_DIR_PATH}/cache" + cp "${tmp_dir_path}/merged-blacklist-sorted" "${tmp_dir_path}/cache" fi return 0 } -isCacheEmpty() +update_IsCacheEmpty() { - if [ ! -s "${TMP_DIR_PATH}/cache" ]; then - echo -e "${PREFIX_WARNING}Nothing to apply." 1>&2 - errorCleanUp + if [ ! -s "${tmp_dir_path}/cache" ]; then + printf "%bNothing to apply.\n" "${prefix_warning}" 1>&2 + remove_ErrorCleanUp exit 1 fi @@ -306,67 +304,79 @@ isCacheEmpty() } -preBuildHosts() +update_BuildHostsFile() { { - # Replace @...@ with the path to the backup hosts - sed "s|#@.\+#@|${HOSTS_FILE_BACKUP_PATH}|g" "${SCRIPT_DIR_PATH}/bin/components/hosts_header" + # Replace #@...@# with variables + sed "s|#@version@#|${version}|g" "${script_dir_path}/bin/components/hosts_header" \ + | sed "s|#@date@#|$(date +'%b %e %X')|g" \ + | sed "s|#@blocked@#|$(wc -l < "${tmp_dir_path}/cache")|g" \ + | sed "s|#@hosts_file_backup_path@#|${hosts_file_backup_path}|g" - echo "" + echo # Add hosts.original - cat "${HOSTS_FILE_BACKUP_PATH}" \ - || echo "${PREFIX}You may want to add your hostname to ${HOSTS_FILE_PATH}" 1>&2 + cat "${hosts_file_backup_path}" \ + || echo "${prefix}You may want to add your hostname to ${hosts_file_path}" 1>&2 - echo "" + echo # Add hosts_title - cat "${SCRIPT_DIR_PATH}/bin/components/hosts_title" - } > "${TMP_DIR_PATH}/hosts" - - return 0 -} + sed "s|#@blocked@#|$(wc -l < "${tmp_dir_path}/cache")|g" "${script_dir_path}/bin/components/hosts_title" - -buildHostsFile() -{ - { - echo "" + echo # Add the fetched ad-domains to the hosts file - cat "${TMP_DIR_PATH}/cache" + cat "${tmp_dir_path}/cache" + + echo - echo "" + # Add the hosts_header to the hosts file in the temporary folder, filter out the line with @ and replace with hosts_file_backup_path + sed "s|#@version@#|${version}|g" "${script_dir_path}/bin/components/hosts_header" \ + | sed "s|#@date@#|$(date +'%b %e %X')|g" \ + | sed "s|#@blocked@#|$(wc -l < "${tmp_dir_path}/cache")|g" \ + | sed "s|#@hosts_file_backup_path@#|${hosts_file_backup_path}|g" - # Add the hosts_header to the hosts file in the temporary folder, filter out the line with @ and replace with HOSTS_FILE_BACKUP_PATH - sed "s|#@.\+#@|${HOSTS_FILE_BACKUP_PATH}|g" "${SCRIPT_DIR_PATH}/bin/components/hosts_header" - } >> "${TMP_DIR_PATH}/hosts" + } > "${tmp_dir_path}/hosts" return 0 } -countBlockedDomains() +update_PreviousHostsFile() { - readonly COUNT_BLOCKED="$(wc -l < "${TMP_DIR_PATH}/cache")" + if [ "${hosts_file_previous_enable}" = "true" ]; then # Check if we should backup the previous hosts file + echo "${prefix}Creating previous hosts file ..." + + # Copy current hosts file to /etc/hosts.previous before the new hosts file will be applied + cp "${hosts_file_path}" "${hosts_file_previous_path}" \ + || { + printf "%bCouldn't create previous hosts file at %s%b\n" "${prefix_fatal}" "${hosts_file_previous_path}" "${prefix_reset}" + remove_ErrorCleanUp + exit 1 + } + + echo "" >> "${hosts_file_previous_path}" + echo "## This was the hosts file before $(date +'%b %e %X')" >> "${hosts_file_previous_path}" + fi - return 0 + return 0; } -applyHostsFile() +update_ApplyHostsFile() { - echo "${PREFIX}Applying new hosts file ..." + echo "${prefix}Applying new hosts file ..." # Replace systems hosts file with the modified version - cp "${TMP_DIR_PATH}/hosts" "${HOSTS_FILE_PATH}" \ + cp "${tmp_dir_path}/hosts" "${hosts_file_path}" \ || { - echo -e "${PREFIX_FATAL}Couldn't apply hosts file. Aborting.${COLOUR_RESET}" 1>&2 - errorCleanUp + printf "%b" "${prefix_fatal}Couldn't apply hosts file. Aborting.${prefix_reset}\n" 1>&2 + remove_ErrorCleanUp exit 126 } - echo -e "${PREFIX_INFO}Successfully applied new hosts file with ${COUNT_BLOCKED} blocked domains.${COLOUR_RESET}" + printf "%bSuccessfully applied new hosts file with %d blocked domains.%b\n" "${prefix_info}" "$(wc -l < "${tmp_dir_path}/cache")" "${prefix_reset}" return 0 } @@ -374,47 +384,45 @@ applyHostsFile() update() { - echo -e "${PREFIX_TITLE}Updating ${HOSTS_FILE_PATH} ...${COLOUR_RESET}" + printf "%bUpdating %s ...%b\n" "${prefix_title}" "${hosts_file_path}" "${prefix_reset}" - checkBackupExist - createTmpDir - readBlackList - readWhiteList - setProxy + update_CheckBackupExist + update_CreateTmpDir + update_ReadBlackList + update_ReadWhiteList - if readSourceList; then - fetchSources - filterDomains "fetched" "fetched-filtered" - sortDomains "fetched-filtered" "fetched-sorted" + if update_ReadSourceList; then + update_FetchSources + update_FilterDomains "fetched" "fetched-filtered" + update_SortDomains "fetched-filtered" "fetched-sorted" - cp "${TMP_DIR_PATH}/fetched-sorted" "${TMP_DIR_PATH}/cache" + cp "${tmp_dir_path}/fetched-sorted" "${tmp_dir_path}/cache" else # Create empty cache file for the ad-domains. - printf "" >> "${TMP_DIR_PATH}/cache" + touch "${tmp_dir_path}/cache" fi - case "${PRIMARY_LIST}" in + case "${primary_list}" in whitelist ) - mergeBlackList - applyWhiteList + update_MergeBlackList + update_ApplyWhiteList ;; blacklist ) - applyWhiteList - mergeBlackList + update_ApplyWhiteList + update_MergeBlackList ;; * ) - echo -e "${PREFIX_FATAL}Wrong PRIMARY_LIST set in adsorber.conf. Choose either 'whitelist' or 'blacklist'${COLOUR_RESET}" 1>&2 - errorCleanUp + printf "%bWrong primary_list set in adsorber.conf. Choose either 'whitelist' or 'blacklist'%b\n" "${prefix_fatal}" "${prefix_reset}" 1>&2 + remove_ErrorCleanUp exit 127 ;; esac - isCacheEmpty - preBuildHosts - buildHostsFile - countBlockedDomains - applyHostsFile - cleanUp + update_IsCacheEmpty + update_BuildHostsFile + update_PreviousHostsFile + update_ApplyHostsFile + remove_CleanUp return 0 } diff --git a/test/shellcheck.sh b/test/shellcheck.sh new file mode 100755 index 0000000..cb73930 --- /dev/null +++ b/test/shellcheck.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +# Checks script files for errors with shellcheck. +# Can be installed via apt or yum. + +readonly script_dir_path="$(cd "$(dirname "${0}")" && pwd)" + +if ! command -v shellcheck 2>/dev/null 1>&2; then + echo "Shellcheck must be installed." +fi + +shellcheck -e SC2154 -e SC1090 -e SC2163 \ + "${script_dir_path}/../adsorber.sh" \ + "${script_dir_path}/../bin/config.sh" \ + "${script_dir_path}/../bin/install.sh" \ + "${script_dir_path}/../bin/update.sh" \ + "${script_dir_path}/../bin/revert.sh" \ + "${script_dir_path}/../bin/restore.sh" \ + "${script_dir_path}/../bin/remove.sh" \ + "${script_dir_path}/../bin/colours.sh"