#!/usr/bin/php
<?php

/// Functions
	function checkdirs($webroot,$client,$domain,$vhost,$uid)
	{
		global $ini;
		checkdir($webroot.'/'.$client, $uid, 33);
		checkdir($webroot.'/'.$client.'/'.$domain, $uid, 33);
		$ret=checkdir($webroot.'/'.$client.'/'.$domain.'/'.$vhost, $uid, 33);
		if ($ret==1)
		{
			$skel=$ini['global']['skeleton_dir']."/index.php";
			$fp="$webroot/$client/$domain/$vhost/index.php";
			copy("$skel", "$fp");
			chown("$fp",$uid);
		}
		checkdir($webroot.'/temp/'.$domain, 33, 33);
		checkdir($webroot.'/temp/'.$domain.'/'.$vhost, 33, 33);
		checkdir($webroot.'/temp/'.$domain.'/'.$vhost.'/session', 33, 33);
		checkdir($webroot.'/temp/'.$domain.'/'.$vhost.'/ultmp', 33, 33);
		checkdir($webroot.'/temp/'.$domain.'/'.$vhost.'/tmp', 33, 33);
	}

#############################################################################

/// init
	global $ini;
	global $node;
	global $force_run;

	require(dirname(__FILE__)."/../include/functions.php");
	check_force_run(1);
	init();

	if (get_ini_opt('confgen','apache-confgen') === '0') { exit(0); }

	check_update('apache_update');

/// include template class
	require(dirname(__FILE__)."/../include/template.class.php");

/// start update
	logme("apache: Export started");

/// register SSL plugins
	register_ssl_plugins();

/// Delete last backup
	foreach ($ini['apache']['confdir'] as $apacheno => $confdir)
	{
		if ($confdir != "" && $confdir != NULL ) {
			if (file_exists($confdir.'/vhost.bck'))
			{
				foreach(glob($confdir.'/vhost.bck/*') as $fn) { unlink($fn); }
				rmdir($confdir.'/vhost.bck');
			}
			rename($confdir.'/vhost.auto',$confdir.'/vhost.bck');
			mkdir($confdir.'/vhost.auto', 0775);
		}
		else
		{
			panic("Apache ".$apacheno." confdir not defined!");
		}
	}
	$nginx_confdir=$ini['nginx']['confdir'];
	if ($nginx_confdir != "" && $nginx_confdir != NULL )
	{
		if (file_exists($nginx_confdir.'/vhost.bck'))
		{
			foreach(glob($nginx_confdir.'/vhost.bck/*') as $fn) { unlink($fn); }
			rmdir($nginx_confdir.'/vhost.bck');
		}
		rename($nginx_confdir.'/vhost.auto',$nginx_confdir.'/vhost.bck');
		mkdir($nginx_confdir.'/vhost.auto', 0775);
	}
	else
	{
		panic("Nginx confdir not defined!");
	}

/// Generate vhosts
	$sql="SELECT
		vhosts.id AS vhid,
		vhosts.host AS host,
		IFNULL(vhosts.token, MD5(RAND())) AS token,
		TRIM('\n' from REPLACE(vhosts.alias,'\r','')) AS alias_r,
		TRIM('\n' from REPLACE(vhosts.ext_alias,'\r','')) AS ext_alias_r,
		REPLACE(vhosts.docroot,'\r','') AS root,
		REPLACE(REPLACE(ifnull(vhosts.extradir,':'),'\r',''),'\n',':') AS extradir,
		REPLACE(vhosts.settings,'\r','') AS settings,
		REPLACE(vhosts.nsettings,'\r','') AS nsettings,
		vhosts.ssl_on AS ssl_on,
		vhosts.ssl_mode AS ssl_mode,
		vhosts.upstream AS upstream,
		REPLACE(vhosts.usparam,'\r','') AS usparam,
		domain.name AS domain,
		client.name AS client,
		if(charset is not null,concat('AddDefaultCharset ',charset),'') AS charset,
		REPLACE(vhosts.writable,'\r','') AS writable,
		domain.clientid as clientid,
		client.migrate as migrate
		FROM vhosts
		JOIN domain ON vhosts.domainid=domain.id
		JOIN client ON domain.clientid=client.id
		WHERE domain.active=1 AND client.active=1 AND vhosts.active=1
		AND (client.node=$node OR client.migrate=1);";

	$res=DBquery($sql) or die(1);
	$n=$res->num_rows;

	//if ($n==0) die(1); // no vhosts = error (it's not a problem anymore)

	logme ("apache: Creating $n vhosts");

