diff --git a/advanced/Scripts/api.sh b/advanced/Scripts/api.sh index b8c7fe99..4447a127 100755 --- a/advanced/Scripts/api.sh +++ b/advanced/Scripts/api.sh @@ -10,14 +10,12 @@ # This file is copyright under the latest version of the EUPL. # Please see LICENSE file for your rights under this license. - # The basic usage steps are # 1) Test Availability of the API # 2) Try to authenticate (read password if needed) # 3) Get the data from the API endpoint # 4) Delete the session - TestAPIAvailability() { # as we are running locally, we can get the port value from FTL directly @@ -115,14 +113,13 @@ LoginAPI() { echo "API Authentication: CLI password not available" fi - - # If this did not work, ask the user for the password - while [ "${validSession}" = false ] || [ -z "${validSession}" ] ; do + while [ "${validSession}" = false ] || [ -z "${validSession}" ]; do echo "Authentication failed. Please enter your Pi-hole password" # secretly read the password - secretRead; printf '\n' + secretRead + printf '\n' # Try to authenticate again Authentication "${1}" @@ -131,23 +128,23 @@ LoginAPI() { } Authentication() { - sessionResponse="$(curl -skS -X POST "${API_URL}auth" --user-agent "Pi-hole cli " --data "{\"password\":\"${password}\"}" )" + sessionResponse="$(curl -skS -X POST "${API_URL}auth" --user-agent "Pi-hole cli " --data "{\"password\":\"${password}\"}")" - if [ -z "${sessionResponse}" ]; then - echo "No response from FTL server. Please check connectivity" - exit 1 - fi - # obtain validity and session ID from session response - validSession=$(echo "${sessionResponse}"| jq .session.valid 2>/dev/null) - SID=$(echo "${sessionResponse}"| jq --raw-output .session.sid 2>/dev/null) - - if [ "${1}" = "verbose" ]; then - if [ "${validSession}" = true ]; then - echo "API Authentication: ${COL_GREEN}Success${COL_NC}" - else - echo "API Authentication: ${COL_RED}Failed${COL_NC}" + if [ -z "${sessionResponse}" ]; then + echo "No response from FTL server. Please check connectivity" + exit 1 + fi + # obtain validity and session ID from session response + validSession=$(echo "${sessionResponse}" | jq .session.valid 2>/dev/null) + SID=$(echo "${sessionResponse}" | jq --raw-output .session.sid 2>/dev/null) + + if [ "${1}" = "verbose" ]; then + if [ "${validSession}" = true ]; then + echo "API Authentication: ${COL_GREEN}Success${COL_NC}" + else + echo "API Authentication: ${COL_RED}Failed${COL_NC}" + fi fi - fi } LogoutAPI() { @@ -155,56 +152,56 @@ LogoutAPI() { # SID is not null (successful Authentication only), delete the session if [ "${validSession}" = true ] && [ ! "${SID}" = null ]; then # Try to delete the session. Omit the output, but get the http status code - deleteResponse=$(curl -skS -o /dev/null -w "%{http_code}" -X DELETE "${API_URL}auth" -H "Accept: application/json" -H "sid: ${SID}") + deleteResponse=$(curl -skS -o /dev/null -w "%{http_code}" -X DELETE "${API_URL}auth" -H "Accept: application/json" -H "sid: ${SID}") case "${deleteResponse}" in - "401") echo "Logout attempt without a valid session. Unauthorized!";; - "204") if [ "${1}" = "verbose" ]; then echo "API Logout: ${COL_GREEN}Success${COL_NC} (session deleted)"; fi;; - esac; + "401") echo "Logout attempt without a valid session. Unauthorized!" ;; + "204") if [ "${1}" = "verbose" ]; then echo "API Logout: ${COL_GREEN}Success${COL_NC} (session deleted)"; fi ;; + esac elif [ "${1}" = "verbose" ]; then echo "API Logout: ${COL_GREEN}Success${COL_NC} (no valid session)" fi } GetFTLData() { - local data response status - # get the data from querying the API as well as the http status code - response=$(curl -skS -w "%{http_code}" -X GET "${API_URL}$1" -H "Accept: application/json" -H "sid: ${SID}" ) + local data response status + # get the data from querying the API as well as the http status code + response=$(curl -skS -w "%{http_code}" -X GET "${API_URL}$1" -H "Accept: application/json" -H "sid: ${SID}") - if [ "${2}" = "raw" ]; then - # return the raw response - echo "${response}" - else - - # status are the last 3 characters - # not using ${response#"${response%???}"}" here because it's extremely slow on big responses - status=$(printf "%s" "${response}" | tail -c 3) - # data is everything from response without the last 3 characters - data="${response%???}" - - # return only the data - if [ "${status}" = 200 ]; then - # response OK - echo "${data}" + if [ "${2}" = "raw" ]; then + # return the raw response + echo "${response}" else - # connection lost - echo "${status}" + + # status are the last 3 characters + # not using ${response#"${response%???}"}" here because it's extremely slow on big responses + status=$(printf "%s" "${response}" | tail -c 3) + # data is everything from response without the last 3 characters + data="${response%???}" + + # return only the data + if [ "${status}" = 200 ]; then + # response OK + echo "${data}" + else + # connection lost + echo "${status}" + fi fi - fi } PostFTLData() { - local data response status - # send the data to the API - response=$(curl -skS -w "%{http_code}" -X POST "${API_URL}$1" --data-raw "$2" -H "Accept: application/json" -H "sid: ${SID}" ) - # data is everything from response without the last 3 characters - if [ "${3}" = "status" ]; then - # Keep the status code appended if requested - printf %s "${response}" - else - # Strip the status code - printf %s "${response%???}" - fi + local data response status + # send the data to the API + response=$(curl -skS -w "%{http_code}" -X POST "${API_URL}$1" --data-raw "$2" -H "Accept: application/json" -H "sid: ${SID}") + # data is everything from response without the last 3 characters + if [ "${3}" = "status" ]; then + # Keep the status code appended if requested + printf %s "${response}" + else + # Strip the status code + printf %s "${response%???}" + fi } secretRead() { @@ -216,18 +213,16 @@ secretRead() { # `-s` option (suppressing the input) or # `-n` option (reading n chars) - # This workaround changes the terminal characteristics to not echo input and later resets this option # credits https://stackoverflow.com/a/4316765 # showing asterisk instead of password # https://stackoverflow.com/a/24600839 # https://unix.stackexchange.com/a/464963 - # Save current terminal settings (needed for later restore after password prompt) stty_orig=$(stty -g) - stty -echo # do not echo user input + stty -echo # do not echo user input stty -icanon min 1 time 0 # disable canonical mode https://man7.org/linux/man-pages/man3/termios.3.html unset password @@ -235,20 +230,20 @@ secretRead() { unset charcount charcount=0 while key=$(dd ibs=1 count=1 2>/dev/null); do #read one byte of input - if [ "${key}" = "$(printf '\0' | tr -d '\0')" ] ; then + if [ "${key}" = "$(printf '\0' | tr -d '\0')" ]; then # Enter - accept password break fi - if [ "${key}" = "$(printf '\177')" ] ; then + if [ "${key}" = "$(printf '\177')" ]; then # Backspace - if [ $charcount -gt 0 ] ; then - charcount=$((charcount-1)) + if [ $charcount -gt 0 ]; then + charcount=$((charcount - 1)) printf '\b \b' password="${password%?}" fi else # any other character - charcount=$((charcount+1)) + charcount=$((charcount + 1)) printf '*' password="$password$key" fi @@ -259,41 +254,41 @@ secretRead() { } apiFunc() { - local data response status status_col + local data response status status_col - # Authenticate with the API - LoginAPI verbose - echo "" + # Authenticate with the API + LoginAPI verbose + echo "" - echo "Requesting: ${COL_PURPLE}GET ${COL_CYAN}${API_URL}${COL_YELLOW}$1${COL_NC}" - echo "" + echo "Requesting: ${COL_PURPLE}GET ${COL_CYAN}${API_URL}${COL_YELLOW}$1${COL_NC}" + echo "" - # Get the data from the API - response=$(GetFTLData "$1" raw) + # Get the data from the API + response=$(GetFTLData "$1" raw) - # status are the last 3 characters - # not using ${response#"${response%???}"}" here because it's extremely slow on big responses - status=$(printf "%s" "${response}" | tail -c 3) - # data is everything from response without the last 3 characters - data="${response%???}" + # status are the last 3 characters + # not using ${response#"${response%???}"}" here because it's extremely slow on big responses + status=$(printf "%s" "${response}" | tail -c 3) + # data is everything from response without the last 3 characters + data="${response%???}" - # Output the status (200 -> green, else red) - if [ "${status}" = 200 ]; then - status_col="${COL_GREEN}" - else - status_col="${COL_RED}" - fi - echo "Status: ${status_col}${status}${COL_NC}" + # Output the status (200 -> green, else red) + if [ "${status}" = 200 ]; then + status_col="${COL_GREEN}" + else + status_col="${COL_RED}" + fi + echo "Status: ${status_col}${status}${COL_NC}" - # Output the data. Format it with jq if available and data is actually JSON. - # Otherwise just print it - echo "Data:" - if command -v jq >/dev/null && echo "${data}" | jq . >/dev/null 2>&1; then - echo "${data}" | jq . - else - echo "${data}" - fi + # Output the data. Format it with jq if available and data is actually JSON. + # Otherwise just print it + echo "Data:" + if command -v jq >/dev/null && echo "${data}" | jq . >/dev/null 2>&1; then + echo "${data}" | jq . + else + echo "${data}" + fi - # Delete the session - LogoutAPI verbose + # Delete the session + LogoutAPI verbose } diff --git a/advanced/Scripts/database_migration/gravity-db.sh b/advanced/Scripts/database_migration/gravity-db.sh index b0982bcc..f40abe87 100755 --- a/advanced/Scripts/database_migration/gravity-db.sh +++ b/advanced/Scripts/database_migration/gravity-db.sh @@ -12,7 +12,7 @@ readonly scriptPath="/etc/.pihole/advanced/Scripts/database_migration/gravity" -upgrade_gravityDB(){ +upgrade_gravityDB() { local database piholeDir version database="${1}" piholeDir="${2}" @@ -29,7 +29,7 @@ upgrade_gravityDB(){ # This migration script upgraded the gravity.db file by # adding the domain_audit table. It is now a no-op echo -e " ${INFO} Upgrading gravity database from version 1 to 2" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/1_to_2.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/1_to_2.sql" version=2 fi if [[ "$version" == "2" ]]; then @@ -37,28 +37,28 @@ upgrade_gravityDB(){ # renaming the regex table to regex_blacklist, and # creating a new regex_whitelist table + corresponding linking table and views echo -e " ${INFO} Upgrading gravity database from version 2 to 3" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/2_to_3.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/2_to_3.sql" version=3 fi if [[ "$version" == "3" ]]; then # This migration script unifies the formally separated domain # lists into a single table with a UNIQUE domain constraint echo -e " ${INFO} Upgrading gravity database from version 3 to 4" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/3_to_4.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/3_to_4.sql" version=4 fi if [[ "$version" == "4" ]]; then # This migration script upgrades the gravity and list views # implementing necessary changes for per-client blocking echo -e " ${INFO} Upgrading gravity database from version 4 to 5" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/4_to_5.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/4_to_5.sql" version=5 fi if [[ "$version" == "5" ]]; then # This migration script upgrades the adlist view # to return an ID used in gravity.sh echo -e " ${INFO} Upgrading gravity database from version 5 to 6" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/5_to_6.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/5_to_6.sql" version=6 fi if [[ "$version" == "6" ]]; then @@ -66,7 +66,7 @@ upgrade_gravityDB(){ # which is automatically associated to all clients not # having their own group assignments echo -e " ${INFO} Upgrading gravity database from version 6 to 7" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/6_to_7.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/6_to_7.sql" version=7 fi if [[ "$version" == "7" ]]; then @@ -74,21 +74,21 @@ upgrade_gravityDB(){ # to ensure uniqueness on the group name # We also add date_added and date_modified columns echo -e " ${INFO} Upgrading gravity database from version 7 to 8" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/7_to_8.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/7_to_8.sql" version=8 fi if [[ "$version" == "8" ]]; then # This migration fixes some issues that were introduced # in the previous migration script. echo -e " ${INFO} Upgrading gravity database from version 8 to 9" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/8_to_9.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/8_to_9.sql" version=9 fi if [[ "$version" == "9" ]]; then # This migration drops unused tables and creates triggers to remove # obsolete groups assignments when the linked items are deleted echo -e " ${INFO} Upgrading gravity database from version 9 to 10" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/9_to_10.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/9_to_10.sql" version=10 fi if [[ "$version" == "10" ]]; then @@ -98,57 +98,57 @@ upgrade_gravityDB(){ # to keep the copying process generic (needs the same columns in both the # source and the destination databases). echo -e " ${INFO} Upgrading gravity database from version 10 to 11" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/10_to_11.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/10_to_11.sql" version=11 fi if [[ "$version" == "11" ]]; then # Rename group 0 from "Unassociated" to "Default" echo -e " ${INFO} Upgrading gravity database from version 11 to 12" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/11_to_12.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/11_to_12.sql" version=12 fi if [[ "$version" == "12" ]]; then # Add column date_updated to adlist table echo -e " ${INFO} Upgrading gravity database from version 12 to 13" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/12_to_13.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/12_to_13.sql" version=13 fi if [[ "$version" == "13" ]]; then # Add columns number and status to adlist table echo -e " ${INFO} Upgrading gravity database from version 13 to 14" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/13_to_14.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/13_to_14.sql" version=14 fi if [[ "$version" == "14" ]]; then # Changes the vw_adlist created in 5_to_6 echo -e " ${INFO} Upgrading gravity database from version 14 to 15" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/14_to_15.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/14_to_15.sql" version=15 fi if [[ "$version" == "15" ]]; then # Add column abp_entries to adlist table echo -e " ${INFO} Upgrading gravity database from version 15 to 16" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/15_to_16.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/15_to_16.sql" version=16 fi if [[ "$version" == "16" ]]; then # Add antigravity table # Add column type to adlist table (to support adlist types) echo -e " ${INFO} Upgrading gravity database from version 16 to 17" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/16_to_17.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/16_to_17.sql" version=17 fi if [[ "$version" == "17" ]]; then # Add adlist.id to vw_gravity and vw_antigravity echo -e " ${INFO} Upgrading gravity database from version 17 to 18" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/17_to_18.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/17_to_18.sql" version=18 fi if [[ "$version" == "18" ]]; then # Modify DELETE triggers to delete BEFORE instead of AFTER to prevent # foreign key constraint violations echo -e " ${INFO} Upgrading gravity database from version 18 to 19" - pihole-FTL sqlite3 -ni "${database}" < "${scriptPath}/18_to_19.sql" + pihole-FTL sqlite3 -ni "${database}" <"${scriptPath}/18_to_19.sql" version=19 fi } diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh index 5c57f878..0a7a4d58 100755 --- a/advanced/Scripts/list.sh +++ b/advanced/Scripts/list.sh @@ -53,7 +53,7 @@ Options: -l, --list Display domains --comment \"text\" Add a comment to the domain. If adding multiple domains the same comment will be used for all" - exit 0 + exit 0 } CreateDomainList() { @@ -89,7 +89,7 @@ AddDomain() { num=$(echo "${data}" | jq '.processed.success | length') if [[ "${num}" -gt 0 ]] && [[ "${verbose}" == true ]]; then echo -e " ${TICK} Added ${num} domain(s):" - for i in $(seq 0 $((num-1))); do + for i in $(seq 0 $((num - 1))); do echo -e " - ${COL_BLUE}$(echo "${data}" | jq --raw-output ".processed.success[$i].item")${COL_NC}" done fi @@ -98,7 +98,7 @@ AddDomain() { num=$(echo "${data}" | jq '.processed.errors | length') if [[ "${num}" -gt 0 ]] && [[ "${verbose}" == true ]]; then echo -e " ${CROSS} Failed to add ${num} domain(s):" - for i in $(seq 0 $((num-1))); do + for i in $(seq 0 $((num - 1))); do echo -e " - ${COL_BLUE}$(echo "${data}" | jq --raw-output ".processed.errors[$i].item")${COL_NC}" error=$(echo "${data}" | jq --raw-output ".processed.errors[$i].error") if [[ "${error}" == "UNIQUE constraint failed: domainlist.domain, domainlist.type" ]]; then @@ -137,10 +137,10 @@ RemoveDomain() { # If there is an .error object in the returned data, display it local error - error=$(jq --compact-output <<< "${data}" '.error') + error=$(jq --compact-output '.error' <<<"${data}") if [[ $error != "null" && $error != "" ]]; then echo -e " ${CROSS} Failed to remove domain(s):" - echo -e " $(jq <<< "${data}" '.error')" + echo -e " $(jq <<<"${data}" '.error')" elif [[ "${verbose}" == true && "${status}" == "204" ]]; then echo -e " ${TICK} Domain(s) removed from the ${kindId} ${typeId}list" elif [[ "${verbose}" == true && "${status}" == "404" ]]; then @@ -170,7 +170,7 @@ Displaylist() { num=$(echo "${data}" | jq '.domains | length') if [[ "${num}" -gt 0 ]]; then echo -e " ${TICK} Found ${num} domain(s) in the ${kindId} ${typeId}list:" - for i in $(seq 0 $((num-1))); do + for i in $(seq 0 $((num - 1))); do echo -e " - ${COL_BLUE}$(echo "${data}" | jq --compact-output ".domains[$i].domain")${COL_NC}" echo -e " Comment: $(echo "${data}" | jq --compact-output ".domains[$i].comment")" echo -e " Groups: $(echo "${data}" | jq --compact-output ".domains[$i].groups")" @@ -196,20 +196,49 @@ GetComment() { fi } -while (( "$#" )); do +while (("$#")); do case "${1}" in - "allow" | "allowlist" ) kindId="exact"; typeId="allow"; abbrv="allow";; - "deny" | "denylist" ) kindId="exact"; typeId="deny"; abbrv="deny";; - "--allow-regex" | "allow-regex" ) kindId="regex"; typeId="allow"; abbrv="--allow-regex";; - "--allow-wild" | "allow-wild" ) kindId="regex"; typeId="allow"; wildcard=true; abbrv="--allow-wild";; - "--regex" | "regex" ) kindId="regex"; typeId="deny"; abbrv="--regex";; - "--wild" | "wildcard" ) kindId="regex"; typeId="deny"; wildcard=true; abbrv="--wild";; - "-d" | "remove" | "delete" ) addmode=false;; - "-q" | "--quiet" ) verbose=false;; - "-h" | "--help" ) helpFunc;; - "-l" | "--list" ) Displaylist;; - "--comment" ) GetComment "${2}"; shift;; - * ) CreateDomainList "${1}";; + "allow" | "allowlist") + kindId="exact" + typeId="allow" + abbrv="allow" + ;; + "deny" | "denylist") + kindId="exact" + typeId="deny" + abbrv="deny" + ;; + "--allow-regex" | "allow-regex") + kindId="regex" + typeId="allow" + abbrv="--allow-regex" + ;; + "--allow-wild" | "allow-wild") + kindId="regex" + typeId="allow" + wildcard=true + abbrv="--allow-wild" + ;; + "--regex" | "regex") + kindId="regex" + typeId="deny" + abbrv="--regex" + ;; + "--wild" | "wildcard") + kindId="regex" + typeId="deny" + wildcard=true + abbrv="--wild" + ;; + "-d" | "remove" | "delete") addmode=false ;; + "-q" | "--quiet") verbose=false ;; + "-h" | "--help") helpFunc ;; + "-l" | "--list") Displaylist ;; + "--comment") + GetComment "${2}" + shift + ;; + *) CreateDomainList "${1}" ;; esac shift done diff --git a/advanced/Scripts/piholeARPTable.sh b/advanced/Scripts/piholeARPTable.sh index f55b1320..269e77b6 100755 --- a/advanced/Scripts/piholeARPTable.sh +++ b/advanced/Scripts/piholeARPTable.sh @@ -25,7 +25,7 @@ if [ -z "$DBFILE" ]; then DBFILE="/etc/pihole/pihole-FTL.db" fi -flushARP(){ +flushARP() { local output if [[ "${args[1]}" != "quiet" ]]; then echo -ne " ${INFO} Flushing network table ..." @@ -78,5 +78,5 @@ flushARP(){ args=("$@") case "${args[0]}" in - "arpflush" ) flushARP;; +"arpflush") flushARP ;; esac diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh index 84c966df..00aa1e27 100755 --- a/advanced/Scripts/piholeCheckout.sh +++ b/advanced/Scripts/piholeCheckout.sh @@ -28,14 +28,14 @@ warning1() { echo -e " ${COL_LIGHT_RED}This feature is NOT supported unless a Pi-hole developer explicitly asks!${COL_NC}" read -r -p " Have you read and understood this? [y/N] " response case "${response}" in - [yY][eE][sS]|[yY]) - echo "" - return 0 - ;; - *) - echo -e "\\n ${INFO} Branch change has been canceled" - return 1 - ;; + [yY][eE][sS] | [yY]) + echo "" + return 0 + ;; + *) + echo -e "\\n ${INFO} Branch change has been canceled" + return 1 + ;; esac } @@ -53,16 +53,16 @@ checkout() { set -f # This is unlikely - if ! is_repo "${PI_HOLE_FILES_DIR}" ; then + if ! is_repo "${PI_HOLE_FILES_DIR}"; then echo -e " ${COL_LIGHT_RED}Error: Core Pi-hole repo is missing from system!" echo -e " Please re-run install script from https://github.com/pi-hole/pi-hole${COL_NC}" - exit 1; + exit 1 fi - if ! is_repo "${webInterfaceDir}" ; then + if ! is_repo "${webInterfaceDir}"; then echo -e " ${COL_LIGHT_RED}Error: Web Admin repo is missing from system!" echo -e " Please re-run install script from https://github.com/pi-hole/pi-hole${COL_NC}" - exit 1; + exit 1 fi if [[ -z "${1}" ]]; then @@ -71,41 +71,53 @@ checkout() { exit 1 fi - if ! warning1 ; then + if ! warning1; then exit 1 fi - if [[ "${1}" == "dev" ]] ; then + if [[ "${1}" == "dev" ]]; then # Shortcut to check out development branches echo -e " ${INFO} Shortcut \"${COL_YELLOW}dev${COL_NC}\" detected - checking out development branches..." echo "" echo -e " ${INFO} Pi-hole Core" - fetch_checkout_pull_branch "${PI_HOLE_FILES_DIR}" "development" || { echo " ${CROSS} Unable to pull Core development branch"; exit 1; } + fetch_checkout_pull_branch "${PI_HOLE_FILES_DIR}" "development" || { + echo " ${CROSS} Unable to pull Core development branch" + exit 1 + } echo "" echo -e " ${INFO} Web interface" - fetch_checkout_pull_branch "${webInterfaceDir}" "development" || { echo " ${CROSS} Unable to pull Web development branch"; exit 1; } + fetch_checkout_pull_branch "${webInterfaceDir}" "development" || { + echo " ${CROSS} Unable to pull Web development branch" + exit 1 + } #echo -e " ${TICK} Pi-hole Core" local path path="development/${binary}" - echo "development" > /etc/pihole/ftlbranch + echo "development" >/etc/pihole/ftlbranch chmod 644 /etc/pihole/ftlbranch - elif [[ "${1}" == "master" ]] ; then + elif [[ "${1}" == "master" ]]; then # Shortcut to check out master branches echo -e " ${INFO} Shortcut \"${COL_YELLOW}master${COL_NC}\" detected - checking out master branches..." echo -e " ${INFO} Pi-hole core" - fetch_checkout_pull_branch "${PI_HOLE_FILES_DIR}" "master" || { echo " ${CROSS} Unable to pull Core master branch"; exit 1; } + fetch_checkout_pull_branch "${PI_HOLE_FILES_DIR}" "master" || { + echo " ${CROSS} Unable to pull Core master branch" + exit 1 + } echo -e " ${INFO} Web interface" - fetch_checkout_pull_branch "${webInterfaceDir}" "master" || { echo " ${CROSS} Unable to pull Web master branch"; exit 1; } + fetch_checkout_pull_branch "${webInterfaceDir}" "master" || { + echo " ${CROSS} Unable to pull Web master branch" + exit 1 + } #echo -e " ${TICK} Web Interface" local path path="master/${binary}" - echo "master" > /etc/pihole/ftlbranch + echo "master" >/etc/pihole/ftlbranch chmod 644 /etc/pihole/ftlbranch - elif [[ "${1}" == "core" ]] ; then + elif [[ "${1}" == "core" ]]; then str="Fetching branches from ${piholeGitUrl}" echo -ne " ${INFO} $str" - if ! fully_fetch_repo "${PI_HOLE_FILES_DIR}" ; then + if ! fully_fetch_repo "${PI_HOLE_FILES_DIR}"; then echo -e "${OVER} ${CROSS} $str" exit 1 fi @@ -129,10 +141,10 @@ checkout() { exit 1 fi checkout_pull_branch "${PI_HOLE_FILES_DIR}" "${2}" - elif [[ "${1}" == "web" ]] ; then + elif [[ "${1}" == "web" ]]; then str="Fetching branches from ${webInterfaceGitUrl}" echo -ne " ${INFO} $str" - if ! fully_fetch_repo "${webInterfaceDir}" ; then + if ! fully_fetch_repo "${webInterfaceDir}"; then echo -e "${OVER} ${CROSS} $str" exit 1 fi @@ -158,7 +170,7 @@ checkout() { checkout_pull_branch "${webInterfaceDir}" "${2}" # Update local and remote versions via updatechecker /opt/pihole/updatecheck.sh - elif [[ "${1}" == "ftl" ]] ; then + elif [[ "${1}" == "ftl" ]]; then local path local oldbranch local existing=false @@ -167,7 +179,7 @@ checkout() { # Check if requested branch is available echo -e " ${INFO} Checking for availability of branch ${COL_CYAN}${2}${COL_NC} on GitHub" - ftlbranches=( $(git ls-remote https://github.com/pi-hole/ftl | grep "refs/heads" | cut -d'/' -f3- -) ) + ftlbranches=($(git ls-remote https://github.com/pi-hole/ftl | grep "refs/heads" | cut -d'/' -f3- -)) # If returned array is empty -> connectivity issue if [[ ${#ftlbranches[@]} -eq 0 ]]; then echo -e " ${CROSS} Unable to fetch branches from GitHub. Please check your Internet connection and try again later." @@ -187,7 +199,7 @@ checkout() { if check_download_exists "$path"; then echo " ${TICK} Binary exists" - echo "${2}" > /etc/pihole/ftlbranch + echo "${2}" >/etc/pihole/ftlbranch chmod 644 /etc/pihole/ftlbranch echo -e " ${INFO} Switching to branch: ${COL_CYAN}${2}${COL_NC} from ${COL_CYAN}${oldbranch}${COL_NC}" FTLinstall "${binary}" @@ -198,7 +210,7 @@ checkout() { # Wait until name resolution is working again after restarting FTL, # so that the updatechecker can run successfully and does not fail # trying to resolve github.com - until getent hosts github.com &> /dev/null; do + until getent hosts github.com &>/dev/null; do # Append one dot for each second waiting str="${str}." echo -ne " ${OVER} ${INFO} ${str}" @@ -230,7 +242,7 @@ checkout() { fi # Force updating everything - if [[ ! "${1}" == "web" && ! "${1}" == "ftl" ]]; then + if [[ ! "${1}" == "web" && ! "${1}" == "ftl" ]]; then echo -e " ${INFO} Running installer to upgrade your installation" if "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" --unattended; then exit 0 diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh index f4226299..a44a95ba 100755 --- a/advanced/Scripts/piholeDebug.sh +++ b/advanced/Scripts/piholeDebug.sh @@ -106,27 +106,27 @@ RESOLVCONF="${ETC}/resolv.conf" DNSMASQ_CONF="${ETC}/dnsmasq.conf" # Store Pi-hole's processes in an array for easy use and parsing -PIHOLE_PROCESSES=( "pihole-FTL" ) +PIHOLE_PROCESSES=("pihole-FTL") # Store the required directories in an array so it can be parsed through REQUIRED_FILES=("${PIHOLE_CRON_FILE}" -"${PIHOLE_INSTALL_LOG_FILE}" -"${PIHOLE_RAW_BLOCKLIST_FILES}" -"${PIHOLE_LOCAL_HOSTS_FILE}" -"${PIHOLE_LOGROTATE_FILE}" -"${PIHOLE_FTL_CONF_FILE}" -"${PIHOLE_DNSMASQ_CONF_FILE}" -"${PIHOLE_COMMAND}" -"${PIHOLE_COLTABLE_FILE}" -"${FTL_PID}" -"${PIHOLE_LOG}" -"${PIHOLE_LOG_GZIPS}" -"${PIHOLE_DEBUG_LOG}" -"${PIHOLE_FTL_LOG}" -"${PIHOLE_WEBSERVER_LOG}" -"${RESOLVCONF}" -"${DNSMASQ_CONF}" -"${PIHOLE_VERSIONS_FILE}") + "${PIHOLE_INSTALL_LOG_FILE}" + "${PIHOLE_RAW_BLOCKLIST_FILES}" + "${PIHOLE_LOCAL_HOSTS_FILE}" + "${PIHOLE_LOGROTATE_FILE}" + "${PIHOLE_FTL_CONF_FILE}" + "${PIHOLE_DNSMASQ_CONF_FILE}" + "${PIHOLE_COMMAND}" + "${PIHOLE_COLTABLE_FILE}" + "${FTL_PID}" + "${PIHOLE_LOG}" + "${PIHOLE_LOG_GZIPS}" + "${PIHOLE_DEBUG_LOG}" + "${PIHOLE_FTL_LOG}" + "${PIHOLE_WEBSERVER_LOG}" + "${RESOLVCONF}" + "${DNSMASQ_CONF}" + "${PIHOLE_VERSIONS_FILE}") DISCLAIMER="This process collects information from your Pi-hole, and optionally uploads it to a unique and random directory on tricorder.pi-hole.net. @@ -135,7 +135,7 @@ The intent of this script is to allow users to self-diagnose their installations NOTE: All log files auto-delete after 48 hours and ONLY the Pi-hole developers can access your data via the given token. We have taken these extra steps to secure your data and will work to further reduce any personal information gathered. " -show_disclaimer(){ +show_disclaimer() { log_write "${DISCLAIMER}" } @@ -158,7 +158,7 @@ log_write() { copy_to_debug_log() { # Copy the contents of file descriptor 3 into the debug log - cat /proc/$$/fd/3 > "${PIHOLE_DEBUG_LOG}" + cat /proc/$$/fd/3 >"${PIHOLE_DEBUG_LOG}" } initialize_debug() { @@ -196,16 +196,16 @@ compare_local_version_to_git_version() { # If the pihole git directory exists, if [[ -d "${git_dir}" ]]; then # move into it - cd "${git_dir}" || \ - # If not, show an error - log_write "${COL_RED}Could not cd into ${git_dir}$COL_NC" - if git status &> /dev/null; then + cd "${git_dir}" || + # If not, show an error + log_write "${COL_RED}Could not cd into ${git_dir}$COL_NC" + if git status &>/dev/null; then # The current version the user is on local local_version - local_version=$(git describe --tags --abbrev=0 2> /dev/null); + local_version=$(git describe --tags --abbrev=0 2>/dev/null) # What branch they are on local local_branch - local_branch=$(git rev-parse --abbrev-ref HEAD); + local_branch=$(git rev-parse --abbrev-ref HEAD) # The commit they are on local local_commit local_commit=$(git describe --long --dirty --tags --always) @@ -214,11 +214,11 @@ compare_local_version_to_git_version() { local_status=$(git status -s) # echo this information out to the user in a nice format if [ ${local_version} ]; then - log_write "${TICK} Version: ${local_version}" + log_write "${TICK} Version: ${local_version}" elif [ -n "${DOCKER_VERSION}" ]; then - log_write "${TICK} Version: Pi-hole Docker Container ${COL_BOLD}${DOCKER_VERSION}${COL_NC}" + log_write "${TICK} Version: Pi-hole Docker Container ${COL_BOLD}${DOCKER_VERSION}${COL_NC}" else - log_write "${CROSS} Version: not detected" + log_write "${CROSS} Version: not detected" fi # Print the repo upstreams @@ -238,13 +238,13 @@ compare_local_version_to_git_version() { log_write "${INFO} Commit: ${local_commit}" # if `local_status` is non-null, then the repo is not clean, display details here if [[ ${local_status} ]]; then - # Replace new lines in the status with 12 spaces to make the output cleaner - log_write "${INFO} Status: ${local_status//$'\n'/'\n '}" - local local_diff - local_diff=$(git diff) - if [[ ${local_diff} ]]; then - log_write "${INFO} Diff: ${local_diff//$'\n'/'\n '}" - fi + # Replace new lines in the status with 12 spaces to make the output cleaner + log_write "${INFO} Status: ${local_status//$'\n'/'\n '}" + local local_diff + local_diff=$(git diff) + if [[ ${local_diff} ]]; then + log_write "${INFO} Diff: ${local_diff//$'\n'/'\n '}" + fi fi # If git status failed, else @@ -269,7 +269,6 @@ check_ftl_version() { FTL_BRANCH=$(pihole-FTL branch) FTL_COMMIT=$(pihole-FTL --hash) - log_write "${TICK} Version: ${FTL_VERSION}" # If they use the master branch, they are on the stable codebase @@ -305,7 +304,10 @@ os_check() { detected_os=$(grep "\bID\b" /etc/os-release | cut -d '=' -f2 | tr -d '"') detected_version=$(grep VERSION_ID /etc/os-release | cut -d '=' -f2 | tr -d '"') - cmdResult="$(dig -4 +short -t txt "${remote_os_domain}" @ns1.pi-hole.net 2>&1; echo $?)" + cmdResult="$( + dig -4 +short -t txt "${remote_os_domain}" @ns1.pi-hole.net 2>&1 + echo $? + )" #Get the return code of the previous command (last line) digReturnCode="${cmdResult##*$'\n'}" @@ -319,7 +321,10 @@ os_check() { log_write "${CROSS} dig response: ${response}" log_write "${INFO} Retrying via IPv6" - cmdResult="$(dig -6 +short -t txt "${remote_os_domain}" @ns1.pi-hole.net 2>&1; echo $?)" + cmdResult="$( + dig -6 +short -t txt "${remote_os_domain}" @ns1.pi-hole.net 2>&1 + echo $? + )" #Get the return code of the previous command (last line) digReturnCode="${cmdResult##*$'\n'}" @@ -333,16 +338,14 @@ os_check() { log_write "${CROSS} Error: ${COL_RED}dig command failed - Unable to check OS${COL_NC}" else IFS=" " read -r -a supportedOS < <(echo "${response}" | tr -d '"') - for distro_and_versions in "${supportedOS[@]}" - do + for distro_and_versions in "${supportedOS[@]}"; do distro_part="${distro_and_versions%%=*}" versions_part="${distro_and_versions##*=}" if [[ "${detected_os^^}" =~ ${distro_part^^} ]]; then valid_os=true IFS="," read -r -a supportedVer <<<"${versions_part}" - for version in "${supportedVer[@]}" - do + for version in "${supportedVer[@]}"; do if [[ "${detected_version}" =~ $version ]]; then valid_version=true break @@ -388,7 +391,7 @@ diagnose_operating_system() { [ -n "${DOCKER_VERSION}" ] && log_write "${INFO} Pi-hole Docker Container: ${DOCKER_VERSION}" # If there is a /etc/*release file, it's probably a supported operating system, so we can - if ls /etc/*release 1> /dev/null 2>&1; then + if ls /etc/*release 1>/dev/null 2>&1; then # display the attributes to the user from the function made earlier os_check else @@ -405,25 +408,25 @@ check_selinux() { # If a SELinux configuration file was found, check the default SELinux mode. DEFAULT_SELINUX=$(awk -F= '/^SELINUX=/ {print $2}' /etc/selinux/config) case "${DEFAULT_SELINUX,,}" in - enforcing) - log_write "${CROSS} ${COL_RED}Default SELinux: $DEFAULT_SELINUX${COL_NC}" - ;; - *) # 'permissive' and 'disabled' - log_write "${TICK} ${COL_GREEN}Default SELinux: $DEFAULT_SELINUX${COL_NC}"; - ;; + enforcing) + log_write "${CROSS} ${COL_RED}Default SELinux: $DEFAULT_SELINUX${COL_NC}" + ;; + *) # 'permissive' and 'disabled' + log_write "${TICK} ${COL_GREEN}Default SELinux: $DEFAULT_SELINUX${COL_NC}" + ;; esac # Check the current state of SELinux CURRENT_SELINUX=$(getenforce) case "${CURRENT_SELINUX,,}" in - enforcing) - log_write "${CROSS} ${COL_RED}Current SELinux: $CURRENT_SELINUX${COL_NC}" - ;; - *) # 'permissive' and 'disabled' - log_write "${TICK} ${COL_GREEN}Current SELinux: $CURRENT_SELINUX${COL_NC}"; - ;; + enforcing) + log_write "${CROSS} ${COL_RED}Current SELinux: $CURRENT_SELINUX${COL_NC}" + ;; + *) # 'permissive' and 'disabled' + log_write "${TICK} ${COL_GREEN}Current SELinux: $CURRENT_SELINUX${COL_NC}" + ;; esac else - log_write "${INFO} ${COL_GREEN}SELinux not detected${COL_NC}"; + log_write "${INFO} ${COL_GREEN}SELinux not detected${COL_NC}" fi } @@ -432,11 +435,11 @@ check_firewalld() { # FirewallD is not configured by the installer and is the responsibility of the user echo_current_diagnostic "FirewallD" # Check if FirewallD service is enabled - if command -v systemctl &> /dev/null; then + if command -v systemctl &>/dev/null; then # get its status via systemctl local firewalld_status firewalld_status=$(systemctl is-active firewalld) - log_write "${INFO} ${COL_GREEN}Firewalld service ${firewalld_status}${COL_NC}"; + log_write "${INFO} ${COL_GREEN}Firewalld service ${firewalld_status}${COL_NC}" if [ "${firewalld_status}" == "active" ]; then # test common required service ports local firewalld_enabled_services @@ -444,7 +447,7 @@ check_firewalld() { local firewalld_expected_services=("http" "dns" "dhcp" "dhcpv6") for i in "${firewalld_expected_services[@]}"; do if [[ "${firewalld_enabled_services}" =~ ${i} ]]; then - log_write "${TICK} ${COL_GREEN} Allow Service: ${i}${COL_NC}"; + log_write "${TICK} ${COL_GREEN} Allow Service: ${i}${COL_NC}" else log_write "${CROSS} ${COL_RED} Allow Service: ${i}${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS_FIREWALLD})" fi @@ -453,12 +456,12 @@ check_firewalld() { local firewalld_zones firewalld_zones=$(firewall-cmd --get-zones) if [[ "${firewalld_zones}" =~ "ftl" ]]; then - log_write "${TICK} ${COL_GREEN}FTL Custom Zone Detected${COL_NC}"; + log_write "${TICK} ${COL_GREEN}FTL Custom Zone Detected${COL_NC}" # check FTL custom zone interface: lo local firewalld_ftl_zone_interfaces firewalld_ftl_zone_interfaces=$(firewall-cmd --zone=ftl --list-interfaces) if [[ "${firewalld_ftl_zone_interfaces}" =~ "lo" ]]; then - log_write "${TICK} ${COL_GREEN} Local Interface Detected${COL_NC}"; + log_write "${TICK} ${COL_GREEN} Local Interface Detected${COL_NC}" else log_write "${CROSS} ${COL_RED} Local Interface Not Detected${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS_FIREWALLD})" fi @@ -466,7 +469,7 @@ check_firewalld() { local firewalld_ftl_zone_ports firewalld_ftl_zone_ports=$(firewall-cmd --zone=ftl --list-ports) if [[ "${firewalld_ftl_zone_ports}" =~ "4711/tcp" ]]; then - log_write "${TICK} ${COL_GREEN} FTL Port 4711/tcp Detected${COL_NC}"; + log_write "${TICK} ${COL_GREEN} FTL Port 4711/tcp Detected${COL_NC}" else log_write "${CROSS} ${COL_RED} FTL Port 4711/tcp Not Detected${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS_FIREWALLD})" fi @@ -475,7 +478,7 @@ check_firewalld() { fi fi else - log_write "${TICK} ${COL_GREEN}Firewalld service not detected${COL_NC}"; + log_write "${TICK} ${COL_GREEN}Firewalld service not detected${COL_NC}" fi } @@ -534,9 +537,9 @@ disk_usage() { # only show those lines not containing a sensitive phrase for line in "${file_system[@]}"; do - if [[ ! $line =~ $hide ]]; then - log_write " ${line}" - fi + if [[ ! $line =~ $hide ]]; then + log_write " ${line}" + fi done } @@ -574,7 +577,7 @@ ping_gateway() { log_write "${INFO} Default IPv${protocol} gateway(s):" while IFS= read -r gateway; do - log_write " $(cut -d ' ' -f 3 <<< "${gateway}")%$(cut -d ' ' -f 5 <<< "${gateway}")" + log_write " $(cut -d ' ' -f 3 <<<"${gateway}")%$(cut -d ' ' -f 5 <<<"${gateway}")" done < <(ip -"${protocol}" route | grep default) gateway_addr=$(ip -"${protocol}" route | grep default | cut -d ' ' -f 3 | head -n 1) @@ -652,8 +655,8 @@ check_required_ports() { ports_in_use=() # Sort the addresses and remove duplicates while IFS= read -r line; do - ports_in_use+=( "$line" ) - done < <( ss --listening --numeric --tcp --udp --processes --no-header ) + ports_in_use+=("$line") + done < <(ss --listening --numeric --tcp --udp --processes --no-header) local ports_configured # Get all configured ports @@ -676,10 +679,10 @@ check_required_ports() { # Check if the right services are using the right ports if [[ ${ports_configured[*]} =~ $(echo "${port_number}" | rev | cut -d: -f1 | rev) ]]; then - compare_port_to_service_assigned "${ftl}" "${service_name}" "${protocol_type}:${port_number}" + compare_port_to_service_assigned "${ftl}" "${service_name}" "${protocol_type}:${port_number}" else # If it's not a default port that Pi-hole needs, just print it out for the user to see - log_write " ${protocol_type}:${port_number} is in use by ${service_name:=}"; + log_write " ${protocol_type}:${port_number} is in use by ${service_name:=}" fi done } @@ -775,7 +778,7 @@ dig_at() { # Removes everything after the interface name interfaces="$(ip link show | sed "/ master /d;/UP/!d;s/^[0-9]*: //g;s/@.*//g;s/: <.*//g;")" - while IFS= read -r iface ; do + while IFS= read -r iface; do # Get addresses of current interface # sed logic breakdown: # /inet(|6) /!d; @@ -786,13 +789,13 @@ dig_at() { # Removes CIDR and everything thereafter (e.g., scope properties) addresses="$(ip address show dev "${iface}" | sed "/${sed_selector} /!d;s/^.*${sed_selector} //g;s/\/.*$//g;")" if [ -n "${addresses}" ]; then - while IFS= read -r local_address ; do + while IFS= read -r local_address; do # If ${local_address} is an IPv6 link-local address, append the interface name to it if [[ "${local_address}" =~ ^fe80 ]]; then local_address="${local_address}%${iface}" fi - # Check if Pi-hole can use itself to block a domain + # Check if Pi-hole can use itself to block a domain if local_dig="$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @"${local_address}" "${record_type}")"; then # If it can, show success if [[ "${local_dig}" == *"status: NOERROR"* ]]; then @@ -809,11 +812,11 @@ dig_at() { # Otherwise, show a failure log_write "${CROSS} ${COL_RED}Failed to resolve${COL_NC} ${random_url} on ${COL_RED}${iface}${COL_NC} (${COL_RED}${local_address}${COL_NC})" fi - done <<< "${addresses}" + done <<<"${addresses}" else - log_write "${TICK} No IPv${protocol} address available on ${COL_CYAN}${iface}${COL_NC}" + log_write "${TICK} No IPv${protocol} address available on ${COL_CYAN}${iface}${COL_NC}" fi - done <<< "${interfaces}" + done <<<"${interfaces}" # Finally, we need to make sure legitimate queries can out to the Internet using an external, public DNS server # We are using the static remote_url here instead of a random one because we know it works with IPv4 and IPv6 @@ -826,7 +829,7 @@ dig_at() { fi } -process_status(){ +process_status() { # Check to make sure Pi-hole's services are running and active echo_current_diagnostic "Pi-hole processes" @@ -838,7 +841,7 @@ process_status(){ local status_of_process # If systemd - if command -v systemctl &> /dev/null; then + if command -v systemctl &>/dev/null; then # get its status via systemctl status_of_process=$(systemctl is-active "${i}") else @@ -848,8 +851,8 @@ process_status(){ if [ -n "${DOCKER_VERSION}" ]; then : else - # non-Docker system - if service "${i}" status | grep -E 'is\srunning' &> /dev/null; then + # non-Docker system + if service "${i}" status | grep -E 'is\srunning' &>/dev/null; then status_of_process="active" else status_of_process="inactive" @@ -871,17 +874,17 @@ process_status(){ done } -ftl_full_status(){ +ftl_full_status() { # if using systemd print the full status of pihole-FTL echo_current_diagnostic "Pi-hole-FTL full status" local FTL_status - if command -v systemctl &> /dev/null; then - FTL_status=$(systemctl status --full --no-pager pihole-FTL.service) - log_write " ${FTL_status}" + if command -v systemctl &>/dev/null; then + FTL_status=$(systemctl status --full --no-pager pihole-FTL.service) + log_write " ${FTL_status}" elif [ -n "${DOCKER_VERSION}" ]; then - log_write "${INFO} systemctl/service not installed inside docker container ${COL_YELLOW}(skipped)${COL_NC}" + log_write "${INFO} systemctl/service not installed inside docker container ${COL_YELLOW}(skipped)${COL_NC}" else - log_write "${INFO} systemctl: command not found" + log_write "${INFO} systemctl: command not found" fi } @@ -898,7 +901,7 @@ make_array_from_file() { : else # Otherwise, read the file line by line - while IFS= read -r line;do + while IFS= read -r line; do # Otherwise, strip out comments and blank lines new_line=$(echo "${line}" | sed -e 's/^\s*#.*$//' -e '/^$/d') # If the line still has content (a non-zero value) @@ -913,7 +916,7 @@ make_array_from_file() { log_write " ${new_line}" fi # Increment the iterator +1 - i=$((i+1)) + i=$((i + 1)) # but if the limit of lines we want to see is exceeded if [[ -z ${limit} ]]; then # do nothing @@ -921,7 +924,7 @@ make_array_from_file() { elif [[ $i -eq ${limit} ]]; then break fi - done < "${filename}" + done <"${filename}" fi } @@ -936,7 +939,7 @@ parse_file() { #shellcheck disable=SC2016 IFS=$'\r\n' command eval 'file_info=( $(cat "${filename}") )' else - read -r -a file_info <<< "$filename" + read -r -a file_info <<<"$filename" fi # Set a named variable for better readability local file_lines @@ -944,7 +947,7 @@ parse_file() { for file_lines in "${file_info[@]}"; do if [[ -n "${file_lines}" ]]; then # skip empty and comment lines line - [[ "${file_lines}" =~ ^[[:space:]]*\#.*$ || ! "${file_lines}" ]] && continue + [[ "${file_lines}" =~ ^[[:space:]]*\#.*$ || ! "${file_lines}" ]] && continue # remove the password hash from the output (*"pwhash = "*) [[ "${file_lines}" == *"pwhash ="* ]] && file_lines=$(echo "${file_lines}" | sed -e 's/\(pwhash = \).*/\1/') # otherwise, display the lines of the file @@ -972,7 +975,7 @@ dir_check() { # For each file in the directory, for filename in ${directory}; do # check if exists first; if it does, - if ls "${filename}" 1> /dev/null 2>&1; then + if ls "${filename}" 1>/dev/null 2>&1; then # do nothing true return @@ -1002,10 +1005,10 @@ list_files_in_dir() { if [[ -d "${dir_to_parse}/${each_file}" ]]; then # If it's a directory, do nothing : - elif [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_DEBUG_LOG}" ]] || \ - [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_RAW_BLOCKLIST_FILES}" ]] || \ - [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_INSTALL_LOG_FILE}" ]] || \ - [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_LOG}" ]] || \ + elif [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_DEBUG_LOG}" ]] || + [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_RAW_BLOCKLIST_FILES}" ]] || + [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_INSTALL_LOG_FILE}" ]] || + [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_LOG}" ]] || [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_LOG_GZIPS}" ]]; then : elif [[ "${dir_to_parse}" == "${DNSMASQ_D_DIRECTORY}" ]]; then @@ -1020,14 +1023,16 @@ list_files_in_dir() { log_write "\\n${COL_GREEN}$(ls -lhd "${dir_to_parse}"/"${each_file}")${COL_NC}" # Check if the file we want to view has a limit (because sometimes we just need a little bit of info from the file, not the entire thing) case "${dir_to_parse}/${each_file}" in - # If it's Web server log, give the first and last 25 lines - "${PIHOLE_WEBSERVER_LOG}") head_tail_log "${dir_to_parse}/${each_file}" 25 - ;; - # Same for the FTL log - "${PIHOLE_FTL_LOG}") head_tail_log "${dir_to_parse}/${each_file}" 35 - ;; - # parse the file into an array in case we ever need to analyze it line-by-line - *) make_array_from_file "${dir_to_parse}/${each_file}"; + # If it's Web server log, give the first and last 25 lines + "${PIHOLE_WEBSERVER_LOG}") + head_tail_log "${dir_to_parse}/${each_file}" 25 + ;; + # Same for the FTL log + "${PIHOLE_FTL_LOG}") + head_tail_log "${dir_to_parse}/${each_file}" 35 + ;; + # parse the file into an array in case we ever need to analyze it line-by-line + *) make_array_from_file "${dir_to_parse}/${each_file}" ;; esac else # Otherwise, do nothing since it's not a file needed for Pi-hole so we don't care about it @@ -1096,12 +1101,12 @@ show_db_entries() { OLD_IFS="$IFS" IFS=$'\r\n' local entries=() - mapfile -t entries < <(\ + mapfile -t entries < <( pihole-FTL sqlite3 -ni "${PIHOLE_GRAVITY_DB_FILE}" \ -cmd ".headers on" \ -cmd ".mode column" \ -cmd ".width ${widths}" \ - "${query}"\ + "${query}" ) for line in "${entries[@]}"; do @@ -1121,12 +1126,12 @@ show_FTL_db_entries() { OLD_IFS="$IFS" IFS=$'\r\n' local entries=() - mapfile -t entries < <(\ + mapfile -t entries < <( pihole-FTL sqlite3 -ni "${PIHOLE_FTL_DB_FILE}" \ -cmd ".headers on" \ -cmd ".mode column" \ -cmd ".width ${widths}" \ - "${query}"\ + "${query}" ) for line in "${entries[@]}"; do @@ -1142,7 +1147,10 @@ check_dhcp_servers() { OLD_IFS="$IFS" IFS=$'\n' local entries=() - mapfile -t entries < <(pihole-FTL dhcp-discover & spinner) + mapfile -t entries < <( + pihole-FTL dhcp-discover & + spinner + ) for line in "${entries[@]}"; do log_write " ${line}" @@ -1216,39 +1224,44 @@ analyze_ftl_db() { fi } -database_integrity_check(){ +database_integrity_check() { local result local database="${1}" log_write "${INFO} Checking integrity of ${database} ... (this can take several minutes)" - result="$(pihole-FTL sqlite3 -ni "${database}" "PRAGMA integrity_check" 2>&1 & spinner)" + result="$( + pihole-FTL sqlite3 -ni "${database}" "PRAGMA integrity_check" 2>&1 & + spinner + )" if [[ ${result} = "ok" ]]; then - log_write "${TICK} Integrity of ${database} intact" + log_write "${TICK} Integrity of ${database} intact" - - log_write "${INFO} Checking foreign key constraints of ${database} ... (this can take several minutes)" - unset result - result="$(pihole-FTL sqlite3 -ni "${database}" -cmd ".headers on" -cmd ".mode column" "PRAGMA foreign_key_check" 2>&1 & spinner)" - if [[ -z ${result} ]]; then - log_write "${TICK} No foreign key errors in ${database}" - else - log_write "${CROSS} ${COL_RED}Foreign key errors in ${database} found.${COL_NC}" - while IFS= read -r line ; do - log_write " $line" - done <<< "$result" - fi + log_write "${INFO} Checking foreign key constraints of ${database} ... (this can take several minutes)" + unset result + result="$( + pihole-FTL sqlite3 -ni "${database}" -cmd ".headers on" -cmd ".mode column" "PRAGMA foreign_key_check" 2>&1 & + spinner + )" + if [[ -z ${result} ]]; then + log_write "${TICK} No foreign key errors in ${database}" + else + log_write "${CROSS} ${COL_RED}Foreign key errors in ${database} found.${COL_NC}" + while IFS= read -r line; do + log_write " $line" + done <<<"$result" + fi else - log_write "${CROSS} ${COL_RED}Integrity errors in ${database} found.\n${COL_NC}" - while IFS= read -r line ; do - log_write " $line" - done <<< "$result" + log_write "${CROSS} ${COL_RED}Integrity errors in ${database} found.\n${COL_NC}" + while IFS= read -r line; do + log_write " $line" + done <<<"$result" fi } # Show a text spinner during a long process run -spinner(){ +spinner() { # Show the spinner only if there is a tty if tty -s; then # PID of the most recent background process @@ -1262,18 +1275,18 @@ spinner(){ _start=$(date +%s) # Hide the cursor - tput civis > /dev/tty + tput civis >/dev/tty # ensures cursor is visible again, in case of premature exit trap 'tput cnorm > /dev/tty' EXIT while [ -d /proc/$_PID ]; do - _elapsed=$(( $(date +%s) - _start )) + _elapsed=$(($(date +%s) - _start)) # use hours only if needed if [ "$_elapsed" -lt 3600 ]; then - printf "\r${_spin:_i++%${#_spin}:1} %02d:%02d" $((_elapsed/60)) $((_elapsed%60)) >"$(tty)" + printf "\r${_spin:_i++%${#_spin}:1} %02d:%02d" $((_elapsed / 60)) $((_elapsed % 60)) >"$(tty)" else - printf "\r${_spin:_i++%${#_spin}:1} %02d:%02d:%02d" $((_elapsed/3600)) $(((_elapsed/60)%60)) $((_elapsed%60)) >"$(tty)" + printf "\r${_spin:_i++%${#_spin}:1} %02d:%02d:%02d" $((_elapsed / 3600)) $(((_elapsed / 60) % 60)) $((_elapsed % 60)) >"$(tty)" fi sleep 0.25 done @@ -1282,25 +1295,25 @@ spinner(){ printf "\r" >"$(tty)" # Restore cursor visibility - tput cnorm > /dev/tty + tput cnorm >/dev/tty fi } analyze_pihole_log() { - echo_current_diagnostic "Pi-hole log" - local pihole_log_permissions - local queryLogging + echo_current_diagnostic "Pi-hole log" + local pihole_log_permissions + local queryLogging - queryLogging="$(get_ftl_conf_value "dns.queryLogging")" - if [[ "${queryLogging}" == "false" ]]; then - # Inform user that logging has been disabled and pihole.log does not contain queries - log_write "${INFO} Query logging is disabled" - log_write "" - fi + queryLogging="$(get_ftl_conf_value "dns.queryLogging")" + if [[ "${queryLogging}" == "false" ]]; then + # Inform user that logging has been disabled and pihole.log does not contain queries + log_write "${INFO} Query logging is disabled" + log_write "" + fi - pihole_log_permissions=$(ls -lhd "${PIHOLE_LOG}") - log_write "${COL_GREEN}${pihole_log_permissions}${COL_NC}" - head_tail_log "${PIHOLE_LOG}" 20 + pihole_log_permissions=$(ls -lhd "${PIHOLE_LOG}") + log_write "${COL_GREEN}${pihole_log_permissions}${COL_NC}" + head_tail_log "${PIHOLE_LOG}" 20 } curl_to_tricorder() { @@ -1318,7 +1331,6 @@ curl_to_tricorder() { fi } - upload_to_tricorder() { local username="pihole" # Set the permissions and owner @@ -1347,10 +1359,13 @@ upload_to_tricorder() { # Users can review the log file locally (or the output of the script since they are the same) and try to self-diagnose their problem read -r -p "[?] Would you like to upload the log? [y/N] " response case ${response} in - # If they say yes, run our function for uploading the log - [yY][eE][sS]|[yY]) curl_to_tricorder;; - # If they choose no, just exit out of the script - *) log_write " * Log will ${COL_GREEN}NOT${COL_NC} be uploaded to tricorder.\\n * A local copy of the debug log can be found at: ${COL_CYAN}${PIHOLE_DEBUG_LOG}${COL_NC}\\n";exit; + # If they say yes, run our function for uploading the log + [yY][eE][sS] | [yY]) curl_to_tricorder ;; + # If they choose no, just exit out of the script + *) + log_write " * Log will ${COL_GREEN}NOT${COL_NC} be uploaded to tricorder.\\n * A local copy of the debug log can be found at: ${COL_CYAN}${PIHOLE_DEBUG_LOG}${COL_NC}\\n" + exit + ;; esac fi # Check if tricorder.pi-hole.net is reachable and provide token diff --git a/advanced/Scripts/piholeLogFlush.sh b/advanced/Scripts/piholeLogFlush.sh index 34d96318..0a2892df 100755 --- a/advanced/Scripts/piholeLogFlush.sh +++ b/advanced/Scripts/piholeLogFlush.sh @@ -55,7 +55,7 @@ if [[ "$*" == *"once"* ]]; then echo -ne " ${INFO} Rotating ${LOGFILE} ..." fi cp -p "${LOGFILE}" "${LOGFILE}.1" - echo " " > "${LOGFILE}" + echo " " >"${LOGFILE}" chmod 640 "${LOGFILE}" if [[ "$*" != *"quiet"* ]]; then echo -e "${OVER} ${TICK} Rotated ${LOGFILE} ..." @@ -66,7 +66,7 @@ if [[ "$*" == *"once"* ]]; then echo -ne " ${INFO} Rotating ${FTLFILE} ..." fi cp -p "${FTLFILE}" "${FTLFILE}.1" - echo " " > "${FTLFILE}" + echo " " >"${FTLFILE}" chmod 640 "${FTLFILE}" if [[ "$*" != *"quiet"* ]]; then echo -e "${OVER} ${TICK} Rotated ${FTLFILE} ..." @@ -79,10 +79,10 @@ else if [[ "$*" != *"quiet"* ]]; then echo -ne " ${INFO} Flushing ${LOGFILE} ..." fi - echo " " > "${LOGFILE}" + echo " " >"${LOGFILE}" chmod 640 "${LOGFILE}" if [ -f "${LOGFILE}.1" ]; then - echo " " > "${LOGFILE}.1" + echo " " >"${LOGFILE}.1" chmod 640 "${LOGFILE}.1" fi if [[ "$*" != *"quiet"* ]]; then @@ -93,10 +93,10 @@ else if [[ "$*" != *"quiet"* ]]; then echo -ne " ${INFO} Flushing ${FTLFILE} ..." fi - echo " " > "${FTLFILE}" + echo " " >"${FTLFILE}" chmod 640 "${FTLFILE}" if [ -f "${FTLFILE}.1" ]; then - echo " " > "${FTLFILE}.1" + echo " " >"${FTLFILE}.1" chmod 640 "${FTLFILE}.1" fi if [[ "$*" != *"quiet"* ]]; then @@ -119,4 +119,3 @@ else echo -e "${OVER} ${TICK} Deleted ${deleted} queries from long-term query database" fi fi - diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh index 6c6167c0..92c722eb 100755 --- a/advanced/Scripts/update.sh +++ b/advanced/Scripts/update.sh @@ -41,7 +41,7 @@ GitCheckUpdateAvail() { cd "${directory}" || exit 1 # Fetch latest changes in this repo - if ! git fetch --quiet origin ; then + if ! git fetch --quiet origin; then echo -e "\\n ${COL_LIGHT_RED}Error: Unable to update local repository. Contact Pi-hole Support.${COL_NC}" exit 1 fi @@ -69,7 +69,6 @@ GitCheckUpdateAvail() { REMOTE="$(git rev-parse "@{upstream}")" fi - if [[ "${#LOCAL}" == 0 ]]; then echo -e "\\n ${COL_LIGHT_RED}Error: Local revision could not be obtained, please contact Pi-hole Support" echo -e " Additional debugging output:${COL_NC}" @@ -116,15 +115,15 @@ main() { install_dependent_packages # This is unlikely - if ! is_repo "${PI_HOLE_FILES_DIR}" ; then + if ! is_repo "${PI_HOLE_FILES_DIR}"; then echo -e "\\n ${COL_LIGHT_RED}Error: Core Pi-hole repo is missing from system!" echo -e " Please re-run install script from https://pi-hole.net${COL_NC}" - exit 1; + exit 1 fi echo -e " ${INFO} Checking for updates..." - if GitCheckUpdateAvail "${PI_HOLE_FILES_DIR}" ; then + if GitCheckUpdateAvail "${PI_HOLE_FILES_DIR}"; then core_update=true echo -e " ${INFO} Pi-hole Core:\\t${COL_YELLOW}update available${COL_NC}" else @@ -132,13 +131,13 @@ main() { echo -e " ${INFO} Pi-hole Core:\\t${COL_LIGHT_GREEN}up to date${COL_NC}" fi - if ! is_repo "${ADMIN_INTERFACE_DIR}" ; then + if ! is_repo "${ADMIN_INTERFACE_DIR}"; then echo -e "\\n ${COL_LIGHT_RED}Error: Web Admin repo is missing from system!" echo -e " Please re-run install script from https://pi-hole.net${COL_NC}" - exit 1; + exit 1 fi - if GitCheckUpdateAvail "${ADMIN_INTERFACE_DIR}" ; then + if GitCheckUpdateAvail "${ADMIN_INTERFACE_DIR}"; then web_update=true echo -e " ${INFO} Web Interface:\\t${COL_YELLOW}update available${COL_NC}" else @@ -156,19 +155,20 @@ main() { echo -e " ${INFO} FTL:\\t\\t${COL_YELLOW}update available${COL_NC}" else case $? in - 1) - echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_GREEN}up to date${COL_NC}" - ;; - 2) - echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_RED}Branch is not available.${COL_NC}\\n\\t\\t\\tUse ${COL_LIGHT_GREEN}pihole checkout ftl [branchname]${COL_NC} to switch to a valid branch." - ;; - 3) - echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_RED}Something has gone wrong, cannot reach download server${COL_NC}" - exit 1 - ;; - *) - echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_RED}Something has gone wrong, contact support${COL_NC}" - exit 1 + 1) + echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_GREEN}up to date${COL_NC}" + ;; + 2) + echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_RED}Branch is not available.${COL_NC}\\n\\t\\t\\tUse ${COL_LIGHT_GREEN}pihole checkout ftl [branchname]${COL_NC} to switch to a valid branch." + ;; + 3) + echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_RED}Something has gone wrong, cannot reach download server${COL_NC}" + exit 1 + ;; + *) + echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_RED}Something has gone wrong, contact support${COL_NC}" + exit 1 + ;; esac FTL_update=false fi @@ -218,7 +218,7 @@ main() { fi if [[ "${FTL_update}" == true || "${core_update}" == true ]]; then - ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --repair --unattended || \ + ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --repair --unattended || echo -e "${basicError}" && exit 1 fi @@ -230,7 +230,7 @@ main() { # if there was only a web update, show the new versions # (on core and FTL updates, this is done as part of the installer run) - if [[ "${web_update}" == true && "${FTL_update}" == false && "${core_update}" == false ]]; then + if [[ "${web_update}" == true && "${FTL_update}" == false && "${core_update}" == false ]]; then "${PI_HOLE_BIN_DIR}"/pihole version fi diff --git a/advanced/Scripts/utils.sh b/advanced/Scripts/utils.sh index 63d51f87..0d39f8ca 100755 --- a/advanced/Scripts/utils.sh +++ b/advanced/Scripts/utils.sh @@ -27,20 +27,20 @@ # addOrEditKeyValPair "/etc/pihole/setupVars.conf" "BLOCKING_ENABLED" "true" ####################### addOrEditKeyValPair() { - local file="${1}" - local key="${2}" - local value="${3}" + local file="${1}" + local key="${2}" + local value="${3}" - # touch file to prevent grep error if file does not exist yet - touch "${file}" + # touch file to prevent grep error if file does not exist yet + touch "${file}" - if grep -q "^${key}=" "${file}"; then - # Key already exists in file, modify the value - sed -i "/^${key}=/c\\${key}=${value}" "${file}" - else - # Key does not already exist, add it and it's value - echo "${key}=${value}" >> "${file}" - fi + if grep -q "^${key}=" "${file}"; then + # Key already exists in file, modify the value + sed -i "/^${key}=/c\\${key}=${value}" "${file}" + else + # Key does not already exist, add it and it's value + echo "${key}=${value}" >>"${file}" + fi } ####################### @@ -58,13 +58,13 @@ getFTLPID() { FTL_PID="$(cat "${FTL_PID_FILE}")" # Exploit prevention: unset the variable if there is malicious content # Verify that the value read from the file is numeric - expr "${FTL_PID}" : "[^[:digit:]]" > /dev/null && unset FTL_PID + expr "${FTL_PID}" : "[^[:digit:]]" >/dev/null && unset FTL_PID fi # If FTL is not running, or the PID file contains malicious stuff, substitute # negative PID to signal this FTL_PID=${FTL_PID:=-1} - echo "${FTL_PID}" + echo "${FTL_PID}" } ####################### @@ -73,8 +73,8 @@ getFTLPID() { # Takes one argument: key # Example getFTLConfigValue dns.piholePTR ####################### -getFTLConfigValue(){ - pihole-FTL --config -q "${1}" +getFTLConfigValue() { + pihole-FTL --config -q "${1}" } ####################### @@ -86,10 +86,10 @@ getFTLConfigValue(){ # Note, for complex values such as dns.upstreams, you should wrap the value in single quotes: # setFTLConfigValue dns.upstreams '[ "8.8.8.8" , "8.8.4.4" ]' ####################### -setFTLConfigValue(){ - pihole-FTL --config "${1}" "${2}" >/dev/null - if [[ $? -eq 5 ]]; then - echo -e " ${CROSS} ${1} set by environment variable. Please unset it to use this function" - exit 5 - fi +setFTLConfigValue() { + pihole-FTL --config "${1}" "${2}" >/dev/null + if [[ $? -eq 5 ]]; then + echo -e " ${CROSS} ${1} set by environment variable. Please unset it to use this function" + exit 5 + fi } diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index d18d4e88..db4641a1 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -219,19 +219,20 @@ is_command() { command -v "${check_command}" >/dev/null 2>&1 } -os_check_dig(){ +os_check_dig() { local protocol="$1" local domain="$2" local nameserver="$3" local response - response="$(dig -"${protocol}" +short -t txt "${domain}" "${nameserver}" 2>&1 - echo $? + response="$( + dig -"${protocol}" +short -t txt "${domain}" "${nameserver}" 2>&1 + echo $? )" echo "${response}" } -os_check_dig_response(){ +os_check_dig_response() { # Checks the reply from the dig command to determine if it's a valid response local digReply="$1" local response @@ -432,7 +433,7 @@ package_manager_detect() { fi } -build_dependency_package(){ +build_dependency_package() { # This function will build a package that contains all the dependencies needed for Pi-hole # remove any leftover build directory that may exist @@ -456,13 +457,13 @@ build_dependency_package(){ touch "${tempdir}"/DEBIAN/control # Write the control file - echo "${PIHOLE_META_PACKAGE_CONTROL_APT}" > "${tempdir}"/DEBIAN/control + echo "${PIHOLE_META_PACKAGE_CONTROL_APT}" >"${tempdir}"/DEBIAN/control # Build the package local str="Building dependency package pihole-meta.deb" printf " %b %s..." "${INFO}" "${str}" - if dpkg-deb --build --root-owner-group "${tempdir}" pihole-meta.deb &>/dev/null; then + if dpkg-deb --build --root-owner-group "${tempdir}" pihole-meta.deb &>/dev/null; then printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}" else printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}" @@ -471,7 +472,7 @@ build_dependency_package(){ fi # Move back into the directory the user started in - popd &> /dev/null || return 1 + popd &>/dev/null || return 1 elif is_command rpm; then # move into the tmp directory @@ -483,7 +484,7 @@ build_dependency_package(){ # Prepare directory structure and spec file mkdir -p "${tempdir}"/SPECS touch "${tempdir}"/SPECS/pihole-meta.spec - echo "${PIHOLE_META_PACKAGE_CONTROL_RPM}" > "${tempdir}"/SPECS/pihole-meta.spec + echo "${PIHOLE_META_PACKAGE_CONTROL_RPM}" >"${tempdir}"/SPECS/pihole-meta.spec # check if we need to install the build dependencies if ! is_command rpmbuild; then @@ -512,7 +513,7 @@ build_dependency_package(){ fi # Move back into the directory the user started in - popd &> /dev/null || return 1 + popd &>/dev/null || return 1 # If neither apt-get or yum/dnf package managers were found else @@ -539,9 +540,9 @@ is_repo() { pushd "${directory}" &>/dev/null || return 1 # Use git to check if the directory is a repo # git -C is not used here to support git versions older than 1.8.4 - git status --short &> /dev/null || rc=$? + git status --short &>/dev/null || rc=$? # Move back into the directory the user started in - popd &> /dev/null || return 1 + popd &>/dev/null || return 1 else # Set a non-zero return code if directory does not exist rc=1 @@ -1430,7 +1431,7 @@ disable_resolved_stublistener() { # Note that this breaks dns functionality on host until FTL is up and running printf "%b %b Disabling systemd-resolved DNSStubListener\\n" "${OVER}" "${TICK}" mkdir -p /etc/systemd/resolved.conf.d - cat > /etc/systemd/resolved.conf.d/90-pi-hole-disable-stub-listener.conf << EOF + cat >/etc/systemd/resolved.conf.d/90-pi-hole-disable-stub-listener.conf <> ${target} +}" >>${target} printf "\\n\\t%b webserver.log added to logrotate file. \\n" "${INFO}" logfileUpdate=true @@ -2227,7 +2228,7 @@ disableLighttpd() { # The terminal is interactive dialog --no-shadow --keep-tite \ --title "Pi-hole v6.0 no longer uses lighttpd" \ - --yesno "\\n\\nPi-hole v6.0 has its own embedded web server so lighttpd is no longer needed *unless* you have custom configurations.\\n\\nIn this case, you can opt-out of disabling lighttpd and pihole-FTL will try to bind to an alternative port such as 8080.\\n\\nDo you want to disable lighttpd (recommended)?" "${r}" "${c}" && response=0 || response="$?" + --yesno "\\n\\nPi-hole v6.0 has its own embedded web server so lighttpd is no longer needed *unless* you have custom configurations.\\n\\nIn this case, you can opt-out of disabling lighttpd and pihole-FTL will try to bind to an alternative port such as 8080.\\n\\nDo you want to disable lighttpd (recommended)?" "${r}" "${c}" && response=0 || response="$?" else # The terminal is non-interactive, assume yes. Lighttpd will be stopped # but keeps being installed and can easily be re-enabled by the user @@ -2419,7 +2420,6 @@ main() { # Download or reset the appropriate git repos depending on the 'repair' flag clone_or_reset_repos - # Create the pihole user create_pihole_user @@ -2448,11 +2448,9 @@ main() { # Copy the temp log file into final log location for storage copy_to_install_log - # Migrate existing install to v6.0 migrate_dnsmasq_configs - # Check for and disable systemd-resolved-DNSStubListener before reloading resolved # DNSStubListener needs to remain in place for installer to download needed files, # so this change needs to be made after installation is complete, @@ -2514,7 +2512,7 @@ main() { if [[ "${useUpdateVars}" == false ]]; then # Get the Web interface port, return only the first port and strip all non-numeric characters - WEBPORT=$(getFTLConfigValue webserver.port|cut -d, -f1 | tr -cd '0-9') + WEBPORT=$(getFTLConfigValue webserver.port | cut -d, -f1 | tr -cd '0-9') # Display the completion dialog displayFinalMessage "${pw}" diff --git a/automated install/uninstall.sh b/automated install/uninstall.sh index 39c13037..ef51e8d7 100755 --- a/automated install/uninstall.sh +++ b/automated install/uninstall.sh @@ -13,8 +13,11 @@ source "/opt/pihole/COL_TABLE" while true; do read -rp " ${QST} Are you sure you would like to remove ${COL_WHITE}Pi-hole${COL_NC}? [y/N] " answer case ${answer} in - [Yy]* ) break;; - * ) echo -e "${OVER} ${COL_LIGHT_GREEN}Uninstall has been canceled${COL_NC}"; exit 0;; + [Yy]*) break ;; + *) + echo -e "${OVER} ${COL_LIGHT_GREEN}Uninstall has been canceled${COL_NC}" + exit 0 + ;; esac done @@ -42,26 +45,24 @@ source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" # package_manager_detect() sourced from basic-install.sh package_manager_detect - removeMetaPackage() { # Purge Pi-hole meta package echo "" - echo -ne " ${INFO} Removing Pi-hole meta package..."; - eval "${SUDO}" "${PKG_REMOVE}" "pihole-meta" &> /dev/null; - echo -e "${OVER} ${INFO} Removed Pi-hole meta package"; + echo -ne " ${INFO} Removing Pi-hole meta package..." + eval "${SUDO}" "${PKG_REMOVE}" "pihole-meta" &>/dev/null + echo -e "${OVER} ${INFO} Removed Pi-hole meta package" } removePiholeFiles() { # Only web directories/files that are created by Pi-hole should be removed echo -ne " ${INFO} Removing Web Interface..." - ${SUDO} rm -rf /var/www/html/admin &> /dev/null - + ${SUDO} rm -rf /var/www/html/admin &>/dev/null # If the web directory is empty after removing these files, then the parent html directory can be removed. if [ -d "/var/www/html" ]; then if [[ ! "$(ls -A /var/www/html)" ]]; then - ${SUDO} rm -rf /var/www/html &> /dev/null + ${SUDO} rm -rf /var/www/html &>/dev/null fi fi echo -e "${OVER} ${TICK} Removed Web Interface" @@ -78,30 +79,30 @@ removePiholeFiles() { fi # Attempt to preserve backwards compatibility with older versions - if [[ -f /etc/cron.d/pihole ]];then - ${SUDO} rm -f /etc/cron.d/pihole &> /dev/null + if [[ -f /etc/cron.d/pihole ]]; then + ${SUDO} rm -f /etc/cron.d/pihole &>/dev/null echo -e " ${TICK} Removed /etc/cron.d/pihole" fi - ${SUDO} rm -rf /var/log/*pihole* &> /dev/null - ${SUDO} rm -rf /var/log/pihole/*pihole* &> /dev/null - ${SUDO} rm -rf /etc/pihole/ &> /dev/null - ${SUDO} rm -rf /etc/.pihole/ &> /dev/null - ${SUDO} rm -rf /opt/pihole/ &> /dev/null - ${SUDO} rm -f /usr/local/bin/pihole &> /dev/null - ${SUDO} rm -f /etc/bash_completion.d/pihole &> /dev/null - ${SUDO} rm -f /etc/sudoers.d/pihole &> /dev/null + ${SUDO} rm -rf /var/log/*pihole* &>/dev/null + ${SUDO} rm -rf /var/log/pihole/*pihole* &>/dev/null + ${SUDO} rm -rf /etc/pihole/ &>/dev/null + ${SUDO} rm -rf /etc/.pihole/ &>/dev/null + ${SUDO} rm -rf /opt/pihole/ &>/dev/null + ${SUDO} rm -f /usr/local/bin/pihole &>/dev/null + ${SUDO} rm -f /etc/bash_completion.d/pihole &>/dev/null + ${SUDO} rm -f /etc/sudoers.d/pihole &>/dev/null echo -e " ${TICK} Removed config files" # Restore Resolved if [[ -e /etc/systemd/resolved.conf.orig ]] || [[ -e /etc/systemd/resolved.conf.d/90-pi-hole-disable-stub-listener.conf ]]; then - ${SUDO} cp -p /etc/systemd/resolved.conf.orig /etc/systemd/resolved.conf &> /dev/null || true + ${SUDO} cp -p /etc/systemd/resolved.conf.orig /etc/systemd/resolved.conf &>/dev/null || true ${SUDO} rm -f /etc/systemd/resolved.conf.d/90-pi-hole-disable-stub-listener.conf systemctl reload-or-restart systemd-resolved fi # Remove FTL - if command -v pihole-FTL &> /dev/null; then + if command -v pihole-FTL &>/dev/null; then echo -ne " ${INFO} Removing pihole-FTL..." if [[ -x "$(command -v systemctl)" ]]; then systemctl stop pihole-FTL @@ -112,12 +113,12 @@ removePiholeFiles() { if [[ -d '/etc/systemd/system/pihole-FTL.service.d' ]]; then read -rp " ${QST} FTL service override directory /etc/systemd/system/pihole-FTL.service.d detected. Do you wish to remove this from your system? [y/N] " answer case $answer in - [yY]*) - echo -ne " ${INFO} Removing /etc/systemd/system/pihole-FTL.service.d..." - ${SUDO} rm -R /etc/systemd/system/pihole-FTL.service.d - echo -e "${OVER} ${INFO} Removed /etc/systemd/system/pihole-FTL.service.d" + [yY]*) + echo -ne " ${INFO} Removing /etc/systemd/system/pihole-FTL.service.d..." + ${SUDO} rm -R /etc/systemd/system/pihole-FTL.service.d + echo -e "${OVER} ${INFO} Removed /etc/systemd/system/pihole-FTL.service.d" ;; - *) echo -e " ${INFO} Leaving /etc/systemd/system/pihole-FTL.service.d in place.";; + *) echo -e " ${INFO} Leaving /etc/systemd/system/pihole-FTL.service.d in place." ;; esac fi ${SUDO} rm -f /etc/init.d/pihole-FTL @@ -133,16 +134,16 @@ removePiholeFiles() { fi # If the pihole user exists, then remove - if id "pihole" &> /dev/null; then - if ${SUDO} userdel -r pihole 2> /dev/null; then + if id "pihole" &>/dev/null; then + if ${SUDO} userdel -r pihole 2>/dev/null; then echo -e " ${TICK} Removed 'pihole' user" else echo -e " ${CROSS} Unable to remove 'pihole' user" fi fi # If the pihole group exists, then remove - if getent group "pihole" &> /dev/null; then - if ${SUDO} groupdel pihole 2> /dev/null; then + if getent group "pihole" &>/dev/null; then + if ${SUDO} groupdel pihole 2>/dev/null; then echo -e " ${TICK} Removed 'pihole' group" else echo -e " ${CROSS} Unable to remove 'pihole' group"