Merge pull request #3035 from pi-hole/fix/query_gravity
pihole -q should also scan gravity table
This commit is contained in:
commit
a1633123aa
|
@ -13,7 +13,6 @@
|
||||||
piholeDir="/etc/pihole"
|
piholeDir="/etc/pihole"
|
||||||
gravityDBfile="${piholeDir}/gravity.db"
|
gravityDBfile="${piholeDir}/gravity.db"
|
||||||
options="$*"
|
options="$*"
|
||||||
adlist=""
|
|
||||||
all=""
|
all=""
|
||||||
exact=""
|
exact=""
|
||||||
blockpage=""
|
blockpage=""
|
||||||
|
@ -53,7 +52,6 @@ Example: 'pihole -q -exact domain.com'
|
||||||
Query the adlists for a specified domain
|
Query the adlists for a specified domain
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-adlist Print the name of the block list URL
|
|
||||||
-exact Search the block lists for exact domain matches
|
-exact Search the block lists for exact domain matches
|
||||||
-all Return all query matches within a block list
|
-all Return all query matches within a block list
|
||||||
-h, --help Show this help dialog"
|
-h, --help Show this help dialog"
|
||||||
|
@ -64,7 +62,6 @@ fi
|
||||||
if [[ "${options}" == *"-bp"* ]]; then
|
if [[ "${options}" == *"-bp"* ]]; then
|
||||||
exact="exact"; blockpage=true
|
exact="exact"; blockpage=true
|
||||||
else
|
else
|
||||||
[[ "${options}" == *"-adlist"* ]] && adlist=true
|
|
||||||
[[ "${options}" == *"-all"* ]] && all=true
|
[[ "${options}" == *"-all"* ]] && all=true
|
||||||
if [[ "${options}" == *"-exact"* ]]; then
|
if [[ "${options}" == *"-exact"* ]]; then
|
||||||
exact="exact"; matchType="exact ${matchType}"
|
exact="exact"; matchType="exact ${matchType}"
|
||||||
|
@ -90,7 +87,7 @@ if [[ -n "${str:-}" ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
scanDatabaseTable() {
|
scanDatabaseTable() {
|
||||||
local domain table type querystr result
|
local domain table type querystr result extra
|
||||||
domain="$(printf "%q" "${1}")"
|
domain="$(printf "%q" "${1}")"
|
||||||
table="${2}"
|
table="${2}"
|
||||||
type="${3:-}"
|
type="${3:-}"
|
||||||
|
@ -99,10 +96,17 @@ scanDatabaseTable() {
|
||||||
# Underscores are SQLite wildcards matching exactly one character. We obviously want to suppress this
|
# Underscores are SQLite wildcards matching exactly one character. We obviously want to suppress this
|
||||||
# behavior. The "ESCAPE '\'" clause specifies that an underscore preceded by an '\' should be matched
|
# behavior. The "ESCAPE '\'" clause specifies that an underscore preceded by an '\' should be matched
|
||||||
# as a literal underscore character. We pretreat the $domain variable accordingly to escape underscores.
|
# as a literal underscore character. We pretreat the $domain variable accordingly to escape underscores.
|
||||||
case "${type}" in
|
if [[ "${table}" == "gravity" ]]; then
|
||||||
"exact" ) querystr="SELECT domain FROM vw_${table} WHERE domain = '${domain}'";;
|
case "${exact}" in
|
||||||
* ) querystr="SELECT domain FROM vw_${table} WHERE domain LIKE '%${domain//_/\\_}%' ESCAPE '\\'";;
|
"exact" ) querystr="SELECT gravity.domain,adlist.address,adlist.enabled FROM gravity LEFT JOIN adlist ON adlist.id = gravity.adlist_id WHERE domain = '${domain}'";;
|
||||||
|
* ) querystr="SELECT gravity.domain,adlist.address,adlist.enabled FROM gravity LEFT JOIN adlist ON adlist.id = gravity.adlist_id WHERE domain LIKE '%${domain//_/\\_}%' ESCAPE '\\'";;
|
||||||
esac
|
esac
|
||||||
|
else
|
||||||
|
case "${exact}" in
|
||||||
|
"exact" ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${type}' AND domain = '${domain}'";;
|
||||||
|
* ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${type}' AND domain LIKE '%${domain//_/\\_}%' ESCAPE '\\'";;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
# Send prepared query to gravity database
|
# Send prepared query to gravity database
|
||||||
result="$(sqlite3 "${gravityDBfile}" "${querystr}")" 2> /dev/null
|
result="$(sqlite3 "${gravityDBfile}" "${querystr}")" 2> /dev/null
|
||||||
|
@ -111,12 +115,17 @@ scanDatabaseTable() {
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "${table}" == "gravity" ]]; then
|
||||||
|
echo "${result}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
# Mark domain as having been white-/blacklist matched (global variable)
|
# Mark domain as having been white-/blacklist matched (global variable)
|
||||||
wbMatch=true
|
wbMatch=true
|
||||||
|
|
||||||
# Print table name
|
# Print table name
|
||||||
if [[ -z "${blockpage}" ]]; then
|
if [[ -z "${blockpage}" ]]; then
|
||||||
echo " ${matchType^} found in ${COL_BOLD}${table^}${COL_NC}"
|
echo " ${matchType^} found in ${COL_BOLD}exact ${table}${COL_NC}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Loop over results and print them
|
# Loop over results and print them
|
||||||
|
@ -126,7 +135,13 @@ scanDatabaseTable() {
|
||||||
echo "π ${result}"
|
echo "π ${result}"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
echo " ${result}"
|
domain="${result/|*}"
|
||||||
|
if [[ "${result#*|}" == "0" ]]; then
|
||||||
|
extra=" (disabled)"
|
||||||
|
else
|
||||||
|
extra=""
|
||||||
|
fi
|
||||||
|
echo " ${domain}${extra}"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,9 +149,10 @@ scanRegexDatabaseTable() {
|
||||||
local domain list
|
local domain list
|
||||||
domain="${1}"
|
domain="${1}"
|
||||||
list="${2}"
|
list="${2}"
|
||||||
|
type="${3:-}"
|
||||||
|
|
||||||
# Query all regex from the corresponding database tables
|
# Query all regex from the corresponding database tables
|
||||||
mapfile -t regexList < <(sqlite3 "${gravityDBfile}" "SELECT domain FROM vw_regex_${list}" 2> /dev/null)
|
mapfile -t regexList < <(sqlite3 "${gravityDBfile}" "SELECT domain FROM domainlist WHERE type = ${type}" 2> /dev/null)
|
||||||
|
|
||||||
# If we have regexps to process
|
# If we have regexps to process
|
||||||
if [[ "${#regexList[@]}" -ne 0 ]]; then
|
if [[ "${#regexList[@]}" -ne 0 ]]; then
|
||||||
|
@ -149,7 +165,7 @@ scanRegexDatabaseTable() {
|
||||||
# Split matching regexps over a new line
|
# Split matching regexps over a new line
|
||||||
str_regexMatches=$(printf '%s\n' "${regexMatches[@]}")
|
str_regexMatches=$(printf '%s\n' "${regexMatches[@]}")
|
||||||
# Form a "matched" message
|
# Form a "matched" message
|
||||||
str_message="${matchType^} found in ${COL_BOLD}Regex ${list}${COL_NC}"
|
str_message="${matchType^} found in ${COL_BOLD}regex ${list}${COL_NC}"
|
||||||
# Form a "results" message
|
# Form a "results" message
|
||||||
str_result="${COL_BOLD}${str_regexMatches}${COL_NC}"
|
str_result="${COL_BOLD}${str_regexMatches}${COL_NC}"
|
||||||
# If we are displaying more than just the source of the block
|
# If we are displaying more than just the source of the block
|
||||||
|
@ -170,32 +186,15 @@ scanRegexDatabaseTable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Scan Whitelist and Blacklist
|
# Scan Whitelist and Blacklist
|
||||||
scanDatabaseTable "${domainQuery}" "whitelist" "${exact}"
|
scanDatabaseTable "${domainQuery}" "whitelist" "0"
|
||||||
scanDatabaseTable "${domainQuery}" "blacklist" "${exact}"
|
scanDatabaseTable "${domainQuery}" "blacklist" "1"
|
||||||
|
|
||||||
# Scan Regex table
|
# Scan Regex table
|
||||||
scanRegexDatabaseTable "${domainQuery}" "whitelist"
|
scanRegexDatabaseTable "${domainQuery}" "whitelist" "2"
|
||||||
scanRegexDatabaseTable "${domainQuery}" "blacklist"
|
scanRegexDatabaseTable "${domainQuery}" "blacklist" "3"
|
||||||
|
|
||||||
# Get version sorted *.domains filenames (without dir path)
|
# Query block lists
|
||||||
lists=("$(cd "$piholeDir" || exit 0; printf "%s\\n" -- *.domains | sort -V)")
|
mapfile -t results <<< "$(scanDatabaseTable "${domainQuery}" "gravity")"
|
||||||
|
|
||||||
# Query blocklists for occurences of domain
|
|
||||||
mapfile -t results <<< "$(scanList "${domainQuery}" "${lists[*]}" "${exact}")"
|
|
||||||
|
|
||||||
# Remove unwanted content from $results
|
|
||||||
# Each line in $results is formatted as such: [fileName]:[line]
|
|
||||||
# 1. Delete lines starting with #
|
|
||||||
# 2. Remove comments after domain
|
|
||||||
# 3. Remove hosts format IP address
|
|
||||||
# 4. Remove any lines that no longer contain the queried domain name (in case the matched domain name was in a comment)
|
|
||||||
esc_domain="${domainQuery//./\\.}"
|
|
||||||
mapfile -t results <<< "$(IFS=$'\n'; sed \
|
|
||||||
-e "/:#/d" \
|
|
||||||
-e "s/[ \\t]#.*//g" \
|
|
||||||
-e "s/:.*[ \\t]/:/g" \
|
|
||||||
-e "/${esc_domain}/!d" \
|
|
||||||
<<< "${results[*]}")"
|
|
||||||
|
|
||||||
# Handle notices
|
# Handle notices
|
||||||
if [[ -z "${wbMatch:-}" ]] && [[ -z "${wcMatch:-}" ]] && [[ -z "${results[*]}" ]]; then
|
if [[ -z "${wbMatch:-}" ]] && [[ -z "${wcMatch:-}" ]] && [[ -z "${results[*]}" ]]; then
|
||||||
|
@ -210,12 +209,6 @@ elif [[ -z "${all}" ]] && [[ "${#results[*]}" -ge 100 ]]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get adlist file content as array
|
|
||||||
if [[ -n "${adlist}" ]] || [[ -n "${blockpage}" ]]; then
|
|
||||||
# Retrieve source URLs from gravity database
|
|
||||||
mapfile -t adlists <<< "$(sqlite3 "${gravityDBfile}" "SELECT address FROM vw_adlist;" 2> /dev/null)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Print "Exact matches for" title
|
# Print "Exact matches for" title
|
||||||
if [[ -n "${exact}" ]] && [[ -z "${blockpage}" ]]; then
|
if [[ -n "${exact}" ]] && [[ -z "${blockpage}" ]]; then
|
||||||
plural=""; [[ "${#results[*]}" -gt 1 ]] && plural="es"
|
plural=""; [[ "${#results[*]}" -gt 1 ]] && plural="es"
|
||||||
|
@ -223,28 +216,25 @@ if [[ -n "${exact}" ]] && [[ -z "${blockpage}" ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for result in "${results[@]}"; do
|
for result in "${results[@]}"; do
|
||||||
fileName="${result/:*/}"
|
match="${result/|*/}"
|
||||||
|
extra="${result#*|}"
|
||||||
# Determine *.domains URL using filename's number
|
adlistAddress="${extra/|*/}"
|
||||||
if [[ -n "${adlist}" ]] || [[ -n "${blockpage}" ]]; then
|
extra="${extra#*|}"
|
||||||
fileNum="${fileName/list./}"; fileNum="${fileNum%%.*}"
|
if [[ "${extra}" == "0" ]]; then
|
||||||
fileName="${adlists[$fileNum]}"
|
extra="(disabled)"
|
||||||
|
else
|
||||||
# Discrepency occurs when adlists has been modified, but Gravity has not been run
|
extra=""
|
||||||
if [[ -z "${fileName}" ]]; then
|
|
||||||
fileName="${COL_LIGHT_RED}(no associated adlists URL found)${COL_NC}"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "${blockpage}" ]]; then
|
if [[ -n "${blockpage}" ]]; then
|
||||||
echo "${fileNum} ${fileName}"
|
echo "0 ${adlistAddress}"
|
||||||
elif [[ -n "${exact}" ]]; then
|
elif [[ -n "${exact}" ]]; then
|
||||||
echo " ${fileName}"
|
echo " - ${adlistAddress} ${extra}"
|
||||||
else
|
else
|
||||||
if [[ ! "${fileName}" == "${fileName_prev:-}" ]]; then
|
if [[ ! "${adlistAddress}" == "${adlistAddress_prev:-}" ]]; then
|
||||||
count=""
|
count=""
|
||||||
echo " ${matchType^} found in ${COL_BOLD}${fileName}${COL_NC}:"
|
echo " ${matchType^} found in ${COL_BOLD}${adlistAddress}${COL_NC}:"
|
||||||
fileName_prev="${fileName}"
|
adlistAddress_prev="${adlistAddress}"
|
||||||
fi
|
fi
|
||||||
: $((count++))
|
: $((count++))
|
||||||
|
|
||||||
|
@ -254,7 +244,7 @@ for result in "${results[@]}"; do
|
||||||
[[ "${count}" -gt "${max_count}" ]] && continue
|
[[ "${count}" -gt "${max_count}" ]] && continue
|
||||||
echo " ${COL_GRAY}Over ${count} results found, skipping rest of file${COL_NC}"
|
echo " ${COL_GRAY}Over ${count} results found, skipping rest of file${COL_NC}"
|
||||||
else
|
else
|
||||||
echo " ${result#*:}"
|
echo " ${match} ${extra}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
Loading…
Reference in New Issue