/// Use template

	$template = new Template;
	$template->template_dir = $ini['global']['template_dir'];
	$template->compile_dir = $ini['global']['template_dir']."_c";


	while ($vhost = $res->fetch_assoc())
	{
		//server-node defaults
		$template->assign('webroot',$ini['global']['webroot']);
		$template->assign('node',$ini['global']['node']);
		$template->assign('node_ip',$ini['nodeip'][$ini['global']['node']]);
		$template->assign('def_domain',$ini['global']['domain']);
#		$template->assign('def_host',$ini['global']['host']);
#		$template->assign('sslkeydir',$ini['ssl']['keydir']);
		//temporary hack to get chrooted path
		$template->assign('sslkeydir',preg_replace('#/chroot/[^/]*#','',$ini['ssl']['keydir']));


		if (array_key_exists($vhost['upstream'], $ini['apache']['port']))
		{
			$upstream_scheme='http';
			$upstream_port=$ini['apache']['port'][$vhost['upstream']];
			$upstream_host='127.0.0.1';
			$upstream_apache=true;
		}
		elseif (array_key_exists('upstream', $ini) && array_key_exists('port', $ini['upstream']) && array_key_exists($vhost['upstream'], $ini['upstream']['port']))
		{
			$upstream_scheme='http';
			$upstream_port=$ini['upstream']['port'][$vhost['upstream']];
			if (array_key_exists('host', $ini['upstream']))
			{
				$upstream_host=$ini['upstream']['host'][$vhost['upstream']];
			}
			else
			{
				$upstream_host='127.0.0.1';
			}
			$upstream_apache=false;
		}
		elseif($vhost['upstream']=='302' || $vhost['upstream']=='301' || $vhost['upstream']=='1')
		{
			$upstream_scheme=null;
			$upstream_port=null;
			$upstream_host=null;
			$upstream_apache=false;
		}
		elseif($vhost['upstream']=='999')
		{
			$upstream_parts = parse_url($vhost['usparam']);
			$upstream_scheme=$upstream_parts['scheme'];
			$upstream_port=$upstream_parts['port'];
			$upstream_host=$upstream_parts['host'];
			$upstream_apache=false;
		}
		else
		{
			$vhost['upstream']=='1';
			$upstream_scheme=null;
			$upstream_port=null;
			$upstream_host=null;
			$upstream_apache=false;
		}
		$template->assign('upstream_scheme', $upstream_scheme);
		$template->assign('upstream_port', $upstream_port);
		$template->assign('upstream_host', $upstream_host);

		if ($vhost['ssl_mode']==2)
		{
			$template->assign('ssl_redir_code', '301');
		}
		else
		{
			$template->assign('ssl_redir_code', '302');
		}

		/// Assemble alias array
#		$aliases=explode("\n", $vhost['alias_r']);
		$aliases=multirow2array($vhost['alias_r']);
#		$ext_aliases=explode("\n", $vhost['ext_alias_r']);
		$ext_aliases=multirow2array($vhost['ext_alias_r']);
#		if (strlen($aliases[0])==0) { $aliases=array(); }
#		if (strlen($ext_aliases[0])==0) { $ext_aliases=array(); }
		$ext_aliases_www= array();

		foreach ($ext_aliases as $alias)
		{
			if (substr($alias,1,4)=='www.')
			{
				array_push($ext_aliases_www, substr($alias,5));
			}
			else
			{
				if (strpos($alias,'*') === false)
				{
					array_push($ext_aliases_www,'www.'.$alias);
				}
			}
		};

		/// Assemble writable dir array
		$writabledirs=multirow2array($vhost['writable']);
#		$writabledirs=array_filter(explode("\n", $vhost['writable']), 'nonempty');
#		if (strlen($writabledirs[0])==0) { $writabledirs=array(); } # array_filter removes empty elements

		$template->assign('aliases',$aliases);
		$template->assign('ext_aliases',$ext_aliases);
		$template->assign('ext_aliases_www',$ext_aliases_www);
		$template->assign('writabledirs',$writabledirs);
		$template->assign($vhost);

		/// Find SSL keys (if SSL is on)
		if ($vhost['ssl_on']==4)
		{
			$ssl_keys=find_ssl_keys($vhost['domain'], $vhost['host']);
			if (is_array($ssl_keys))
			{
				// we have keys, let's generate SSL vhosts
				$template->assign('https',1);
				$template->assign('ssl_key',$ssl_keys['key']);
				$template->assign('ssl_cert',$ssl_keys['cert']);
			}
			else
			{
				if ($vhost['migrate']==0 && $ini['global']['live']==1 && $force_run==0)
				{
					//set SSL to failed in database (user has to regenerate/retry)
					DBquery("UPDATE `vhosts` SET `ssl_on`='3' WHERE `id` = '".$vhost['vhid']."' AND `ssl_on`='4';");
					$template->assign('ssl_on',3);
				}
				$template->assign('ssl_mode',0);
				$template->assign('https',0);
			}
		}
		else
		{
			//$template->assign('ssl_on',0);
			$template->assign('ssl_mode',0);
			$template->assign('https',0);
		}

		//var_dump($template->getTemplateVars()); # debug

		/// Find config template files
		if ($vhost['upstream']=='302')
		{
			$template->assign('redirect',$vhost['usparam']);
			$template->assign('redirect_code',302);
			$nginx_template_filename='nginx_vhost_red.tpl';
#			$apache_template_filename='vhost_red.tpl';
		}
		elseif ($vhost['upstream']=='301')
		{
			$template->assign('redirect',$vhost['usparam']);
			$template->assign('redirect_code',301);
			$nginx_template_filename='nginx_vhost_red.tpl';
#			$apache_template_filename='vhost_red.tpl';
		}
		elseif ($vhost['upstream']=='1')
		{
			$nginx_template_filename='nginx_vhost_static.tpl';
		}
		else
		{
			if (file_exists($ini['global']['template_dir'].'/nginx_vhost_'.$vhost['upstream'].'.tpl'))
			{
				$nginx_template_filename='nginx_vhost_'.$vhost['upstream'].'.tpl';
			}
			else
			{
				if ($upstream_apache)
				{
					$nginx_template_filename='nginx_vhost.tpl';
				}
				else
				{
					$nginx_template_filename='nginx_vhost_ext.tpl';
				}
			}

			if (file_exists($ini['global']['template_dir'].'/vhost_'.$vhost['upstream'].'.tpl'))
			{
				$apache_template_filename='vhost_'.$vhost['upstream'].'.tpl';
			}
			else
			{
				$apache_template_filename='vhost.tpl';
			}
		}

		/// Create configs and dirs

		/// Create apache vhost config file
		if ($upstream_apache)
		{
			foreach ($ini['apache']['confdir'] as $apacheno => $confdir)
			{
				$port=$ini['apache']['port'][$apacheno];
				$template->assign('port',$port);
				if (!(file_exists($confdir.'/vhost.manual/'.$vhost['host'].'.'.$vhost['domain'])))
				{
					fpush($confdir.'/vhost.auto/'.$vhost['host'].'.'.$vhost['domain'],$template->fetch($apache_template_filename));
				}
			}
		}

		/// Create nginx vhost config file
		if (!(file_exists($ini['nginx']['confdir'].'/vhost.manual/'.$vhost['host'].'.'.$vhost['domain'])))
		{
			fpush($ini['nginx']['confdir'].'/vhost.auto/'.$vhost['host'].'.'.$vhost['domain'],$template->fetch($nginx_template_filename));
		}

		/// check Dirs
		$uid=$ini['global']['firstuid']+$vhost['clientid'];
		checkdirs($ini['global']['webroot'],$vhost['client'],$vhost['domain'],$vhost['host'],$uid);

		$template->clearAllAssign();
	}

