#!/usr/bin/php -q
<?php
if (PHP_VERSION_ID < 60000) {
	mb_internal_encoding("UTF-8");
	set_time_limit(0);
	ob_implicit_flush();
	declare(ticks = 1);
	date_default_timezone_set("Europe/Paris");
}
error_reporting(-1);
error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('display_errors', true);
ini_set('display_startup_errors', true);
ini_set('log_errors', true);
ini_set('error_log', '/var/log/wprotect/wp_backup.log');
//§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ FUNCTION DECLARATION §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
function create_backup_wprotect($without_log=FALSE) {  //creation de backup Wprotect
	global $config;
	global $connbdd;
	proc_nice(19);
	if ($without_log) {
		$nolog="-no-log";
	}
	else {
		$nolog="";
	}
	apc_store("backup_running", 1);
	logme ("BACKUP : start backup wprotect ...");
	sleep(2); // pour ne pas avoir de boublons sur les noms de fichier de sauvegarde
	exec_mysql("INSERT INTO thread SET pid='".getmypid()."', name='wp_backup', status='running'");
	if (!file_exists("/backup/tmp")) {
		mkdir ("/backup/tmp", 0777, true);
		if (!file_exists("/backup/tmp")) {
			logme("Erreur impossible de créer  le dossier /backup/tmp");
			logme("BACKUP : failed ...");
			apc_store("backup_running", 0);
			exec_mysql("UPDATE thread SET status='ERROR', date_end=NOW() WHERE pid='".getmypid()."' AND status='running'");
			exit();
		}
	}
	system ("chmod -R 777 /backup");
	system ("rm -f -r /backup/tmp/*");
	if (!$without_log) {
		system ("mkdir /backup/tmp/log");
	}
	system ("mkdir -p /backup/tmp/etc");
	system ("mkdir -p /backup/tmp/etc/wprotect");
	system ("mkdir -p /backup/tmp/etc/network");
	system ("mkdir -p /backup/tmp/var/lib/munin");
	system ("cp -R /var/lib/munin/* /backup/tmp/var/lib/munin/");
	system ("cp -R /etc/wprotect/* /backup/tmp/etc/wprotect/");
	system ("cp /etc/network/interfaces /backup/tmp/etc/network/interfaces");
	system ("cp -R /var/www/admin/fileman/Uploads /backup/tmp/");
	system ("mv /backup/tmp/Uploads /backup/tmp/portal_files");
	if (!$without_log) {
		system ("cp -R /var/log/wprotect/netwo* /backup/tmp/log/");
	}
	system ("cp -R /etc/wprotect /backup/tmp/");
	$result = exec_mysql("SHOW TABLES FROM wprotect");
	while ($val = mysqli_fetch_array($result)) {
		$tablename=$val[0];
		system ("mysqldump -h ".$config['config_mysql_host']." -u ".$config['config_mysql_user']." -p".$config['config_mysql_password']." ".$config['config_mysql_db']." ".$tablename." > /backup/tmp/".$tablename.".sql");
	}
	$date = date("Y-m-d_h-i-s");
	if (!file_exists("/backup/backup".$nolog."_".$config["hostname"]."-".$date.".tar.bz2")) {
		system ("cd /backup/tmp && tar cfj /backup/backup".$nolog."_".$config["hostname"]."-".$date.".tar.bz2 *");
		system ("rm -f -r /backup/tmp/*");
	}
	else {
		logme("BACKUP : ERROR -> the file backup name already exist ABORDING backup...");
		exec_mysql("UPDATE thread SET status='ERROR', date_end=NOW() WHERE pid='".getmypid()."' AND status='running'");
		apc_store("backup_running", 0);
		system ("rm -R /backup/tmp");
		exit();
	}
	if (file_exists("/backup/backup".$nolog."_".$config["hostname"]."-".$date.".tar.bz2")) {
		exec_mysql("UPDATE thread SET status='OK', date_end=NOW() WHERE pid='".getmypid()."' AND status='running'");
		logme ("BACKUP : backup finish with success ...");
		apc_store("backup_running", 0);
		system ("rm -R /backup/tmp");
		exit();
	}
	else {
		exec_mysql("UPDATE thread SET status='ERROR', date_end=NOW() WHERE pid='".getmypid()."' AND status='running'");
		logme ("BACKUP : backup failed the archive doesnt exist ...");
		apc_store("backup_running", 0);
		system ("rm -R /backup/tmp");
		exit();
	}
	apc_store("backup_running", 0);
	system ("rm -R /backup/tmp");
}
//------------------------------------------------------------------------------
function readconfig_master() { // lit le fichier de configuration
	global $config;
	global $connbdd;
	$tmp=myexec("hostname -f");
	$config["hostname"]=$tmp[0];
	$reader = new XMLReader(); 
	$reader->open("/etc/wprotect/wprotect.conf"); 
	while ($reader->read()) { 
		switch ($reader->nodeType)  { 
			case (XMLREADER::ELEMENT): 
				if ($reader->name == "security_key") { $reader->read(); $config['config_security_key'] = trim( $reader->value ); break; }
				if ($reader->name == "master_ip") { $reader->read(); $config['master_ip'] = trim( $reader->value ); break; }
				if ($reader->name == "master_port") { $reader->read(); $config['master_port'] = trim( $reader->value ); break; }
				if ($reader->name == "config_mysql_host") { $reader->read(); $config['config_mysql_host'] = trim( $reader->value ); break; }
				if ($reader->name == "config_mysql_user") { $reader->read(); $config['config_mysql_user'] = trim( $reader->value ); break; }
				if ($reader->name == "config_mysql_password") { $reader->read(); $config['config_mysql_password'] = trim( $reader->value ); break; }
				if ($reader->name == "config_mysql_db") { $reader->read(); $config['config_mysql_db'] = trim( $reader->value ); break; }
				if ($reader->name == "admin_interface") { $reader->read(); $config['admin_interface'] = trim( $reader->value ); break; }
				if ($reader->name == "theme") { $reader->read(); $config['theme'] = trim( $reader->value ); break; }
				if ($reader->name == "debug") { $reader->read(); $config['debug'] = trim( $reader->value ); break; }
				if ($reader->name == "wifi_access_point_ip") { $reader->read(); $config['wifi_access_point_ip'] = trim( $reader->value ); break; }
				if ($reader->name == "wifi_access_point_mac") { $reader->read(); $config['wifi_access_point_mac'] = trim( $reader->value ); break; }
				if ($reader->name == "public_interface") { $reader->read(); $config['public_interface'][1] = trim( $reader->value ); break; }
				if ($reader->name == "private_interface") { $reader->read(); $config['private_interface'][1] = trim( $reader->value ); break; }
				if ($reader->name == "bridge_interface") { $reader->read(); $config['bridge_interface'][1] = trim( $reader->value ); break; }
				if ($reader->name == "public2_interface") { $reader->read(); $config['public_interface'][2] = trim( $reader->value ); break; }
				if ($reader->name == "private2_interface") { $reader->read(); $config['private_interface'][2] = trim( $reader->value ); break; }
				if ($reader->name == "bridge2_interface") { $reader->read(); $config['bridge_interface'][2] = trim( $reader->value ); break; }
				if ($reader->name == "public3_interface") { $reader->read(); $config['public_interface'][3] = trim( $reader->value ); break; }
				if ($reader->name == "private3_interface") { $reader->read(); $config['private_interface'][3] = trim( $reader->value ); break; }
				if ($reader->name == "bridge3_interface") { $reader->read(); $config['bridge_interface'][3] = trim( $reader->value ); break; }
				if ($reader->name == "public4_interface") { $reader->read(); $config['public_interface'][4] = trim( $reader->value ); break; }
				if ($reader->name == "private4_interface") { $reader->read(); $config['private_interface'][4] = trim( $reader->value ); break; }
				if ($reader->name == "bridge4_interface") { $reader->read(); $config['bridge_interface'][4] = trim( $reader->value ); break; }
				if ($reader->name == "hotspot") { $reader->read(); $config['hotspot'] = trim( $reader->value ); break; }
		}
	}
}
//-----------------------------------------------------------------------------
function myexec($commande, $log_error=TRUE) {
	exec ($commande, $result, $return);
	if (($return > 0) && $log_error) logme ("EXEC : ".$commande." -> ".$return);
	return $result;
}
//------------------------------------------------------------------------------------
function logme ($data) {
	syslog ( LOG_DEBUG , "[wprotect] ".$data );
}
//------------------------------------------------------------
function connect_mysql () {
    global $config;
	global $connbdd;
	$connbdd = mysqli_connect ($config['config_mysql_host'], $config['config_mysql_user'], $config['config_mysql_password'], $config['config_mysql_db']);
	if (mysqli_connect_errno())
	{
		logme("Failed to connect to MySQL: " . mysqli_connect_error());
		return FALSE;
	}
    return TRUE;
}
//-----------------------------------------------------------
function verif_mysql () {
    global $config;
	global $connbdd;
	if (!isset($connbdd)) connect_mysql();
	if (!($result = @mysqli_query($connbdd, "SET NAMES 'utf8'"))) {
		logme("Verif MySQL ERROR try to reconnect : " . mysqli_error($connbdd));
		connect_mysql();
		if (!($result = @mysqli_query($connbdd, "SET NAMES 'utf8'"))) {
			logme("Failed to connect to MySQL: " . mysqli_connect_error());
			return FALSE;
		}
		else {
			return TRUE;
		}
	}
    return TRUE;
}
//------------------------------------------------------------
function exec_mysql($query) {
	global $config;
	global $connbdd;
	if (!is_resource($connbdd)) {
		connect_mysql();
	}
	if (!($result = @mysqli_query($connbdd, $query))) {
		logme("EXEC_MYSQL ERROR (".$query.") : " . @mysqli_error($connbdd));
		if (verif_mysql()) {
			if (!($result = @mysqli_query($connbdd, $query))) {
				logme("EXEC_MYSQL TWICE ERROR (".$query.") : " . @mysqli_error($connbdd));
			}
			else {
				return $result;
			}
		}
		else {
			logme("MYSQL VERIF ERROR : connexion impossible");
			return FALSE;
		}
	}
	else {
		return $result;
	}
}
//-------------------------------------------------------------------
function get_system_version() {
	global $config;
	global $connbdd;
	$r=myexec("lsb_release -da");
	$i=0;
	foreach ($r AS $k=>$v) {
		$v=trim($v);
		$a=explode(":", $v);
		$a[0]=trim($a[0]);
		$a[1]=trim($a[1]);
		$b[$a[0]]=$a[1];
	}
	$config['sys_os_name']=$b['Distributor ID'];
	$config['sys_os_version']=$b['Release'];
	$config['sys_os_fullname']=$b['Description'];
	$config['sys_os_codename']=$b['Codename'];
	exec_mysql("INSERT INTO options SET name='sys_os_name', value='".$config['sys_os_name']."' ON DUPLICATE KEY UPDATE value='".$config['sys_os_name']."'");
	exec_mysql("INSERT INTO options SET name='sys_os_version', value='".$config['sys_os_version']."' ON DUPLICATE KEY UPDATE value='".$config['sys_os_version']."'");
	exec_mysql("INSERT INTO options SET name='sys_os_fullname', value='".$config['sys_os_fullname']."' ON DUPLICATE KEY UPDATE value='".$config['sys_os_fullname']."'");
	exec_mysql("INSERT INTO options SET name='sys_os_codename', value='".$config['sys_os_codename']."' ON DUPLICATE KEY UPDATE value='".$config['sys_os_codename']."'");
}
//-------------------------------------------------------------------
function get_infos_net_iface($iface) {
	$result=array();
	$tmp = myexec("ifconfig ".$iface);
	foreach ($tmp AS $key => $value) {
		preg_match("/^.*inet\saddr\:(?P<ip>([0-9.]*))\s+Bcast\:(?P<bcast>([0-9.]*))\s+Mask\:(?P<netmask>([0-9.]*)).*$/", $value, $match);
		if (isset($match['ip'])) {
			$result["ip"]=$match['ip'];
			$result["netmask"]=$match['netmask'];
			$result["bcast"]=$match['bcast'];
		}
		preg_match("/^.*inet\sadr\:(?P<ip>([0-9.]*))\s+Bcast\:(?P<bcast>([0-9.]*))\s+Masque\:(?P<netmask>([0-9.]*)).*$/", $value, $match);
		if (isset($match['ip'])) {
			$result["ip"]=$match['ip'];
			$result["netmask"]=$match['netmask'];
			$result["bcast"]=$match['bcast'];
		}
		preg_match("/^.*inet\s(?P<ip>([0-9.]*))\s+netmask\s(?P<netmask>([0-9.]*))\s+broadcast\s(?P<bcast>([0-9.]*)).*$/", $value, $match);
		if (isset($match['ip'])) {
			$result["ip"]=$match['ip'];
			$result["netmask"]=$match['netmask'];
			$result["bcast"]=$match['bcast'];
		}
	}
	logme("GET IFACE ".$iface." IP:".$result['ip']." netmask:".$result['netmask']." Bcast:".$result['bcast']);
	return $result;
}
//§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ MAIN PROGRAM §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
$nolog=FALSE;
foreach ($argv AS $k=>$v) {
	if (($v=="-help") OR ($v=="--help") OR ($v=="-h")) {
		echo "Create backup for WPROTECT, backup will be store into /backup.\n\n";
		echo "Commandline Argument :\n";
		echo "----------------------\n";
		echo "-nolog : Backup all except log files\n\n";
		exit();
	}
	if ($v=="-nolog") {
		$nolog=TRUE;
	}
}
logme("WP_BACKUP : start ...");
logme("WP_BACKUP : Read config ...");
readconfig_master();
$connbdd=FALSE;
connect_mysql();
apc_store("backup_running", 1);
create_backup_wprotect($nolog);
?>