mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
c498fb9db2
Signed-off-by: DL6ER <dl6er@dl6er.de>
189 lines
4.9 KiB
C
189 lines
4.9 KiB
C
/* Pi-hole: A black hole for Internet advertisements
|
|
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
|
* Network-wide ad blocking via your own hardware.
|
|
*
|
|
* FTL Engine
|
|
* Core routine
|
|
*
|
|
* This file is copyright under the latest version of the EUPL.
|
|
* Please see LICENSE file for your rights under this license. */
|
|
|
|
#include "FTL.h"
|
|
#include "daemon.h"
|
|
#include "log.h"
|
|
#include "setupVars.h"
|
|
#include "args.h"
|
|
#include "config/config.h"
|
|
#include "database/common.h"
|
|
#include "main.h"
|
|
// exit_code
|
|
#include "signals.h"
|
|
#include "regex_r.h"
|
|
// init_shmem()
|
|
#include "shmem.h"
|
|
#include "capabilities.h"
|
|
#include "timers.h"
|
|
#include "procps.h"
|
|
// init_memory_database(), import_queries_from_disk()
|
|
#include "database/query-table.h"
|
|
// init_overtime()
|
|
#include "overTime.h"
|
|
// flush_message_table()
|
|
#include "database/message-table.h"
|
|
|
|
#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
|
|
#pragma message "Minimum GLIBC version: " xstr(__GLIBC__) "." xstr(__GLIBC_MINOR__)
|
|
#else
|
|
#pragma message "Minimum GLIBC version: unknown, assuming this is a MUSL build"
|
|
#endif
|
|
|
|
char *username;
|
|
bool needGC = false;
|
|
bool needDBGC = false;
|
|
bool startup = true;
|
|
jmp_buf exit_jmp;
|
|
|
|
int main (int argc, char *argv[])
|
|
{
|
|
// Get user pihole-FTL is running as
|
|
// We store this in a global variable
|
|
// such that the log routine can access
|
|
// it if needed
|
|
username = getUserName();
|
|
|
|
// Obtain log file location
|
|
getLogFilePath();
|
|
|
|
// Parse arguments
|
|
// We run this also for no direct arguments
|
|
// to have arg{c,v}_dnsmasq initialized
|
|
parse_args(argc, argv);
|
|
|
|
// Initialize FTL log
|
|
init_FTL_log(argc > 0 ? argv[0] : NULL);
|
|
// Try to open FTL log
|
|
init_config_mutex();
|
|
timer_start(EXIT_TIMER);
|
|
log_info("########## FTL started on %s! ##########", hostname());
|
|
log_FTL_version(false);
|
|
|
|
// Catch signals not handled by dnsmasq
|
|
// We configure real-time signals later (after dnsmasq has forked)
|
|
handle_signals();
|
|
|
|
// Process pihole.toml configuration file
|
|
// The file is rewritten after parsing to ensure that all
|
|
// settings are present and have a valid value
|
|
readFTLconf(&config, true);
|
|
|
|
// Set process priority
|
|
set_nice();
|
|
|
|
// Initialize shared memory
|
|
if(!init_shmem())
|
|
{
|
|
log_crit("Initialization of shared memory failed.");
|
|
// Check if there is already a running FTL process
|
|
check_running_FTL();
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// pihole-FTL should really be run as user "pihole" to not mess up with file permissions
|
|
// print warning otherwise
|
|
if(strcmp(username, "pihole") != 0)
|
|
log_warn("Starting pihole-FTL as user %s is not recommended", username);
|
|
|
|
// Write PID early on so systemd cannot be fooled during DELAY_STARTUP
|
|
// times. The PID in this file will later be overwritten after forking
|
|
savepid();
|
|
|
|
// Delay startup (if requested)
|
|
// Do this before reading the database to make this option not only
|
|
// useful for interfaces that aren't ready but also for fake-hwclocks
|
|
// which aren't ready at this point
|
|
delay_startup();
|
|
|
|
// Initialize overTime datastructure
|
|
initOverTime();
|
|
|
|
// Initialize query database (pihole-FTL.db)
|
|
db_init();
|
|
|
|
// Initialize in-memory databases
|
|
if(!init_memory_database())
|
|
{
|
|
log_crit("FATAL: Cannot initialize in-memory database.");
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// Flush messages stored in the long-term database
|
|
flush_message_table();
|
|
|
|
// Try to import queries from long-term database if available
|
|
if(config.database.DBimport.v.b)
|
|
{
|
|
import_queries_from_disk();
|
|
DB_read_queries();
|
|
}
|
|
|
|
// Initialize in-memory database starting index
|
|
update_disk_db_idx();
|
|
|
|
// Log some information about the imported queries (if any)
|
|
log_counter_info();
|
|
|
|
// Check for availability of capabilities in debug mode
|
|
if(config.debug.caps.v.b)
|
|
check_capabilities();
|
|
|
|
// Initialize pseudo-random number generator
|
|
srand(time(NULL));
|
|
|
|
// Start the resolver
|
|
startup = false;
|
|
// Stop writing to STDOUT
|
|
log_ctrl(true, false);
|
|
|
|
// Call embedded dnsmasq only on the first run
|
|
// Skip it here if we jump back to this point from die()
|
|
const int jmpret = setjmp(exit_jmp);
|
|
if(jmpret == 0)
|
|
main_dnsmasq(argc_dnsmasq, (char**)argv_dnsmasq);
|
|
else
|
|
{
|
|
// We are jumping back to this point from dnsmasq's die()
|
|
log_debug(DEBUG_ANY, "Jumped back to main() from dnsmasq/die()");
|
|
dnsmasq_failed = true;
|
|
|
|
if(!resolver_ready)
|
|
{
|
|
// If dnsmasq never finished initializing, we need to
|
|
// launch the threads
|
|
FTL_fork_and_bind_sockets(NULL, false);
|
|
}
|
|
|
|
// Loop here to keep the webserver running unless requested to restart
|
|
while(!FTL_terminate)
|
|
sleepms(100);
|
|
}
|
|
|
|
log_info("Shutting down... // exit code %d // jmpret %d", exit_code, jmpret);
|
|
// Extra grace time is needed as dnsmasq script-helpers and the API may not
|
|
// be terminating immediately
|
|
sleepms(250);
|
|
|
|
// Save new queries to database (if database is used)
|
|
if(config.database.DBexport.v.b)
|
|
{
|
|
export_queries_to_disk(true);
|
|
log_info("Finished final database update");
|
|
}
|
|
|
|
cleanup(exit_code);
|
|
|
|
if(exit_code == RESTART_FTL_CODE)
|
|
execv(argv[0], argv);
|
|
|
|
return exit_code;
|
|
}
|