### Check configs

	// apache

	$apache_panic=array();
	foreach ($ini['apache']['conftest'] as $apacheno => $conftest)
	{
		$confdir=$ini['apache']['confdir'][$apacheno];

		// delete old error dir
		if ($confdir != "" && $confdir != NULL )
		{
			if (file_exists($confdir.'/vhost.error'))
			{
				foreach(glob($confdir.'/vhost.error/*') as $fn) { unlink($fn); }
				rmdir($confdir.'/vhost.error');
			}
		}

		if (exec_err($conftest.' 2>/dev/null') != 0)
		{
			if ($confdir != "" && $confdir != NULL )
			{
				//revert to backup
				if (file_exists($confdir.'/vhost.bck'))
				{
					rename($confdir.'/vhost.auto',$confdir.'/vhost.error');
					rename($confdir.'/vhost.bck',$confdir.'/vhost.auto');
					//mkdir($confdir.'/vhost.bck', 0775);
				}
			}
			$apache_panic[]=$apacheno;
		}
	}

	// nginx

	// delete old nginx error dir
	$nginx_confdir=$ini['nginx']['confdir'];
	if ($nginx_confdir != "" && $nginx_confdir != NULL )
	{
		if (file_exists($nginx_confdir.'/vhost.error'))
		{
			foreach(glob($nginx_confdir.'/vhost.error/*') as $fn) { unlink($fn); }
			rmdir($nginx_confdir.'/vhost.error');
		}
	}

	$nginx_panic=0;
	if (exec_err($ini['nginx']['conftest'].' 2>/dev/null') != 0)
	{
		if ($nginx_confdir != "" && $nginx_confdir != NULL )
		{
			if (file_exists($nginx_confdir.'/vhost.bck'))
			{
				rename($nginx_confdir.'/vhost.auto',$nginx_confdir.'/vhost.error');
				rename($nginx_confdir.'/vhost.bck',$nginx_confdir.'/vhost.auto');
				//mkdir($nginx_confdir.'/vhost.bck', 0775);
			}
		}
		$nginx_panic=1;
	}

	// do the panic

	if (count($apache_panic)>0 || $nginx_panic>0)
	{
		$pt=array();

		if (count($apache_panic)>0)
		{
			$pt[]="Apache ".implode(', ', $apache_panic);
		}

		if ($nginx_panic>0)
		{
			$pt[]="Nginx";
		}

		panic(implode(', ', $pt)." config error");
	}

### Generate vhost list

	global $spooldir;
	checkdir($spooldir,0,0);

	$res->data_seek(0);

	//create/overwrite vhost list
	$vhlf=fopen($spooldir.'/vhlist.txt','w');

	while ($vhost = $res->fetch_assoc())
	{
		fwrite($vhlf,$vhost['domain'].'/'.$vhost['host']."\n");
	}

	fclose($vhlf);

### Reload all apache instances

	$apache_restarts=array();

	foreach ($ini['apache']['name'] as $apacheno => $daemon_name)
	{
		$apache_reload="restart";

		if (array_key_exists('reload', $ini['apache']) && array_key_exists($apacheno, $ini['apache']['reload']))
		{
			$apache_reload=$ini['apache']['reload'][$apacheno];
		}

		$apache_restarts[$daemon_name]=$apache_reload;
	}
	daemons_startstop($apache_restarts);

### Reload nginx

	$nginx_reload="reload";
	if (array_key_exists('reload', $ini['nginx']))
	{
		$nginx_reload=$ini['nginx']['reload'];
	}

	daemons_startstop(array($ini['nginx']['name'] => $nginx_reload));

### reset update flag

	unlock_update('apache_update');

	logme("apache: Export done.");

