diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 04303614..6f277b21 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,7 +1,33 @@ -##### Expected Behaviour: +**In raising this issue, I confirm the following (please check boxes, eg [X] - no spaces) Failure to fill the template will close your issue:** + +- [] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md). +- [] The issue I am reporting can be *replicated* +- [] The issue I'm reporting isn't a duplicate (see [FAQs](https://github.com/pi-hole/pi-hole/wiki/FAQs), [closed issues](https://github.com/pi-hole/pi-hole/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), and [open issues](https://github.com/pi-hole/pi-hole/issues)). + +**How familiar are you with the codebase?:** + +_{replace this text with a number from 1 to 10, with 1 being not familiar, and 10 being very familiar}_ + +--- +**[FEATURE REQUEST | QUESTION | OTHER]:** + +Please [submit your feature request here](https://discourse.pi-hole.net/c/feature-requests), so it is votable by the community. It's also easier for us to track. + +**[BUG | ISSUE] Expected Behaviour:** -##### Actual Behaviour: +**[BUG | ISSUE] Actual Behaviour:** -##### Steps to reproduce this issue: +**[BUG | ISSUE] Steps to reproduce:** + +- +- +- +- + +**(Optional) Debug token generated by `pihole -d`:** + +`` + +_This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._ diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 047c8b05..2c391428 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,11 +1,19 @@ -Fixes #[issue number] . +**By submitting this pull request, I confirm the following (please check boxes, eg [X] - no spaces) _Failure to fill the template will close your PR_:** -Changes proposed in this pull request: +***Please submit all pull requests against the `development` branch. Failure to do so will delay or deny your request*** -- +- [] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md). +- [] I have checked that [another pull request](https://github.com/pi-hole/pi-hole/pulls) for this purpose does not exist. +- [] I have considered, and confirmed that this submission will be valuable to others. +- [] I accept that this submission may not be used, and the pull request closed at the will of the maintainer. +- [] I give this submission freely, and claim no ownership to its content. -- +**How familiar are you with the codebase?:** -- +_{replace this text with a number from 1 to 10, with 1 being not familiar, and 10 being very familiar}_ -@pi-hole/dashboard +--- +_{replace this line with your pull request content}_ + + +_This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._ diff --git a/.user.php.ini b/.user.php.ini new file mode 100644 index 00000000..7660f85a --- /dev/null +++ b/.user.php.ini @@ -0,0 +1,2 @@ +memory_limit = 256M +max_execution_time = 300 diff --git a/api.php b/api.php index aa47b530..6a22a5a2 100644 --- a/api.php +++ b/api.php @@ -70,7 +70,16 @@ } elseif (isset($_GET['disable'], $_GET['token']) && $auth) { check_csrf($_GET['token']); - exec('sudo pihole disable'); + $disable = intval($_GET['disable']); + // intval returns the integer value on success, or 0 on failure + if($disable > 0) + { + exec("sudo pihole disable ".$disable."s"); + } + else + { + exec('sudo pihole disable'); + } $data = array_merge($data, Array( "status" => "disabled" )); @@ -80,6 +89,10 @@ $data = array_merge($data, getGravity()); } + if (isset($_GET['tailLog'])) { + $data = array_merge($data, tailPiholeLog($_GET['tailLog'])); + } + function filterArray(&$inArray) { $outArray = array(); foreach ($inArray as $key=>$value) { diff --git a/index.php b/index.php index 8c562022..0651a645 100644 --- a/index.php +++ b/index.php @@ -4,7 +4,7 @@ ?>
-
+
@@ -17,7 +17,7 @@
-
+
@@ -30,7 +30,7 @@
-
+
@@ -43,11 +43,11 @@
-
+
-

---

+

---

Domains Being Blocked

