From 25601b9fcc4a87220cbd641deaf2f079b71994ee Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Sat, 13 May 2017 17:49:58 -0700 Subject: [PATCH 1/7] Document `sed` substitution for user readability Comment the oneliner with explanations of what each step does. --- advanced/Scripts/list.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh index 52c4c569..05806e46 100755 --- a/advanced/Scripts/list.sh +++ b/advanced/Scripts/list.sh @@ -158,6 +158,10 @@ RemoveDomain() { # Remove it from the other one echo "::: Removing $1 from $list..." # Busybox sed compatible case-insensitive domain removal + # grep case insensitive domain from list, print line numbers + # split on ':' with awk and print the line number + # For conditions with more than one match, substitute newline with ',' + # sed substitute final trailing ',' with newline sed -i "$(grep -in "^${domain}$" ${list} | awk -F':' '{print $1}' | tr '\n' ',' | sed 's/,$/\n/')d" ${list} reload=true else From b721ed49abaa7cacb743de5547199b3beb11cee4 Mon Sep 17 00:00:00 2001 From: WaLLy3K Date: Sun, 14 May 2017 11:11:44 +1000 Subject: [PATCH 2/7] Update Help Output (#1467) * File consistency * Tabs to 2 spaces * Corrected indenting * Double braced conditionals * Quoted variables within conditionals * Standardise core help text * Added help text for disable command * Added help text for logging command * Clean up * Fixed certain new lines and spaces * Sync with development branch * Formatting consistency * Tabs to 2 spaces * Corrected indenting * Double braced conditionals * Quoted variables within conditionals * Fixed certain newlines and spaces * Admin help text * Added help text for interface command * Sync with development branch * Formatting consistency * Tabs to 2 spaces * Fixed some wording * Fixed certain spaces * Formatting consistency * Minor wording changes * Tabs to 2 spaces * Corrected indenting * Double braced conditionals * Quoted variables within conditionals * Fixed certain newlines and spaces * Blacklist help text * Formatting consistency * Tabs to 2 spaces * Corrected indenting * Cronometer help text * Formatting consistency * Fixed certain newlines and spaces * Corrected indenting * Checkout warning alteration * Add checkout help text * Corrected help output --- advanced/Scripts/chronometer.sh | 131 ++++++------ advanced/Scripts/list.sh | 313 ++++++++++++++--------------- advanced/Scripts/piholeCheckout.sh | 30 +-- advanced/Scripts/version.sh | 168 +++++++++------- advanced/Scripts/webpage.sh | 187 ++++++++--------- pihole | 250 ++++++++++++----------- 6 files changed, 547 insertions(+), 532 deletions(-) diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh index 67ff495b..b5d54e5f 100755 --- a/advanced/Scripts/chronometer.sh +++ b/advanced/Scripts/chronometer.sh @@ -8,101 +8,98 @@ # This file is copyright under the latest version of the EUPL. # Please see LICENSE file for your rights under this license. -#Functions############################################################################################################## +# Functions piLog="/var/log/pihole.log" gravity="/etc/pihole/gravity.list" . /etc/pihole/setupVars.conf function GetFTLData { - # Open connection to FTL - exec 3<>/dev/tcp/localhost/"$(cat /var/run/pihole-FTL.port)" + # Open connection to FTL + exec 3<>/dev/tcp/localhost/"$(cat /var/run/pihole-FTL.port)" - # Test if connection is open - if { >&3; } 2> /dev/null; then - # Send command to FTL - echo -e ">$1" >&3 + # Test if connection is open + if { >&3; } 2> /dev/null; then + # Send command to FTL + echo -e ">$1" >&3 - # Read input + # Read input + read -r -t 1 LINE <&3 + until [ ! $? ] || [[ "$LINE" == *"EOM"* ]]; do + echo "$LINE" >&1 read -r -t 1 LINE <&3 - until [ ! $? ] || [[ "$LINE" == *"EOM"* ]]; do - echo "$LINE" >&1 - read -r -t 1 LINE <&3 - done + done - # Close connection - exec 3>&- - exec 3<&- - fi + # Close connection + exec 3>&- + exec 3<&- + fi } outputJSON() { - get_summary_data - echo "{\"domains_being_blocked\":${domains_being_blocked_raw},\"dns_queries_today\":${dns_queries_today_raw},\"ads_blocked_today\":${ads_blocked_today_raw},\"ads_percentage_today\":${ads_percentage_today_raw}}" + get_summary_data + echo "{\"domains_being_blocked\":${domains_being_blocked_raw},\"dns_queries_today\":${dns_queries_today_raw},\"ads_blocked_today\":${ads_blocked_today_raw},\"ads_percentage_today\":${ads_percentage_today_raw}}" } get_summary_data() { - local summary=$(GetFTLData "stats") - domains_being_blocked_raw=$(grep "domains_being_blocked" <<< "${summary}" | grep -Eo "[0-9]+$") - domains_being_blocked=$(printf "%'.f" ${domains_being_blocked_raw}) - dns_queries_today_raw=$(grep "dns_queries_today" <<< "$summary" | grep -Eo "[0-9]+$") - dns_queries_today=$(printf "%'.f" ${dns_queries_today_raw}) - ads_blocked_today_raw=$(grep "ads_blocked_today" <<< "$summary" | grep -Eo "[0-9]+$") - ads_blocked_today=$(printf "%'.f" ${ads_blocked_today_raw}) - ads_percentage_today_raw=$(grep "ads_percentage_today" <<< "$summary" | grep -Eo "[0-9.]+$") - LC_NUMERIC=C ads_percentage_today=$(printf "%'.f" ${ads_percentage_today_raw}) + local summary=$(GetFTLData "stats") + domains_being_blocked_raw=$(grep "domains_being_blocked" <<< "${summary}" | grep -Eo "[0-9]+$") + domains_being_blocked=$(printf "%'.f" ${domains_being_blocked_raw}) + dns_queries_today_raw=$(grep "dns_queries_today" <<< "$summary" | grep -Eo "[0-9]+$") + dns_queries_today=$(printf "%'.f" ${dns_queries_today_raw}) + ads_blocked_today_raw=$(grep "ads_blocked_today" <<< "$summary" | grep -Eo "[0-9]+$") + ads_blocked_today=$(printf "%'.f" ${ads_blocked_today_raw}) + ads_percentage_today_raw=$(grep "ads_percentage_today" <<< "$summary" | grep -Eo "[0-9.]+$") + LC_NUMERIC=C ads_percentage_today=$(printf "%'.f" ${ads_percentage_today_raw}) } normalChrono() { - for (( ; ; )); do - get_summary_data - domain=$(GetFTLData recentBlocked) - clear - # Displays a colorful Pi-hole logo - echo " ___ _ _ _" - echo "| _ (_)___| |_ ___| |___" - echo "| _/ |___| ' \/ _ \ / -_)" - echo "|_| |_| |_||_\___/_\___|" - echo "" - echo " ${IPV4_ADDRESS}" - echo "" - uptime | cut -d' ' -f11- - #uptime -p #Doesn't work on all versions of uptime - uptime | awk -F'( |,|:)+' '{if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}' - echo "-------------------------------" - echo "Recently blocked:" - echo " $domain" + for (( ; ; )); do + get_summary_data + domain=$(GetFTLData recentBlocked) + clear + # Displays a colorful Pi-hole logo + echo " ___ _ _ _" + echo "| _ (_)___| |_ ___| |___" + echo "| _/ |___| ' \/ _ \ / -_)" + echo "|_| |_| |_||_\___/_\___|" + echo "" + echo " ${IPV4_ADDRESS}" + echo "" + uptime | cut -d' ' -f11- + #uptime -p # Doesn't work on all versions of uptime + uptime | awk -F'( |,|:)+' '{if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}' + echo "-------------------------------" + echo "Recently blocked:" + echo " $domain" - echo "Blocking: ${domains_being_blocked}" - echo "Queries: ${dns_queries_today}" - echo "Pi-holed: ${ads_blocked_today} (${ads_percentage_today}%)" + echo "Blocking: ${domains_being_blocked}" + echo "Queries: ${dns_queries_today}" + echo "Pi-holed: ${ads_blocked_today} (${ads_percentage_today}%)" - sleep 5 - done + sleep 5 + done } displayHelp() { - cat << EOM -::: Displays stats about your piHole! -::: -::: Usage: sudo pihole -c [optional:-j] -::: Note: If no option is passed, then stats are displayed on screen, updated every 5 seconds -::: -::: Options: -::: -j, --json output stats as JSON formatted string -::: -h, --help display this help text -EOM - exit 0 + echo "Usage: pihole -c [options] +Example: 'pihole -c -j' +Calculates stats and displays to an LCD + +Options: + -j, --json Output stats as JSON formatted string + -h, --help Display this help text" + exit 0 } if [[ $# = 0 ]]; then - normalChrono + normalChrono fi for var in "$@"; do - case "$var" in - "-j" | "--json" ) outputJSON;; - "-h" | "--help" ) displayHelp;; - * ) exit 1;; - esac + case "$var" in + "-j" | "--json" ) outputJSON;; + "-h" | "--help" ) displayHelp;; + * ) exit 1;; + esac done diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh index 537ebac3..14b18249 100755 --- a/advanced/Scripts/list.sh +++ b/advanced/Scripts/list.sh @@ -3,14 +3,12 @@ # (c) 2017 Pi-hole, LLC (https://pi-hole.net) # Network-wide ad blocking via your own hardware. # -# Whitelists and blacklists domains +# Whitelist and blacklist domains # # This file is copyright under the latest version of the EUPL. # Please see LICENSE file for your rights under this license. - - -#globals +# Globals basename=pihole piholeDir=/etc/${basename} whitelist=${piholeDir}/whitelist.txt @@ -27,122 +25,120 @@ listMain="" listAlt="" helpFunc() { + if [[ "${listMain}" == "${whitelist}" ]]; then + letter="w" + word="white" + else + letter="b" + word="black" + fi - if [[ ${listMain} == ${whitelist} ]]; then - letter="w" - word="white" - else - letter="b" - word="black" - fi + echo "Usage: pihole -${letter} [options] +Example: 'pihole -${letter} site.com', or 'pihole -${letter} site1.com site2.com' +${word^}list one or more domains - cat << EOM -::: Immediately ${word}lists one or more domains in the hosts file -::: -::: Usage: pihole -${letter} domain1 [domain2 ...] -::: -::: Options: -::: -d, --delmode Remove domains from the ${word}list -::: -nr, --noreload Update ${word}list without refreshing dnsmasq -::: -q, --quiet Output is less verbose -::: -h, --help Show this help dialog -::: -l, --list Display your ${word}listed domains -EOM -if [[ "${letter}" == "b" ]]; then - echo "::: -wild, --wildcard Add wildcard entry (only blacklist)" -fi - exit 0 +Options:" + + if [[ "${letter}" == "b" ]]; then + echo " -wild, --wildcard Add wildcard entry to blacklist" + fi + +echo " -d, --delmode Remove domain(s) from the ${word}list + -nr, --noreload Update ${word}list without refreshing dnsmasq + -q, --quiet Make output less verbose + -h, --help Show this help dialog + -l, --list Display all your ${word}listed domains" + +exit 0 } EscapeRegexp() { - # This way we may safely insert an arbitrary - # string in our regular expressions - # Also remove leading "." if present - echo $* | sed 's/^\.*//' | sed "s/[]\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g" + # This way we may safely insert an arbitrary + # string in our regular expressions + # Also remove leading "." if present + echo $* | sed 's/^\.*//' | sed "s/[]\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g" } -HandleOther(){ - # First, convert everything to lowercase - domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1") +HandleOther() { + # First, convert everything to lowercase + domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1") - #check validity of domain - validDomain=$(echo "${domain}" | perl -lne 'print if /(?!.*[^a-z0-9-\.].*)^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9-]+\.)*[a-z]{2,63}/') - if [ -z "${validDomain}" ]; then - echo "::: $1 is not a valid argument or domain name" - else - domList=("${domList[@]}" ${validDomain}) - fi + # Check validity of domain + validDomain=$(echo "${domain}" | perl -lne 'print if /(?!.*[^a-z0-9-\.].*)^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9-]+\.)*[a-z]{2,63}/') + if [[ -z "${validDomain}" ]]; then + echo "::: $1 is not a valid argument or domain name" + else + domList=("${domList[@]}" ${validDomain}) + fi } PoplistFile() { - #check whitelist file exists, and if not, create it - if [[ ! -f ${whitelist} ]]; then - touch ${whitelist} - fi - for dom in "${domList[@]}"; do - # Logic : If addmode then add to desired list and remove from the other; if delmode then remove from desired list but do not add to the other - if ${addmode}; then - AddDomain "${dom}" "${listMain}" - RemoveDomain "${dom}" "${listAlt}" - if [[ "${listMain}" == "${whitelist}" || "${listMain}" == "${blacklist}" ]]; then - RemoveDomain "${dom}" "${wildcardlist}" - fi - else - RemoveDomain "${dom}" "${listMain}" - fi - done + # Check whitelist file exists, and if not, create it + if [[ ! -f ${whitelist} ]]; then + touch ${whitelist} + fi + + for dom in "${domList[@]}"; do + # Logic: If addmode then add to desired list and remove from the other; if delmode then remove from desired list but do not add to the other + if ${addmode}; then + AddDomain "${dom}" "${listMain}" + RemoveDomain "${dom}" "${listAlt}" + if [[ "${listMain}" == "${whitelist}" || "${listMain}" == "${blacklist}" ]]; then + RemoveDomain "${dom}" "${wildcardlist}" + fi + else + RemoveDomain "${dom}" "${listMain}" + fi + done } AddDomain() { - list="$2" - domain=$(EscapeRegexp "$1") + list="$2" + domain=$(EscapeRegexp "$1") - if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then + if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then + bool=true + # Is the domain in the list we want to add it to? + grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false - bool=true - #Is the domain in the list we want to add it to? - grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false + if [[ "${bool}" == false ]]; then + # Domain not found in the whitelist file, add it! + if [[ "${verbose}" == true ]]; then + echo "::: Adding $1 to $list..." + fi + reload=true + # Add it to the list we want to add it to + echo "$1" >> "${list}" + else + if [[ "${verbose}" == true ]]; then + echo "::: ${1} already exists in ${list}, no need to add!" + fi + fi + elif [[ "${list}" == "${wildcardlist}" ]]; then + source "${piholeDir}/setupVars.conf" + # Remove the /* from the end of the IPv4addr. + IPV4_ADDRESS=${IPV4_ADDRESS%/*} + IPV6_ADDRESS=${IPV6_ADDRESS} - if [[ "${bool}" == false ]]; then - #domain not found in the whitelist file, add it! - if [[ "${verbose}" == true ]]; then - echo "::: Adding $1 to $list..." - fi - reload=true - # Add it to the list we want to add it to - echo "$1" >> "${list}" - else - if [[ "${verbose}" == true ]]; then - echo "::: ${1} already exists in ${list}, no need to add!" - fi - fi + bool=true + # Is the domain in the list? + grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false - elif [[ "${list}" == "${wildcardlist}" ]]; then - - source "${piholeDir}/setupVars.conf" - #Remove the /* from the end of the IPv4addr. - IPV4_ADDRESS=${IPV4_ADDRESS%/*} - IPV6_ADDRESS=${IPV6_ADDRESS} - - bool=true - #Is the domain in the list? - grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false - - if [[ "${bool}" == false ]]; then - if [[ "${verbose}" == true ]]; then - echo "::: Adding $1 to wildcard blacklist..." - fi - reload=true - echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}" - if [[ ${#IPV6_ADDRESS} > 0 ]] ; then - echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}" - fi - else - if [[ "${verbose}" == true ]]; then - echo "::: ${1} already exists in wildcard blacklist, no need to add!" - fi - fi - fi + if [[ "${bool}" == false ]]; then + if [[ "${verbose}" == true ]]; then + echo "::: Adding $1 to wildcard blacklist..." + fi + reload=true + echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}" + if [[ "${#IPV6_ADDRESS}" > 0 ]]; then + echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}" + fi + else + if [[ "${verbose}" == true ]]; then + echo "::: ${1} already exists in wildcard blacklist, no need to add!" + fi + fi + fi } RemoveDomain() { @@ -150,85 +146,82 @@ RemoveDomain() { domain=$(EscapeRegexp "$1") if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then - - bool=true - #Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa - grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false - if [[ "${bool}" == true ]]; then - # Remove it from the other one - echo "::: Removing $1 from $list..." - # /I flag: search case-insensitive - sed -i "/${domain}/Id" "${list}" - reload=true - else - if [[ "${verbose}" == true ]]; then - echo "::: ${1} does not exist in ${list}, no need to remove!" - fi + bool=true + # Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa + grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false + if [[ "${bool}" == true ]]; then + # Remove it from the other one + echo "::: Removing $1 from $list..." + # /I flag: search case-insensitive + sed -i "/${domain}/Id" "${list}" + reload=true + else + if [[ "${verbose}" == true ]]; then + echo "::: ${1} does not exist in ${list}, no need to remove!" fi - + fi elif [[ "${list}" == "${wildcardlist}" ]]; then - - bool=true - #Is it in the list? - grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false - if [[ "${bool}" == true ]]; then - # Remove it from the other one - echo "::: Removing $1 from $list..." - # /I flag: search case-insensitive - sed -i "/address=\/${domain}/Id" "${list}" - reload=true - else - if [[ "${verbose}" == true ]]; then - echo "::: ${1} does not exist in ${list}, no need to remove!" - fi + bool=true + # Is it in the list? + grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false + if [[ "${bool}" == true ]]; then + # Remove it from the other one + echo "::: Removing $1 from $list..." + # /I flag: search case-insensitive + sed -i "/address=\/${domain}/Id" "${list}" + reload=true + else + if [[ "${verbose}" == true ]]; then + echo "::: ${1} does not exist in ${list}, no need to remove!" fi + fi fi } Reload() { - # Reload hosts file - pihole -g -sd + # Reload hosts file + pihole -g -sd } Displaylist() { - if [[ ${listMain} == ${whitelist} ]]; then - string="gravity resistant domains" - else - string="domains caught in the sinkhole" - fi - verbose=false - echo -e " Displaying $string \n" - count=1 - while IFS= read -r RD; do - echo "${count}: ${RD}" - count=$((count+1)) - done < "${listMain}" - exit 0; + if [[ "${listMain}" == "${whitelist}" ]]; then + string="gravity resistant domains" + else + string="domains caught in the sinkhole" + fi + verbose=false + echo -e "Displaying $string:\n" + count=1 + while IFS= read -r RD; do + echo "${count}: ${RD}" + count=$((count+1)) + done < "${listMain}" + exit 0; } for var in "$@"; do - case "${var}" in - "-w" | "whitelist" ) listMain="${whitelist}"; listAlt="${blacklist}";; - "-b" | "blacklist" ) listMain="${blacklist}"; listAlt="${whitelist}";; - "-wild" | "wildcard" ) listMain="${wildcardlist}";; - "-nr"| "--noreload" ) reload=false;; - "-d" | "--delmode" ) addmode=false;; - "-f" | "--force" ) force=true;; - "-q" | "--quiet" ) verbose=false;; - "-h" | "--help" ) helpFunc;; - "-l" | "--list" ) Displaylist;; - * ) HandleOther "${var}";; - esac + case "${var}" in + "-w" | "whitelist" ) listMain="${whitelist}"; listAlt="${blacklist}";; + "-b" | "blacklist" ) listMain="${blacklist}"; listAlt="${whitelist}";; + "-wild" | "wildcard" ) listMain="${wildcardlist}";; + "-nr"| "--noreload" ) reload=false;; + "-d" | "--delmode" ) addmode=false;; + "-f" | "--force" ) force=true;; + "-q" | "--quiet" ) verbose=false;; + "-h" | "--help" ) helpFunc;; + "-l" | "--list" ) Displaylist;; + * ) HandleOther "${var}";; + esac done shift if [[ $# = 0 ]]; then - helpFunc + helpFunc fi PoplistFile if ${reload}; then - Reload + Reload fi diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh index 09f20d6b..00bea12c 100644 --- a/advanced/Scripts/piholeCheckout.sh +++ b/advanced/Scripts/piholeCheckout.sh @@ -3,7 +3,7 @@ # (c) 2017 Pi-hole, LLC (https://pi-hole.net) # Network-wide ad blocking via your own hardware. # -# Checkout other branches than master +# Switch Pi-hole subsystems to a different Github branch # # This file is copyright under the latest version of the EUPL. # Please see LICENSE file for your rights under this license. @@ -18,9 +18,12 @@ PH_TEST="true" source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" # setupVars set in basic-install.sh source "${setupVars}" - update="false" +# Colour codes +red="\e[1;31m" +def="\e[0m" + fully_fetch_repo() { # Add upstream branches to shallow clone local directory="${1}" @@ -35,7 +38,7 @@ fully_fetch_repo() { return 0 } -get_available_branches(){ +get_available_branches() { # Return available branches local directory="${1}" @@ -79,23 +82,23 @@ checkout_pull_branch() { } warning1() { - echo "::: Note that changing the branch is a severe change of your Pi-hole system." - echo "::: This is not supported unless one of the developers explicitly asks you to do this!" - read -r -p "::: Have you read and understood this? [y/N] " response + echo " Please note that changing branches severely alters your Pi-hole subsystems" + echo " Features that work on the master branch, may not on a development branch" + echo -e " ${red}This feature is NOT supported unless a Pi-hole developer explicitly asks!${def}" + read -r -p " Have you read and understood this? [Y/N] " response case ${response} in [yY][eE][sS]|[yY]) - echo "::: Continuing." + echo "::: Continuing with branch change." return 0 ;; *) - echo "::: Aborting." + echo "::: Branch change has been cancelled." return 1 ;; esac } -checkout() -{ +checkout() { local corebranches local webbranches @@ -192,11 +195,10 @@ checkout() if [[ ! "${1}" == "web" && "${update}" == "true" ]]; then echo "::: Running installer to upgrade your installation" if "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" --unattended; then - exit 0 + exit 0 else - echo "Unable to complete update, contact Pi-hole" - exit 1 + echo "Unable to complete update, contact Pi-hole" + exit 1 fi fi } - diff --git a/advanced/Scripts/version.sh b/advanced/Scripts/version.sh index 7f96e29a..73888295 100755 --- a/advanced/Scripts/version.sh +++ b/advanced/Scripts/version.sh @@ -3,24 +3,29 @@ # (c) 2017 Pi-hole, LLC (https://pi-hole.net) # Network-wide ad blocking via your own hardware. # -# shows version numbers +# Show version numbers # # This file is copyright under the latest version of the EUPL. # Please see LICENSE file for your rights under this license. # Variables DEFAULT="-1" -PHGITDIR="/etc/.pihole/" +COREGITDIR="/etc/.pihole/" WEBGITDIR="/var/www/html/admin/" getLocalVersion() { + # FTL requires a different method + if [[ "$1" == "FTL" ]]; then + pihole-FTL version + return 0 + fi + # Get the tagged version of the local repository local directory="${1}" local version - cd "${directory}" || { echo "${DEFAULT}"; return 1; } - version=$(git describe --tags --always || \ - echo "${DEFAULT}") + cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; } + version=$(git describe --tags --always || echo "$DEFAULT") if [[ "${version}" =~ ^v ]]; then echo "${version}" elif [[ "${version}" == "${DEFAULT}" ]]; then @@ -33,13 +38,18 @@ getLocalVersion() { } getLocalHash() { + # Local FTL hash does not exist on filesystem + if [[ "$1" == "FTL" ]]; then + echo "N/A" + return 0 + fi + # Get the short hash of the local repository local directory="${1}" local hash - cd "${directory}" || { echo "${DEFAULT}"; return 1; } - hash=$(git rev-parse --short HEAD || \ - echo "${DEFAULT}") + cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; } + hash=$(git rev-parse --short HEAD || echo "$DEFAULT") if [[ "${hash}" == "${DEFAULT}" ]]; then echo "ERROR" return 1 @@ -49,12 +59,33 @@ getLocalHash() { return 0 } +getRemoteHash(){ + # Remote FTL hash is not applicable + if [[ "$1" == "FTL" ]]; then + echo "N/A" + return 0 + fi + + local daemon="${1}" + local branch="${2}" + + hash=$(git ls-remote --heads "https://github.com/pi-hole/${daemon}" | \ + awk -v bra="$branch" '$0~bra {print substr($0,0,8);exit}') + if [[ -n "$hash" ]]; then + echo "$hash" + else + echo "ERROR" + return 1 + fi + return 0 +} + getRemoteVersion(){ # Get the version from the remote origin local daemon="${1}" local version - version=$(curl --silent --fail https://api.github.com/repos/pi-hole/${daemon}/releases/latest | \ + version=$(curl --silent --fail "https://api.github.com/repos/pi-hole/${daemon}/releases/latest" | \ awk -F: '$1 ~/tag_name/ { print $2 }' | \ tr -cd '[[:alnum:]]._-') if [[ "${version}" =~ ^v ]]; then @@ -66,72 +97,73 @@ getRemoteVersion(){ return 0 } -#PHHASHLATEST=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/commits/master | \ -# grep sha | \ -# head -n1 | \ -# awk -F ' ' '{ print $2 }' | \ -# tr -cd '[[:alnum:]]._-') - -#WEBHASHLATEST=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/commits/master | \ -# grep sha | \ -# head -n1 | \ -# awk -F ' ' '{ print $2 }' | \ -# tr -cd '[[:alnum:]]._-') - - -normalOutput() { - echo "::: Pi-hole version is $(getLocalVersion "${PHGITDIR}") (Latest version is $(getRemoteVersion pi-hole))" - if [ -d "${WEBGITDIR}" ]; then - echo "::: Web-Admin version is $(getLocalVersion "${WEBGITDIR}") (Latest version is $(getRemoteVersion AdminLTE))" - fi -} - -webOutput() { - if [ -d "${WEBGITDIR}" ]; then - case "${1}" in - "-l" | "--latest" ) echo $(getRemoteVersion AdminLTE);; - "-c" | "--current" ) echo $(getLocalVersion "${WEBGITDIR}");; - "-h" | "--hash" ) echo $(getLocalHash "${WEBGITDIR}");; - * ) echo "::: Invalid Option!"; exit 1; - esac - else - echo "::: Web interface not installed!"; exit 1; +versionOutput() { + [[ "$1" == "pi-hole" ]] && GITDIR=$COREGITDIR + [[ "$1" == "AdminLTE" ]] && GITDIR=$WEBGITDIR + [[ "$1" == "FTL" ]] && GITDIR="FTL" + + [[ "$2" == "-c" ]] || [[ "$2" == "--current" ]] || [[ -z "$2" ]] && current=$(getLocalVersion $GITDIR) + [[ "$2" == "-l" ]] || [[ "$2" == "--latest" ]] || [[ -z "$2" ]] && latest=$(getRemoteVersion "$1") + if [[ "$2" == "-h" ]] || [[ "$2" == "--hash" ]]; then + [[ "$3" == "-c" ]] || [[ "$3" == "--current" ]] || [[ -z "$3" ]] && curHash=$(getLocalHash "$GITDIR") + [[ "$3" == "-l" ]] || [[ "$3" == "--latest" ]] || [[ -z "$3" ]] && latHash=$(getRemoteHash "$1" "$(cd "$GITDIR" 2> /dev/null && git rev-parse --abbrev-ref HEAD)") fi + + if [[ -n "$current" ]] && [[ -n "$latest" ]]; then + output="${1^} version is $current (Latest: $latest)" + elif [[ -n "$current" ]] && [[ -z "$latest" ]]; then + output="Current ${1^} version is $current" + elif [[ -z "$current" ]] && [[ -n "$latest" ]]; then + output="Latest ${1^} version is $latest" + elif [[ "$curHash" == "N/A" ]] || [[ "$latHash" == "N/A" ]]; then + output="${1^} hash is not applicable" + elif [[ -n "$curHash" ]] && [[ -n "$latHash" ]]; then + output="${1^} hash is $curHash (Latest: $latHash)" + elif [[ -n "$curHash" ]] && [[ -z "$latHash" ]]; then + output="Current ${1^} hash is $curHash" + elif [[ -z "$curHash" ]] && [[ -n "$latHash" ]]; then + output="Latest ${1^} hash is $latHash" + else + errorOutput + fi + + [[ -n "$output" ]] && echo "$output" } -coreOutput() { - case "${1}" in - "-l" | "--latest" ) echo $(getRemoteVersion pi-hole);; - "-c" | "--current" ) echo $(getLocalVersion "${PHGITDIR}");; - "-h" | "--hash" ) echo $(getLocalHash "${PHGITDIR}");; - * ) echo "::: Invalid Option!"; exit 1; - esac +errorOutput() { + echo "Invalid Option! Try 'pihole -v -h' for more information." + exit 1 +} + +defaultOutput() { + versionOutput "pi-hole" "$@" + versionOutput "AdminLTE" "$@" + versionOutput "FTL" "$@" } helpFunc() { - cat << EOM -::: -::: Show Pi-hole/Web Admin versions -::: -::: Usage: pihole -v [ -a | -p ] [ -l | -c ] -::: -::: Options: -::: -a, --admin Show both current and latest versions of web admin -::: -p, --pihole Show both current and latest versions of Pi-hole core files -::: -l, --latest (Only after -a | -p) Return only latest version -::: -c, --current (Only after -a | -p) Return only current version -::: -h, --help Show this help dialog -::: -EOM - exit 0 + echo "Usage: pihole -v [REPO | OPTION] [OPTION] +Example: 'pihole -v -p -l' +Show Pi-hole, Admin Console & FTL versions + +Repositories: + -p, --pihole Only retrieve info regarding Pi-hole repository + -a, --admin Only retrieve info regarding AdminLTE repository + -f, --ftl Only retrieve info regarding FTL repository + +Options: + -c, --current Return the current version + -l, --latest Return the latest version + -h, --hash Return the Github hash from your local repositories + --help Show this help dialog +" + exit 0 } -if [[ $# = 0 ]]; then - normalOutput -fi - case "${1}" in - "-a" | "--admin" ) shift; webOutput "$@";; - "-p" | "--pihole" ) shift; coreOutput "$@" ;; - "-h" | "--help" ) helpFunc;; + "-p" | "--pihole" ) shift; versionOutput "pi-hole" "$@";; + "-a" | "--admin" ) shift; versionOutput "AdminLTE" "$@";; + "-f" | "--ftl" ) shift; versionOutput "FTL" "$@";; + "--help" ) helpFunc;; + * ) defaultOutput "$@";; esac diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh index d3ad3032..6626dab8 100755 --- a/advanced/Scripts/webpage.sh +++ b/advanced/Scripts/webpage.sh @@ -8,7 +8,6 @@ # This file is copyright under the latest version of the EUPL. # Please see LICENSE file for your rights under this license. - readonly setupVars="/etc/pihole/setupVars.conf" readonly dnsmasqconfig="/etc/dnsmasq.d/01-pihole.conf" readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf" @@ -16,23 +15,19 @@ readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf" readonly dhcpstaticconfig="/etc/dnsmasq.d/04-pihole-static-dhcp.conf" helpFunc() { - cat << EOM -::: Set admin options for the web interface of pihole -::: -::: Usage: pihole -a [options] -::: -::: Options: -::: -p, password Set web interface password, an empty input will remove any previously set password -::: -c, celsius Set Celsius temperature unit -::: -f, fahrenheit Set Fahrenheit temperature unit -::: -k, kelvin Set Kelvin temperature unit -::: -h, --help Show this help dialog -::: -i, interface Setup interface listening behavior of dnsmasq -::: pihole -a -i local : Listen on all interfaces, but allow only queries from -::: devices that are at most one hop away (local devices) -::: pihole -a -i single : Listen only on one interface (see PIHOLE_INTERFACE) -::: pihole -a -i all : Listen on all interfaces, permit all origins -EOM + echo "Usage: pihole -a [options] +Example: pihole -a -p password +Set options for the Admin Console + +Options: + -f, flush Flush the Pi-hole log + -p, password Set Admin Console password + -c, celsius Set Celsius as preferred temperature unit + -f, fahrenheit Set Fahrenheit as preferred temperature unit + -k, kelvin Set Kelvin as preferred temperature unit + -h, --help Show this help dialog + -i, interface Specify dnsmasq's interface listening behavior + Add '-h' for more info on interface usage" exit 0 } @@ -61,21 +56,18 @@ delete_dnsmasq_setting() { sed -i "/${1}/d" "${dnsmasqconfig}" } -SetTemperatureUnit(){ - +SetTemperatureUnit() { change_setting "TEMPERATUREUNIT" "${unit}" - } -HashPassword(){ - # Compute password hash twice to avoid rainbow table vulnerability - return=$(echo -n ${1} | sha256sum | sed 's/\s.*$//') - return=$(echo -n ${return} | sha256sum | sed 's/\s.*$//') - echo ${return} +HashPassword() { + # Compute password hash twice to avoid rainbow table vulnerability + return=$(echo -n ${1} | sha256sum | sed 's/\s.*$//') + return=$(echo -n ${return} | sha256sum | sed 's/\s.*$//') + echo ${return} } -SetWebPassword(){ - +SetWebPassword() { if [ "${SUDO_USER}" == "www-data" ]; then echo "Security measure: user www-data is not allowed to change webUI password!" echo "Exiting" @@ -175,8 +167,7 @@ trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE3 } -SetDNSServers(){ - +SetDNSServers() { # Save setting to file delete_setting "PIHOLE_DNS" IFS=',' read -r -a array <<< "${args[2]}" @@ -207,72 +198,59 @@ SetDNSServers(){ # Restart dnsmasq to load new configuration RestartDNS - } -SetExcludeDomains(){ - +SetExcludeDomains() { change_setting "API_EXCLUDE_DOMAINS" "${args[2]}" - } -SetExcludeClients(){ - +SetExcludeClients() { change_setting "API_EXCLUDE_CLIENTS" "${args[2]}" - } -Reboot(){ - +Reboot() { nohup bash -c "sleep 5; reboot" &> /dev/null /dev/null else service dnsmasq restart &> /dev/null fi - } -SetQueryLogOptions(){ - +SetQueryLogOptions() { change_setting "API_QUERY_LOG_SHOW" "${args[2]}" - } ProcessDHCPSettings() { - source "${setupVars}" if [[ "${DHCP_ACTIVE}" == "true" ]]; then + interface=$(grep 'PIHOLE_INTERFACE=' /etc/pihole/setupVars.conf | sed "s/.*=//") - interface=$(grep 'PIHOLE_INTERFACE=' /etc/pihole/setupVars.conf | sed "s/.*=//") + # Use eth0 as fallback interface + if [ -z ${interface} ]; then + interface="eth0" + fi - # Use eth0 as fallback interface - if [ -z ${interface} ]; then - interface="eth0" - fi + if [[ "${PIHOLE_DOMAIN}" == "" ]]; then + PIHOLE_DOMAIN="local" + change_setting "PIHOLE_DOMAIN" "${PIHOLE_DOMAIN}" + fi - if [[ "${PIHOLE_DOMAIN}" == "" ]]; then - PIHOLE_DOMAIN="local" - change_setting "PIHOLE_DOMAIN" "${PIHOLE_DOMAIN}" - fi + if [[ "${DHCP_LEASETIME}" == "0" ]]; then + leasetime="infinite" + elif [[ "${DHCP_LEASETIME}" == "" ]]; then + leasetime="24h" + change_setting "DHCP_LEASETIME" "${leasetime}" + else + leasetime="${DHCP_LEASETIME}h" + fi - if [[ "${DHCP_LEASETIME}" == "0" ]]; then - leasetime="infinite" - elif [[ "${DHCP_LEASETIME}" == "" ]]; then - leasetime="24h" - change_setting "DHCP_LEASETIME" "${leasetime}" - else - leasetime="${DHCP_LEASETIME}h" - fi - - # Write settings to file - echo "############################################################################### + # Write settings to file + echo "############################################################################### # DHCP SERVER CONFIG FILE AUTOMATICALLY POPULATED BY PI-HOLE WEB INTERFACE. # # ANY CHANGES MADE TO THIS FILE WILL BE LOST ON CHANGE # ############################################################################### @@ -283,26 +261,25 @@ dhcp-leasefile=/etc/pihole/dhcp.leases #quiet-dhcp " > "${dhcpconfig}" -if [[ "${PIHOLE_DOMAIN}" != "none" ]]; then - echo "domain=${PIHOLE_DOMAIN}" >> "${dhcpconfig}" -fi + if [[ "${PIHOLE_DOMAIN}" != "none" ]]; then + echo "domain=${PIHOLE_DOMAIN}" >> "${dhcpconfig}" + fi - if [[ "${DHCP_IPv6}" == "true" ]]; then -echo "#quiet-dhcp6 + if [[ "${DHCP_IPv6}" == "true" ]]; then + echo "#quiet-dhcp6 #enable-ra dhcp-option=option6:dns-server,[::] dhcp-range=::100,::1ff,constructor:${interface},ra-names,slaac,${leasetime} ra-param=*,0,0 " >> "${dhcpconfig}" - fi + fi else rm "${dhcpconfig}" &> /dev/null fi } -EnableDHCP(){ - +EnableDHCP() { change_setting "DHCP_ACTIVE" "true" change_setting "DHCP_START" "${args[2]}" change_setting "DHCP_END" "${args[3]}" @@ -320,8 +297,7 @@ EnableDHCP(){ RestartDNS } -DisableDHCP(){ - +DisableDHCP() { change_setting "DHCP_ACTIVE" "false" # Remove possible old setting from file @@ -333,23 +309,20 @@ DisableDHCP(){ RestartDNS } -SetWebUILayout(){ - +SetWebUILayout() { change_setting "WEBUIBOXEDLAYOUT" "${args[2]}" - } CustomizeAdLists() { - list="/etc/pihole/adlists.list" - if [[ "${args[2]}" == "enable" ]] ; then + if [[ "${args[2]}" == "enable" ]]; then sed -i "\\@${args[3]}@s/^#http/http/g" "${list}" - elif [[ "${args[2]}" == "disable" ]] ; then + elif [[ "${args[2]}" == "disable" ]]; then sed -i "\\@${args[3]}@s/^http/#http/g" "${list}" - elif [[ "${args[2]}" == "add" ]] ; then + elif [[ "${args[2]}" == "add" ]]; then echo "${args[3]}" >> ${list} - elif [[ "${args[2]}" == "del" ]] ; then + elif [[ "${args[2]}" == "del" ]]; then var=$(echo "${args[3]}" | sed 's/\//\\\//g') sed -i "/${var}/Id" "${list}" else @@ -358,18 +331,15 @@ CustomizeAdLists() { fi } -SetPrivacyMode(){ - - if [[ "${args[2]}" == "true" ]] ; then +SetPrivacyMode() { + if [[ "${args[2]}" == "true" ]]; then change_setting "API_PRIVACY_MODE" "true" else change_setting "API_PRIVACY_MODE" "false" fi - } ResolutionSettings() { - typ="${args[2]}" state="${args[3]}" @@ -378,11 +348,9 @@ ResolutionSettings() { elif [[ "${typ}" == "clients" ]]; then change_setting "API_GET_CLIENT_HOSTNAME" "${state}" fi - } AddDHCPStaticAddress() { - mac="${args[2]}" ip="${args[3]}" host="${args[4]}" @@ -397,18 +365,14 @@ AddDHCPStaticAddress() { # Full info given echo "dhcp-host=${mac},${ip},${host}" >> "${dhcpstaticconfig}" fi - } RemoveDHCPStaticAddress() { - mac="${args[2]}" sed -i "/dhcp-host=${mac}.*/d" "${dhcpstaticconfig}" - } -SetHostRecord(){ - +SetHostRecord() { if [ -n "${args[3]}" ]; then change_setting "HOSTRECORD" "${args[2]},${args[3]}" echo "Setting host record for ${args[2]} -> ${args[3]}" @@ -421,17 +385,28 @@ SetHostRecord(){ # Restart dnsmasq to load new configuration RestartDNS - } -SetListeningMode(){ - +SetListeningMode() { source "${setupVars}" + + if [[ "$3" == "-h" ]]; then + echo "Usage: pihole -a -i [interface] +Example: 'pihole -a -i local' +Specify dnsmasq's network interface listening behavior - if [[ "${args[2]}" == "all" ]] ; then +Interfaces: + local Listen on all interfaces, but only allow queries from + devices that are at most one hop away (local devices) + single Listen only on ${PIHOLE_INTERFACE} interface + all Listen on all interfaces, permit all origins" + exit 0 + fi + + if [[ "${args[2]}" == "all" ]]; then echo "Listening on all interfaces, permiting all origins, hope you have a firewall!" change_setting "DNSMASQ_LISTENING" "all" - elif [[ "${args[2]}" == "local" ]] ; then + elif [[ "${args[2]}" == "local" ]]; then echo "Listening on all interfaces, permitting only origins that are at most one hop away (local devices)" change_setting "DNSMASQ_LISTENING" "local" else @@ -446,17 +421,14 @@ SetListeningMode(){ # Restart dnsmasq to load new configuration RestartDNS fi - } -Teleporter() -{ +Teleporter() { local datetimestamp=$(date "+%Y-%m-%d_%H-%M-%S") php /var/www/html/admin/scripts/pi-hole/php/teleporter.php > "pi-hole-teleporter_${datetimestamp}.zip" } main() { - args=("$@") case "${args[1]}" in @@ -479,7 +451,7 @@ main() { "addstaticdhcp" ) AddDHCPStaticAddress;; "removestaticdhcp" ) RemoveDHCPStaticAddress;; "hostrecord" ) SetHostRecord;; - "-i" | "interface" ) SetListeningMode;; + "-i" | "interface" ) SetListeningMode "$@";; "-t" | "teleporter" ) Teleporter;; "adlist" ) CustomizeAdLists;; * ) helpFunc;; @@ -490,5 +462,4 @@ main() { if [[ $# = 0 ]]; then helpFunc fi - } diff --git a/pihole b/pihole index 83e13000..79a5c35d 100755 --- a/pihole +++ b/pihole @@ -9,11 +9,11 @@ # Please see LICENSE file for your rights under this license. readonly PI_HOLE_SCRIPT_DIR="/opt/pihole" - readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf" + # Must be root to use this tool if [[ ! $EUID -eq 0 ]];then - if [ -x "$(command -v sudo)" ];then + if [[ -x "$(command -v sudo)" ]]; then exec sudo bash "$0" "$@" exit $? else @@ -80,66 +80,49 @@ updateGravityFunc() { exit 0 } -scanList(){ +scanList() { domain="${1}" list="${2}" method="${3}" - if [[ ${method} == "-exact" ]] ; then - grep -i -E "(^|\s)${domain}($|\s)" "${list}" - else - grep -i "${domain}" "${list}" - fi -} -processWildcards() { - IFS="." read -r -a array <<< "${1}" - for (( i=${#array[@]}-1; i>=0; i-- )); do - ar="" - for (( j=${#array[@]}-1; j>${#array[@]}-i-2; j-- )); do - if [[ $j == $((${#array[@]}-1)) ]]; then - ar="${array[$j]}" - else - ar="${array[$j]}.${ar}" - fi - done - echo "${ar}" - done + if [[ "${method}" == "-exact" ]]; then + grep -i -E -l "(^|\s|\/)${domain}($|\s|\/)" ${list} + else + grep -i "${domain}" ${list} + fi } queryFunc() { - domain="${2}" method="${3}" - lists=( /etc/pihole/list.* /etc/pihole/blacklist.txt) - for list in ${lists[@]}; do - if [ -e "${list}" ]; then - result=$(scanList ${domain} ${list} ${method}) - # Remove empty lines before couting number of results - count=$(sed '/^\s*$/d' <<< "$result" | wc -l) - echo "::: ${list} (${count} results)" - if [[ ${count} > 0 ]]; then - echo "${result}" - fi - echo "" - else - echo "::: ${list} does not exist" - echo "" - fi - done - - # Scan for possible wildcard matches - if [ -e "${wildcardlist}" ]; then - local wildcards=($(processWildcards "${domain}")) - for domain in ${wildcards[@]}; do - result=$(scanList "\/${domain}\/" ${wildcardlist}) - # Remove empty lines before couting number of results - count=$(sed '/^\s*$/d' <<< "$result" | wc -l) - if [[ ${count} > 0 ]]; then - echo "::: Wildcard blocking ${domain} (${count} results)" - echo "${result}" - echo "" - fi - done + + # If domain contains non ASCII characters, convert domain to punycode if python exists + # Cr: https://serverfault.com/a/335079 + if [[ -z "${2}" ]]; then + echo "::: No domain specified" + exit 1 + elif [[ "${2}" = *[![:ascii:]]* ]]; then + [[ "$(which python)" ]] && domain=$(python -c 'import sys;print sys.argv[1].decode("utf-8").encode("idna")' "${2}") + else + domain="${2}" fi + + # Scan Whitelist, Blacklist and Wildcards + lists="/etc/pihole/whitelist.txt /etc/pihole/blacklist.txt $wildcardlist" + result=$(scanList ${domain} "${lists}" ${method}) + if [[ -n "$result" ]]; then + echo "$result" + [[ ! -t 1 ]] && exit 0 + fi + + # Scan Domains lists + result=$(scanList ${domain} "/etc/pihole/*.domains" ${method}) + if [[ -n "$result" ]]; then + sort -t . -k 2 -g <<< "$result" + else + [ -n "$method" ] && exact="exact " + echo "::: No ${exact}results found for ${domain}" + fi + exit 0 } @@ -163,16 +146,16 @@ versionFunc() { restartDNS() { dnsmasqPid=$(pidof dnsmasq) - if [[ ${dnsmasqPid} ]]; then - # service already running - reload config - if [ -x "$(command -v systemctl)" ]; then + if [[ "${dnsmasqPid}" ]]; then + # Service already running - reload config + if [[ -x "$(command -v systemctl)" ]]; then systemctl restart dnsmasq else service dnsmasq restart fi else - # service not running, start it up - if [ -x "$(command -v systemctl)" ]; then + # Service not running, start it up + if [[ -x "$(command -v systemctl)" ]]; then systemctl start dnsmasq else service dnsmasq start @@ -181,16 +164,25 @@ restartDNS() { } piholeEnable() { - if [[ "${1}" == "0" ]] ; then - #Disable Pihole + if [[ "${2}" == "-h" ]]; then + echo "Usage: pihole disable [time] +Example: 'pihole disable', or 'pihole disable 5m' +Disable Pi-hole subsystems + +Time: + #s Disable Pi-hole functionality for # second(s) + #m Disable Pi-hole functionality for # minute(s)" + exit 0 + elif [[ "${1}" == "0" ]]; then + # Disable Pi-hole sed -i 's/^addn-hosts=\/etc\/pihole\/gravity.list/#addn-hosts=\/etc\/pihole\/gravity.list/' /etc/dnsmasq.d/01-pihole.conf echo "::: Blocking has been disabled!" - if [[ $# > 1 ]] ; then - if [[ ${2} == *"s"* ]] ; then + if [[ $# > 1 ]]; then + if [[ "${2}" == *"s"* ]]; then tt=${2%"s"} echo "::: Blocking will be re-enabled in ${tt} seconds" nohup bash -c "sleep ${tt}; pihole enable" /dev/null & - elif [[ ${2} == *"m"* ]] ; then + elif [[ "${2}" == *"m"* ]]; then tt=${2%"m"} echo "::: Blocking will be re-enabled in ${tt} minutes" tt=$((${tt}*60)) @@ -204,7 +196,7 @@ piholeEnable() { fi fi else - #Enable pihole + # Enable Pi-hole echo "::: Blocking has been enabled!" sed -i 's/^#addn-hosts/addn-hosts/' /etc/dnsmasq.d/01-pihole.conf fi @@ -213,15 +205,23 @@ piholeEnable() { piholeLogging() { shift + if [[ "${1}" == "-h" ]]; then + echo "Usage: pihole logging [options] +Example: 'pihole logging on' +Specify whether the Pi-hole log should be used - if [[ "${1}" == "off" ]] ; then - #Disable Logging +Options: + on Enable the Pi-hole log at /var/log/pihole.log + off Disable the Pi-hole log at /var/log/pihole.log" + exit 0 + elif [[ "${1}" == "off" ]]; then + # Disable logging sed -i 's/^log-queries/#log-queries/' /etc/dnsmasq.d/01-pihole.conf sed -i 's/^QUERY_LOGGING=true/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf pihole -f echo "::: Logging has been disabled!" - elif [[ "${1}" == "on" ]] ; then - #Enable logging + elif [[ "${1}" == "on" ]]; then + # Enable logging sed -i 's/^#log-queries/log-queries/' /etc/dnsmasq.d/01-pihole.conf sed -i 's/^QUERY_LOGGING=false/QUERY_LOGGING=true/' /etc/pihole/setupVars.conf echo "::: Logging has been enabled!" @@ -233,12 +233,12 @@ piholeLogging() { } piholeStatus() { - if [[ $(netstat -plnt | grep -c ':53 ') > 0 ]]; then - if [[ "${1}" != "web" ]] ; then + if [[ "$(netstat -plnt | grep -c ':53 ')" -gt "0" ]]; then + if [[ "${1}" != "web" ]]; then echo "::: DNS service is running" fi else - if [[ "${1}" == "web" ]] ; then + if [[ "${1}" == "web" ]]; then echo "-1"; else echo "::: DNS service is NOT running" @@ -246,28 +246,28 @@ piholeStatus() { return fi - if [[ $(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then - #list is commented out - if [[ "${1}" == "web" ]] ; then + if [[ "$(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf)" ]]; then + # List is commented out + if [[ "${1}" == "web" ]]; then echo 0; else echo "::: Pi-hole blocking is Disabled"; fi - elif [[ $(grep -i "^addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then - #list set - if [[ "${1}" == "web" ]] ; then + elif [[ "$(grep -i "^addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf)" ]]; then + # List set + if [[ "${1}" == "web" ]]; then echo 1; else echo "::: Pi-hole blocking is Enabled"; fi else - #addn-host not found - if [[ "${1}" == "web" ]] ; then + # Addn-host not found + if [[ "${1}" == "web" ]]; then echo 99 else echo "::: No hosts file linked to dnsmasq, adding it in enabled state" fi - #add addn-host= to dnsmasq + # Add addn-host= to dnsmasq echo "addn-hosts=/etc/pihole/gravity.list" >> /etc/dnsmasq.d/01-pihole.conf restartDNS fi @@ -280,46 +280,66 @@ tailFunc() { } piholeCheckoutFunc() { + if [[ "$2" == "-h" ]]; then + echo "Usage: pihole checkout [repo] [branch] +Example: 'pihole checkout master' or 'pihole checkout core dev' +Switch Pi-hole subsystems to a different Github branch + +Repositories: + core [branch] Change the branch of Pi-hole's core subsystem + web [branch] Change the branch of Admin Console subsystem + +Branches: + master Update subsystems to the latest stable release + dev Update subsystems to the latest development release" + exit 0 + fi + source "${PI_HOLE_SCRIPT_DIR}"/piholeCheckout.sh shift checkout "$@" } helpFunc() { - cat << EOM -::: Control all Pi-hole specific functions -::: -::: Usage: pihole [options] -::: Add -h after -w (whitelist), -b (blacklist), -c (chronometer), or -a (admin) for more information on usage -::: -::: Options: -::: -w, whitelist Whitelist domain(s) -::: -b, blacklist Blacklist domain(s) (exact match) -::: -wild, wildcard Blacklist whole domain(s) (wildcard) -::: -d, debug Start a debugging session -::: Automated debugging can be enabled with '-a'. -::: 'pihole -d -a' -::: -f, flush Flush the 'pihole.log' file -::: -t, tail Output the last lines of the 'pihole.log' file. Lines are appended as the file grows -::: -up, updatePihole Update Pi-hole components -::: -r, reconfigure Reconfigure or Repair Pi-hole -::: -g, updateGravity Update the list of ad-serving domains -::: -c, chronometer Calculates stats and displays to an LCD -::: -h, help Show this help dialog -::: -v, version Show installed versions of Pi-hole and Web-Admin -::: -q, query Query the adlists for a specific domain -::: 'pihole -q domain -exact' shows exact matches only -::: -l, logging Enable or Disable logging (pass 'on' or 'off') -::: -a, admin Admin webpage options -::: uninstall Uninstall Pi-hole from your system! :( -::: status Display if Pi-hole is Enabled or Disabled -::: enable Enable Pi-hole DNS Blocking -::: disable Disable Pi-hole DNS Blocking -::: Blocking can also be disabled only temporarily, e.g., -::: 'pihole disable 5m' - will disable blocking for 5 minutes -::: restartdns Restart dnsmasq -::: checkout Check out different branches -EOM + echo "Usage: pihole [options] +Example: 'pihole -w -h' +Add '-h' after specific commands for more information on usage + +Whitelist/Blacklist Options: + -w, whitelist Whitelist domain(s) + -b, blacklist Blacklist domain(s) + -wild, wildcard Blacklist domain(s), and all its subdomains + Add '-h' for more info on whitelist/blacklist usage + +Debugging Options: + -d, debug Start a debugging session + Add '-a' to enable automated debugging + -f, flush Flush the Pi-hole log + -r, reconfigure Reconfigure or Repair Pi-hole subsystems + -t, tail View the live output of the Pi-hole log + +Options: + -a, admin Admin Console options + Add '-h' for more info on admin console usage + -c, chronometer Calculates stats and displays to an LCD + Add '-h' for more info on chronometer usage + -g, updateGravity Update the list of ad-serving domains + -h, --help, help Show this help dialog + -l, logging Specify whether the Pi-hole log should be used + Add '-h' for more info on logging usage + -q, query Query the adlists for a specified domain + Add '-exact' AFTER a specified domain for exact match + -up, updatePihole Update Pi-hole subsystems + -v, version Show installed versions of Pi-hole, Admin Console & FTL + Add '-h' for more info on version usage + uninstall Uninstall Pi-hole from your system + status Display the running status of Pi-hole subsystems + enable Enable Pi-hole subsystems + disable Disable Pi-hole subsystems + Add '-h' for more info on disable usage + restartdns Restart Pi-hole subsystems + checkout Switch Pi-hole subsystems to a different Github branch + Add '-h' for more info on checkout usage"; exit 0 } @@ -344,7 +364,7 @@ case "${1}" in "-l" | "logging" ) piholeLogging "$@";; "uninstall" ) uninstallFunc;; "enable" ) piholeEnable 1;; - "disable" ) piholeEnable 0 $2;; + "disable" ) piholeEnable 0 "$2";; "status" ) piholeStatus "$2";; "restartdns" ) restartDNS;; "-a" | "admin" ) webpageFunc "$@";; From 0e4473685bb9fdc00f196cf2751be99c6877368c Mon Sep 17 00:00:00 2001 From: WaLLy3K Date: Sun, 14 May 2017 11:47:56 +1000 Subject: [PATCH 3/7] Show help for "pihole -a -i --help" --- advanced/Scripts/webpage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh index 6626dab8..8419aa8d 100755 --- a/advanced/Scripts/webpage.sh +++ b/advanced/Scripts/webpage.sh @@ -390,7 +390,7 @@ SetHostRecord() { SetListeningMode() { source "${setupVars}" - if [[ "$3" == "-h" ]]; then + if [[ "$3" == "-h" ]] || [[ "$3" == "--help" ]]; then echo "Usage: pihole -a -i [interface] Example: 'pihole -a -i local' Specify dnsmasq's network interface listening behavior From 4eb7d2868ca2d347ed0a497b6fb5c3a195ac4bf6 Mon Sep 17 00:00:00 2001 From: WaLLy3K Date: Sun, 14 May 2017 11:53:40 +1000 Subject: [PATCH 4/7] Fix "pihole disable --help" and "pihole -l --help" --- pihole | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pihole b/pihole index 79a5c35d..1b75add5 100755 --- a/pihole +++ b/pihole @@ -164,7 +164,7 @@ restartDNS() { } piholeEnable() { - if [[ "${2}" == "-h" ]]; then + if [[ "${2}" == "-h" ]] || [[ "${2}" == "--help" ]]; then echo "Usage: pihole disable [time] Example: 'pihole disable', or 'pihole disable 5m' Disable Pi-hole subsystems @@ -205,7 +205,7 @@ Time: piholeLogging() { shift - if [[ "${1}" == "-h" ]]; then + if [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]]; then echo "Usage: pihole logging [options] Example: 'pihole logging on' Specify whether the Pi-hole log should be used From 3bd677c102fddcce8ce72c81ae811b7453b8caa8 Mon Sep 17 00:00:00 2001 From: WaLLy3K Date: Sun, 14 May 2017 11:57:46 +1000 Subject: [PATCH 5/7] Show help for "pihole -v -h" * Indent output text * Minor help text change --- advanced/Scripts/version.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/advanced/Scripts/version.sh b/advanced/Scripts/version.sh index 73888295..50bdb608 100755 --- a/advanced/Scripts/version.sh +++ b/advanced/Scripts/version.sh @@ -104,7 +104,7 @@ versionOutput() { [[ "$2" == "-c" ]] || [[ "$2" == "--current" ]] || [[ -z "$2" ]] && current=$(getLocalVersion $GITDIR) [[ "$2" == "-l" ]] || [[ "$2" == "--latest" ]] || [[ -z "$2" ]] && latest=$(getRemoteVersion "$1") - if [[ "$2" == "-h" ]] || [[ "$2" == "--hash" ]]; then + if [[ "$2" == "--hash" ]]; then [[ "$3" == "-c" ]] || [[ "$3" == "--current" ]] || [[ -z "$3" ]] && curHash=$(getLocalHash "$GITDIR") [[ "$3" == "-l" ]] || [[ "$3" == "--latest" ]] || [[ -z "$3" ]] && latHash=$(getRemoteHash "$1" "$(cd "$GITDIR" 2> /dev/null && git rev-parse --abbrev-ref HEAD)") fi @@ -127,11 +127,11 @@ versionOutput() { errorOutput fi - [[ -n "$output" ]] && echo "$output" + [[ -n "$output" ]] && echo " $output" } errorOutput() { - echo "Invalid Option! Try 'pihole -v -h' for more information." + echo " Invalid Option! Try 'pihole -v -h' for more information." exit 1 } @@ -142,7 +142,7 @@ defaultOutput() { } helpFunc() { - echo "Usage: pihole -v [REPO | OPTION] [OPTION] + echo "Usage: pihole -v [repo | option] [option] Example: 'pihole -v -p -l' Show Pi-hole, Admin Console & FTL versions @@ -154,8 +154,8 @@ Repositories: Options: -c, --current Return the current version -l, --latest Return the latest version - -h, --hash Return the Github hash from your local repositories - --help Show this help dialog + --hash Return the Github hash from your local repositories + -h, --help Show this help dialog " exit 0 } @@ -164,6 +164,6 @@ case "${1}" in "-p" | "--pihole" ) shift; versionOutput "pi-hole" "$@";; "-a" | "--admin" ) shift; versionOutput "AdminLTE" "$@";; "-f" | "--ftl" ) shift; versionOutput "FTL" "$@";; - "--help" ) helpFunc;; + "-h" | "--help" ) helpFunc;; * ) defaultOutput "$@";; esac From 39b74ebfd47e1847ebaff7cfabccb6fdc7d20f90 Mon Sep 17 00:00:00 2001 From: WaLLy3K Date: Sun, 14 May 2017 12:22:19 +1000 Subject: [PATCH 6/7] Show help for "pihole checkout --help" --- pihole | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pihole b/pihole index 1b75add5..c1359ef9 100755 --- a/pihole +++ b/pihole @@ -280,7 +280,7 @@ tailFunc() { } piholeCheckoutFunc() { - if [[ "$2" == "-h" ]]; then + if [[ "$2" == "-h" ]] || [[ "$2" == "--help" ]]; then echo "Usage: pihole checkout [repo] [branch] Example: 'pihole checkout master' or 'pihole checkout core dev' Switch Pi-hole subsystems to a different Github branch From 69f361a3a1884879fe18ec8c1dccc09fabfc3815 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sun, 14 May 2017 16:28:35 +0200 Subject: [PATCH 7/7] :taco: is the new :shipit: squirrel --- .pullapprove.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pullapprove.yml b/.pullapprove.yml index 39566b34..188a64f2 100644 --- a/.pullapprove.yml +++ b/.pullapprove.yml @@ -10,7 +10,7 @@ group_defaults: reset_on_push: enabled: true reject_value: -2 - approve_regex: '^(Approved|:shipit:|:\+1:|Engage)' + approve_regex: '^(Approved|:shipit:|:\+1:|Engage|:taco:)' reject_regex: '^(Rejected|:-1:|Borg)' author_approval: auto: true