diff --git a/js/pihole/taillog.js b/js/pihole/taillog.js new file mode 100644 index 00000000..00cbfb15 --- /dev/null +++ b/js/pihole/taillog.js @@ -0,0 +1,40 @@ +var offset, timer, pre, scrolling = true; + +// Check every 200msec for fresh data +var interval = 200; + +// Function that asks the API for new data +function reloadData(){ + clearTimeout(timer); + $.getJSON("api.php?tailLog="+offset, function (data) + { + offset = data["offset"]; + pre.append(data["lines"]); + }); + + if(scrolling) + { + window.scrollTo(0,document.body.scrollHeight); + } + timer = setTimeout(reloadData, interval); +} + +$(function(){ + // Get offset at first loading of page + $.getJSON("api.php?tailLog", function (data) + { + offset = data["offset"]; + }); + pre = $("#output"); + // Trigger function that looks for new data + reloadData(); +}); + +$("#chk1").click(function() { + $("#chk2").prop("checked",this.checked); + scrolling = this.checked; +}); +$("#chk2").click(function() { + $("#chk1").prop("checked",this.checked); + scrolling = this.checked; +}); diff --git a/queries.php b/queries.php index 13489a4e..30fe7b3b 100644 --- a/queries.php +++ b/queries.php @@ -29,6 +29,14 @@ if(isset($setupVars["API_QUERY_LOG_SHOW"])) } } +if(isset($setupVars["API_PRIVACY_MODE"])) +{ + if($setupVars["API_PRIVACY_MODE"]) + { + // Overwrite string from above + $showing = "(privacy mode enabled)"; + } +} ?> diff --git a/scripts/pi-hole/js/footer.js b/scripts/pi-hole/js/footer.js index 57659dbc..b9029236 100644 --- a/scripts/pi-hole/js/footer.js +++ b/scripts/pi-hole/js/footer.js @@ -8,34 +8,82 @@ $("body").on("click", function(event) { } }); -// Enable/Disable -$("#flip-status").on("click", (e) => { - e.preventDefault(); - const btnStatus = $("#flip-status"); +function piholeChanged(action) +{ const status = $("#status"); - const text = btnStatus.text().trim(); - const token = encodeURIComponent($("#token").html()); + const ena = $("#pihole-enable"); + const dis = $("#pihole-disable"); - switch(text) { - case "Enable": - btnStatus.html(" Enabling..."); - $.getJSON("api.php?enable&token=" + token, (data) => { - if(data.status === "enabled") { - btnStatus.html(" Disable"); - status.html(" Active"); - } - }); - break; - case "Disable": - btnStatus.html(" Disabling..."); - $.getJSON("api.php?disable&token=" + token, (data) => { - if(data.status === "disabled") { - btnStatus.html(" Enable"); - status.html(" Offline"); - } - }); - break; + switch(action) { + case "enabled": + status.html(" Active"); + ena.hide(); + dis.show(); + dis.removeClass("active"); + break; + + case "disabled": + status.html(" Offline"); + ena.show(); + dis.hide(); + break; } + +} + +function piholeChange(action, duration) +{ + const token = encodeURIComponent($("#token").html()); + var btnStatus; + + switch(action) { + case "enable": + btnStatus = $("#flip-status-enable"); + btnStatus.html(" "); + $.getJSON("api.php?enable&token=" + token, (data) => { + if(data.status === "enabled") { + btnStatus.html(""); + piholeChanged("enabled"); + } + }); + break; + + case "disable": + btnStatus = $("#flip-status-disable"); + btnStatus.html(" "); + $.getJSON("api.php?disable=" + duration + "&token=" + token, (data) => { + if(data.status === "disabled") { + btnStatus.html(""); + piholeChanged("disabled"); + } + }); + break; + } +} + +// Handle Enable/Disable +$("#pihole-enable").on("click", (e) => { + e.preventDefault(); + piholeChange("enable",""); +}); +$("#pihole-disable-permanently").on("click", (e) => { + e.preventDefault(); + piholeChange("disable","0"); +}); +$("#pihole-disable-10s").on("click", (e) => { + e.preventDefault(); + piholeChange("disable","10"); + setTimeout(function(){piholeChanged("enabled");},10000); +}); +$("#pihole-disable-30s").on("click", (e) => { + e.preventDefault(); + piholeChange("disable","30"); + setTimeout(function(){piholeChanged("enabled");},30000); +}); +$("#pihole-disable-5m").on("click", (e) => { + e.preventDefault(); + piholeChange("disable","300"); + setTimeout(function(){piholeChanged("enabled");},300000); }); var piholeVersion = $("#piholeVersion").html(); diff --git a/scripts/pi-hole/js/index.js b/scripts/pi-hole/js/index.js index 7bdc39f1..26a5ca72 100644 --- a/scripts/pi-hole/js/index.js +++ b/scripts/pi-hole/js/index.js @@ -132,14 +132,22 @@ function escapeHtml(text) { function updateTopClientsChart() { $.getJSON("api.php?summaryRaw&getQuerySources", function(data) { var clienttable = $("#client-frequency").find("tbody:last"); - var domain, percentage; + var domain, percentage, domainname; for (domain in data.top_sources) { if ({}.hasOwnProperty.call(data.top_sources, domain)){ // Sanitize domain domain = escapeHtml(domain); + if(domain.indexOf("|") > -1) + { + domainname = domain.substr(0, domain.indexOf("|")); + } + else + { + domainname = domain; + } - var url = ""+domain+""; + var url = ""+domainname+""; percentage = data.top_sources[domain] / data.dns_queries_today * 100; clienttable.append(" " + url + " " + data.top_sources[domain] + "
-1) + { + key = key.substr(0, key.indexOf("|")); + } forwardDestinationChart.data.labels.push(key); }); // Build a single dataset with the data to be pushed @@ -180,7 +192,6 @@ function updateTopLists() { var domaintable = $("#domain-frequency").find("tbody:last"); var adtable = $("#ad-frequency").find("tbody:last"); var url, domain, percentage; - for (domain in data.top_queries) { if ({}.hasOwnProperty.call(data.top_queries,domain)){ // Sanitize domain @@ -198,8 +209,14 @@ function updateTopLists() { " " + data.top_queries[domain] + "
"); } - } + + // Remove table if there are no results (e.g. privacy mode enabled) + if(jQuery.isEmptyObject(data.top_queries)) + { + $("#domain-frequency").parent().remove(); + } + for (domain in data.top_ads) { if ({}.hasOwnProperty.call(data.top_ads,domain)){ // Sanitize domain diff --git a/scripts/pi-hole/js/queryads.js b/scripts/pi-hole/js/queryads.js index 7058d305..e8b91be4 100644 --- a/scripts/pi-hole/js/queryads.js +++ b/scripts/pi-hole/js/queryads.js @@ -16,7 +16,7 @@ function eventsource() { } var host = window.location.host; - var source = new EventSource("http://"+host+"/admin/scripts/pi-hole/php/queryads.php?domain="+domain.val()+"&"+exact); + var source = new EventSource("http://"+host+"/admin/php/queryads.php?domain="+domain.val().toLowerCase()+"&"+exact); // Reset and show field ta.empty(); diff --git a/scripts/pi-hole/php/auth.php b/scripts/pi-hole/php/auth.php index 1c8a4fe2..d2345ca4 100644 --- a/scripts/pi-hole/php/auth.php +++ b/scripts/pi-hole/php/auth.php @@ -20,26 +20,42 @@ function check_cors() { // Check CORS $AUTHORIZED_HOSTNAMES = array( - 'http://' . $ipv4, - 'http://' . $_SERVER['SERVER_NAME'], - 'http://pi.hole', - 'http://localhost' + $ipv4, + $_SERVER["SERVER_NAME"], + "pi.hole", + "localhost" ); # Allow user set virtual hostnames $virtual_host = getenv('VIRTUAL_HOST'); if (! empty($virtual_host)) - array_push($AUTHORIZED_HOSTNAMES, 'http://' . $virtual_host); + array_push($AUTHORIZED_HOSTNAMES, $virtual_host); // Since the Host header is easily manipulated, we can only check if it's wrong and can't use it // to validate that the client is authorized, only unauthorized. - if(isset($_SERVER['HTTP_HOST']) && !in_array("http://".$_SERVER['HTTP_HOST'], $AUTHORIZED_HOSTNAMES)) { - log_and_die("Failed Host Check: " . $_SERVER['HTTP_HOST'] .' vs '. join(', ', $AUTHORIZED_HOSTNAMES)); + $server_host = $_SERVER['HTTP_HOST']; + + // If HTTP_HOST contains a non-standard port (!= 80) we have to strip the port + if(strpos($server_host, ":")) + { + $server_host = parse_url($_SERVER['HTTP_HOST'], PHP_URL_HOST); + } + + if(isset($_SERVER['HTTP_HOST']) && !in_array($server_host, $AUTHORIZED_HOSTNAMES)) { + log_and_die("Failed Host Check: " . $server_host .' vs '. join(', ', $AUTHORIZED_HOSTNAMES)); } if(isset($_SERVER['HTTP_ORIGIN'])) { - if(!in_array($_SERVER['HTTP_ORIGIN'], $AUTHORIZED_HOSTNAMES)) { - log_and_die("Failed CORS: " . $_SERVER['HTTP_ORIGIN'] .' vs '. join(', ', $AUTHORIZED_HOSTNAMES)); + $server_origin = $_SERVER['HTTP_ORIGIN']; + + // If HTTP_ORIGIN contains a non-standard port (!= 80) we have to strip the port + if(strpos($server_origin, ":")) + { + $server_origin = parse_url($_SERVER['HTTP_ORIGIN'], PHP_URL_HOST); + } + + if(!in_array($server_origin, $AUTHORIZED_HOSTNAMES)) { + log_and_die("Failed CORS: " . $server_origin .' vs '. join(', ', $AUTHORIZED_HOSTNAMES)); } header("Access-Control-Allow-Origin: ${_SERVER['HTTP_ORIGIN']}"); } diff --git a/scripts/pi-hole/php/data.php b/scripts/pi-hole/php/data.php index 711f599c..ad24e57e 100644 --- a/scripts/pi-hole/php/data.php +++ b/scripts/pi-hole/php/data.php @@ -20,6 +20,15 @@ $blackListFile = checkfile("/etc/pihole/blacklist.txt"); $blacklist = new \SplFileObject($blackListFile); + if(isset($setupVars["API_PRIVACY_MODE"])) + { + $privacyMode = $setupVars["API_PRIVACY_MODE"]; + } + else + { + $privacyMode = false; + } + /******* Public Members ********/ function getSummaryData() { $domains_being_blocked = gravityCount(); @@ -45,6 +54,14 @@ $domains_over_time = overTime($dns_queries); $ads_over_time = overTime($ads_blocked); + + // Provide a minimal valid array if there have are no blocked + // queries at all. Otherwise the output of the API is inconsistent. + if(count($ads_blocked) == 0) + { + $ads_over_time = [1 => 0]; + } + alignTimeArrays($ads_over_time, $domains_over_time); return Array( 'domains_over_time' => $domains_over_time, @@ -59,6 +76,14 @@ $domains_over_time = overTime10mins($dns_queries); $ads_over_time = overTime10mins($ads_blocked); + + // Provide a minimal valid array if there have are no blocked + // queries at all. Otherwise the output of the API is inconsistent. + if(count($ads_blocked) == 0) + { + $ads_over_time = [1 => 0]; + } + alignTimeArrays($ads_over_time, $domains_over_time); return Array( 'domains_over_time' => $domains_over_time, @@ -67,12 +92,19 @@ } function getTopItems() { - global $log; + global $log,$privacyMode; $dns_queries = getDnsQueries($log); $ads_blocked = getBlockedQueries($log); $topAds = topItems($ads_blocked); - $topQueries = topItems($dns_queries, $topAds); + if(!$privacyMode) + { + $topQueries = topItems($dns_queries, $topAds); + } + else + { + $topQueries = []; + } return Array( 'top_queries' => $topQueries, @@ -107,13 +139,36 @@ return $queryTypes; } + function resolveIPs(&$array) { + $hostarray = []; + foreach ($array as $key => $value) + { + $hostname = gethostbyaddr($key); + // If we found a hostname for the IP, replace it + if($hostname) + { + // Generate HOST entry + $hostarray["$hostname|$key"] = $value; + } + else + { + // Generate IP entry + $hostarray[$key] = $value; + } + } + $array = $hostarray; + + // Sort new array + arsort($array); + } + function getForwardDestinations() { - global $log; + global $log, $setupVars; $forwards = getForwards($log); $destinations = array(); foreach ($forwards as $forward) { $exploded = explode(" ", trim($forward)); - $dest = hasHostName($exploded[count($exploded) - 1]); + $dest = $exploded[count($exploded) - 1]; if (isset($destinations[$dest])) { $destinations[$dest]++; } @@ -122,17 +177,36 @@ } } + if(istrue($setupVars["API_GET_UPSTREAM_DNS_HOSTNAME"])) + { + resolveIPs($destinations); + } + return $destinations; } + // Check for existance of variable + // and test it only if it exists + function istrue(&$argument) { + $ret = false; + if(isset($argument)) + { + if($argument) + { + $ret = true; + } + } + return $ret; + } + function getQuerySources() { - global $log; + global $log, $setupVars; $dns_queries = getDnsQueries($log); $sources = array(); foreach($dns_queries as $query) { $exploded = explode(" ", $query); - $ip = hasHostName(trim($exploded[count($exploded)-1])); + $ip = trim($exploded[count($exploded)-1]); if (isset($sources[$ip])) { $sources[$ip]++; } @@ -149,6 +223,12 @@ arsort($sources); $sources = array_slice($sources, 0, 10); + + if(istrue($setupVars["API_GET_CLIENT_HOSTNAME"])) + { + resolveIPs($sources); + } + return Array( 'top_sources' => $sources ); @@ -197,57 +277,93 @@ } function getAllQueries($orderBy) { - global $log,$showBlocked,$showPermitted; + global $log,$showBlocked,$showPermitted,$privacyMode; $allQueries = array("data" => array()); - $dns_queries = getDnsQueriesAll($log); + $dns_queries = getDnsQueries($log); // Create empty array for gravity $gravity_domains = getGravity(); + setShowBlockedPermitted(); + + // Privacy mode? + if($privacyMode) + { + $showPermitted = false; + } + + if(!$showBlocked && !$showPermitted) + { + // Nothing to do for us here + return []; + } + foreach ($dns_queries as $query) { $time = date_create(substr($query, 0, 16)); $exploded = explode(" ", trim($query)); $domain = $exploded[count($exploded)-3]; $tmp = $exploded[count($exploded)-4]; - setShowBlockedPermitted(); - - if (substr($tmp, 0, 5) == "query") + $status = isset($gravity_domains[$domain]) ? "Pi-holed" : "OK"; + if(($status === "Pi-holed" && $showBlocked) || ($status === "OK" && $showPermitted)) { - $status = isset($gravity_domains[$domain]) ? "Pi-holed" : "OK"; - if(($status === "Pi-holed" && $showBlocked) || ($status === "OK" && $showPermitted)) - { - $type = substr($exploded[count($exploded)-4], 6, -1); - $client = $exploded[count($exploded)-1]; + $type = substr($exploded[count($exploded)-4], 6, -1); + $client = $exploded[count($exploded)-1]; - if($orderBy == "orderByClientDomainTime"){ - $allQueries['data'][hasHostName($client)][$domain][$time->format('Y-m-d\TH:i:s')] = $status; - }elseif ($orderBy == "orderByClientTimeDomain"){ - $allQueries['data'][hasHostName($client)][$time->format('Y-m-d\TH:i:s')][$domain] = $status; - }elseif ($orderBy == "orderByTimeClientDomain"){ - $allQueries['data'][$time->format('Y-m-d\TH:i:s')][hasHostName($client)][$domain] = $status; - }elseif ($orderBy == "orderByTimeDomainClient"){ - $allQueries['data'][$time->format('Y-m-d\TH:i:s')][$domain][hasHostName($client)] = $status; - }elseif ($orderBy == "orderByDomainClientTime"){ - $allQueries['data'][$domain][hasHostName($client)][$time->format('Y-m-d\TH:i:s')] = $status; - }elseif ($orderBy == "orderByDomainTimeClient"){ - $allQueries['data'][$domain][$time->format('Y-m-d\TH:i:s')][hasHostName($client)] = $status; - }else{ - array_push($allQueries['data'], array( - $time->format('Y-m-d\TH:i:s'), - $type, - $domain, - hasHostName($client), - $status, - "" - )); - } + if($orderBy == "orderByClientDomainTime"){ + $allQueries['data'][hasHostName($client)][$domain][$time->format('Y-m-d\TH:i:s')] = $status; + }elseif ($orderBy == "orderByClientTimeDomain"){ + $allQueries['data'][hasHostName($client)][$time->format('Y-m-d\TH:i:s')][$domain] = $status; + }elseif ($orderBy == "orderByTimeClientDomain"){ + $allQueries['data'][$time->format('Y-m-d\TH:i:s')][hasHostName($client)][$domain] = $status; + }elseif ($orderBy == "orderByTimeDomainClient"){ + $allQueries['data'][$time->format('Y-m-d\TH:i:s')][$domain][hasHostName($client)] = $status; + }elseif ($orderBy == "orderByDomainClientTime"){ + $allQueries['data'][$domain][hasHostName($client)][$time->format('Y-m-d\TH:i:s')] = $status; + }elseif ($orderBy == "orderByDomainTimeClient"){ + $allQueries['data'][$domain][$time->format('Y-m-d\TH:i:s')][hasHostName($client)] = $status; + }else{ + array_push($allQueries['data'], array( + $time->format('Y-m-d\TH:i:s'), + $type, + $domain, + hasHostName($client), + $status, + "" + )); } } } return $allQueries; } + function tailPiholeLog($param) { + // Not using SplFileObject here, since direct + // usage of f-streams will be much faster for + // files as large as the pihole.log + global $logListName; + $file = fopen($logListName,"r"); + $offset = intval($param); + if($offset > 0) + { + // Seeks on the file pointer where we want to continue reading is known + fseek($file, $offset); + $lines = []; + while (!feof($file)) { + array_push($lines,fgets($file)); + } + return ["offset" => ftell($file), "lines" => $lines]; + } + else + { + // Locate the current position of the file read/write pointer + fseek($file, -1, SEEK_END); + // Add one to skip the very last "\n" in the log file + return ["offset" => ftell($file)+1]; + } + fclose($file); + } + /******** Private Members ********/ function gravityCount() { global $gravityListName,$blackListFile; @@ -260,7 +376,7 @@ $log->rewind(); $lines = []; foreach ($log as $line) { - if(strpos($line, ": query[") !== false) { + if(strpos($line, ": query[A") !== false) { $lines[] = $line; } } @@ -269,14 +385,14 @@ function countDnsQueries() { global $logListName; - return exec("grep -c \": query\\[\" $logListName"); + return exec("grep -c \": query\\[A\" $logListName"); } function getDnsQueriesAll(\SplFileObject $log) { $log->rewind(); $lines = []; foreach ($log as $line) { - if(strpos($line, ": query[") || strpos($line, "gravity.list") || strpos($line, ": forwarded") !== false) { + if(strpos($line, ": query[A") || strpos($line, "gravity.list") || strpos($line, ": forwarded") !== false) { $lines[] = $line; } } @@ -323,16 +439,39 @@ function getBlockedQueries(\SplFileObject $log) { $log->rewind(); $lines = []; - $hostname = trim(file_get_contents("/etc/hostname"), "\x00..\x1F"); foreach ($log as $line) { - $line = preg_replace('/ {2,}/', ' ', $line); $exploded = explode(" ", $line); - if(count($exploded) == 8) { - $tmp = $exploded[count($exploded) - 4]; - $tmp2 = $exploded[count($exploded) - 5]; - $tmp3 = $exploded[count($exploded) - 3]; - //filter out bad names and host file reloads: - if(substr($tmp, strlen($tmp) - 12, 12) == "gravity.list" && $tmp2 != "read" && $tmp3 != "pi.hole" && $tmp3 != $hostname) { + if(count($exploded) == 8 || count($exploded) == 10) { + // Structure of data is currently like: + // Array + // ( + // [0] => Dec + // [1] => 19 + // [2] => 11:21:51 + // [3] => dnsmasq[2584]: + // [4] => /etc/pihole/gravity.list + // [5] => doubleclick.com + // [6] => is + // [7] => ip.of.pi.hole + // ) + // with extra logging enabled + // Array + // ( + // [0] => Dec + // [1] => 19 + // [2] => 11:21:51 + // [3] => dnsmasq[2584]: + // [4] => 1 (identifier) + // [5] => 1.2.3.4/12345 + // [6] => /etc/pihole/gravity.list + // [7] => doubleclick.com + // [8] => is + // [9] => ip.of.pi.hole + // ) + $list = $exploded[count($exploded)-4]; + $is = $exploded[count($exploded)-2]; + // Consider only gravity.list as DNS source (not e.g. hostname.list) + if(substr($list, strlen($list) - 12, 12) === "gravity.list" && $is === "is") { $lines[] = $line; }; } @@ -342,8 +481,7 @@ function countBlockedQueries() { global $logListName; - $hostname = trim(file_get_contents("/etc/hostname"), "\x00..\x1F"); - return exec("grep \"gravity.list\" $logListName | grep -v \"pi.hole\" | grep -v \" read \" | grep -v -c \"".$hostname."\""); + return exec("grep \"gravity.list\" $logListName | grep -c \" is \""); } function getForwards(\SplFileObject $log) { diff --git a/scripts/pi-hole/php/header.php b/scripts/pi-hole/php/header.php index 0db12917..6811bde3 100644 --- a/scripts/pi-hole/php/header.php +++ b/scripts/pi-hole/php/header.php @@ -21,7 +21,16 @@ // Test if we succeeded in getting the temperature if(is_numeric($output)) { - $celsius = intVal($output)*1e-3; + // $output could be either 4-5 digits or 2-3, and we only divide by 1000 if it's 4-5 + // ex. 39007 vs 39 + $celsius = intVal($output); + + // If celsius is greater than 1 degree and is in the 4-5 digit format + if($celsius > 1000) { + // Use multiplication to get around the division-by-zero error + $celsius *= 1e-3; + } + $kelvin = $celsius + 273.15; $fahrenheit = ($celsius*9./5)+32.0; @@ -240,7 +249,7 @@
- Pi-hole logo + Pi-hole logo

Status

@@ -257,7 +266,7 @@ // CPU Temp if ($celsius >= -273.15) { echo " 45) { + if ($celsius > 60) { echo "#FF0000"; } else @@ -314,55 +323,114 @@
+