<?php

// global to track if http configuration backup has been performed or not
$httpdConfBackedUp = false;

function webserverParseConfiguration($installationDir, $httpdConf)
{
	$vars = array();

	$fh = fopen($httpdConf, 'r');

	// ****** Debian/Ubuntu specific checks ****** //
	if(is_dir('/etc/apache2'))
	{
		// check if mod-expires is available but not enabled
		if(		is_file("/etc/apache2/mods-available/expires.load")
			&& !is_file("/etc/apache2/mods-enabled/expires.load"))
		{
			// enable it
			system("ln -s /etc/apache2/mods-available/expires.load /etc/apache2/mods-enabled/expires.load");
			$vars['mod_expires'] = true;
		}
		elseif(is_file("/etc/apache2/mods-enabled/expires.load"))
		{
			$vars['mod_expires_on'] = 1;
		}

		// check if mod-deflate available but not enabled
		if(		is_file("/etc/apache2/mods-available/deflate.load")
			&&	!is_file("/etc/apache2/mods-enabled/deflate.load"))
		{
			system("ln -s /etc/apache2/mods-available/deflate.load /etc/apache2/mods-enabled/deflate.load");
			$vars['mod_gzip'] = true;
		}
		elseif(is_file("/etc/apache2/mods-enabled/deflate.load"))
		{
			$vars['mod_gzip_on'] = 1;
		}
		
		// check if mod-rewrite is available but not enabled
		if(		is_file("/etc/apache2/mods-available/rewrite.load")
			&& !is_file("/etc/apache2/mods-enabled/rewrite.load"))
		{
			// enable it
			system("ln -s /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load");
			$vars['mod_rewrite'] = true;
		}
		elseif(is_file("/etc/apache2/mods-enabled/rewrite.load"))
		{
			$vars['mod_rewrite'] = true;
		}

		
	}

	$apache_special_comments = array(
		'mod_gzip_on' => '/^# @mail GZIP Conf/i',
		'mod_expires_on' => '/# @mail Expires Conf/i',
		'mod_php_on' => '/^# Atmail Mod_PHP Conf/i'
	);

	$debian = (file_exists('/etc/debian_version') || file_exists('/etc/debian_release')) ? 1 : 0;

	$apache_attributes = array(
		'alias' => array('type' => 'boolean', 'filter' => '/Alias \/archive(\/|\s)/i'),
		'userIsAtmail' => array('type' => 'boolean', 'filter' => '/User atmail/i'),
		'addhandler_php' => array('type' => 'boolean', 'filter' => '/AddHandler (.*?)(\.php)/i'),
		'mod_gzip' => array('type' => 'boolean', 'filter' => array('/Addmodule deflate_module.c/i', '/LoadModule deflate_module/i')),
		'mod_php' => array('type' => 'boolean', 'filter' => array('/AddModule mod_php(\d).c/i', '/LoadModule php(\d)_module/i')),
		'mod_expires' => array('filter' => '/LoadModule expires_module/i'),
		'mod_rewrite' => array('filter' => '/LoadModule rewrite_module/i'),
		'serverRoot' => array('type' => 'string', 'trim' => '"\'', 'filter' => '/^ServerRoot (.*)/i', 'single' => true),
		'directory' => array('filter' => "/<Directory \"\/usr\/local\/atmail\/webmail\">/i", 'set' => 'directory_tagged'),
		'alias' => array('filter' => "|Alias /mail " . $installationDir . "|i"),
		'activeSyncAlias' => array('filter' => "|Alias /Microsoft-Server-ActiveSync $installationDir|i"),
		'davVhost' => array('filter' => '|RewriteRule \^/\(\.\*\)\$ /rootserver.php \[L\]|i'),
		'wwwUser' => array('type'=> 'string', 'trim' => '"\'', 'illegalChars' => array(" ", "\r"), 'filter' => '/^User (.*)/i', 'single' => true),
		'wwwGroup' => array('type' => 'string', 'trim' => '"\'', 'illegalChars' => array("\r"), 'filter' => '/^Group (.*)/i', 'single' => true, 'extendedCondition' => !$debian),
		'doc_root' => array('type' => 'string', 'trim' => true, 'illegalChars' => array('"', "'"), 'filter' => '/^DocumentRoot(.*)/i', 'single' => true),
		'execCGI' => array('filter' => '/Options.*?ExecCGI/i', 'single' => 'directory_tagged'),
		'currentCharset' => array('type' => 'string', 'filter' => '/AddDefaultCharset (.*)/i', 'trim' => true, 'callback' => create_function('$vars', '$vars["defaultCharset"] = (strtoupper($vars["currentCharset"]) == "UTF-8" ? true: false); return $vars;')),
		'includeHolder' => array('type' => 'string', 'filter' => '/^Include (.*)/', 'trim' => '"\'', 'callback' =>
			create_function('$vars',
					'	
					$vars["serverRoot"] = rtrim($vars["serverRoot"], "/");
						//if includHolder starts with / then absolute path so dont cat on serverRoot
						if(substr($vars[\'includeHolder\'], 0, 1) == \'/\')
							$inc = $vars[\'includeHolder\'];
						else
							$inc = $vars["serverRoot"] . "/" . $vars[\'includeHolder\'];
						
						$vars[\'httpdIncludes\'] = array();
						if(strpos($inc, \'/*.conf\') !== false)
						{
							$files = glob($inc);
							foreach ($files as $file)
							{
								$vars[\'httpdIncludes\'][] = $file;
							}
						}
						else
							$vars[\'httpdIncludes\'][] = $inc;
						return $vars;'))
	);

	// scan for attributes
	while (false !== $line = fgets($fh))
	{
		$line = rtrim($line, "\r\n");
		if($line == '')
		{
			continue;
		}
		
		// match special comments
		foreach($apache_special_comments as $k => $v)
		{
			if( preg_match($v, $line) )
			{
				$vars[$k] = true;
				continue;
			}
		}

		// Ignore all other comments
		if(substr(ltrim($line), 0, 1) == '#')
		{
			continue;
		}

		// match known attributes
		foreach($apache_attributes as $k => $v)
		{
			$found = false;
			if(!is_array($v['filter']))
			{
				$v['filter'] = array($v['filter']);
			}
			if(!isset($v['type']))
			{
				$v['type'] = 'boolean';
			}
			foreach($v['filter'] as $test)
			{
				if( preg_match($test, $line, $m) )
				{
					if(		!isset($v['single'])
						||	(isset($v['single']) && is_bool($v['single']) && !isset($vars[$k]))
						||	(isset($v['single']) && is_string($v['single']) && isset($vars[$v['single']]))
						&&	(isset($v['extendedCondition']) ? $v['extendedCondition'] : true))
					{
						switch($v['type'])
						{
							default:
							case 'boolean':
							{
								$vars[$k] = true;
								if(isset($v['single']) && is_string($v['single']) && isset($vars[$v['single']]))
								{
									$vars[$v['single']] = false;
								}
								if(isset($v['set']) && is_string($v['set']) && !isset($vars[$v['set']]))
								{
									$vars[$v['set']] = true;
								}

							} break;
							case 'string':
							{
								if(isset($v['trim']))
								{
									if(is_bool($v['trim']) && $v['trim'] == true)
									{
										$vars[$k] = trim($m[1]);
										$vars[$k] = rtrim($vars[$k]);
									}
									else if(isset($v['trim']))
									{
										$vars[$k] = trim($m[1], $v['trim']);
										$vars[$k] = rtrim($vars[$k], $v['trim'] . "\r");
									}
								}
								else
								{
									$vars[$k] = $m[1];
								}

								if(isset($v['illegalChars']))
								{
									foreach($v['illegalChars'] as $illegalChar)
									{
										$vars[$k] = str_replace($illegalChar, '', $vars[$k]);
									}
								}
							} break;
						}
					}
					if(isset($v['callback']))
					{
						$vars = $v['callback']($vars);
					}
					$found = true;
					continue;
				}
			}
			if($found) continue;
		}
	}
	fclose($fh);
	
	// post process any environment variables out
	foreach($vars as $key => $var)
	{
		if(is_string($var) && strpos($var, '${') !== false)
		{
			// found a variable
			// nuke it.
			unset($vars[$key]);
		}
	}
	
	return $vars;
}

/**
 * find where apache is located
 */
function webserverFindBin()
{
	foreach (array('httpd', 'apache') as $name)
	{
		$ps = `ps auxw | grep $name | grep -v grep | grep -v Xvnc`;
		if (preg_match("/\s+(\/.+)$/", $ps, $m))
		{
			$bin = $m[1];
			break;
		}
	}

	if (isset($bin) && is_executable($bin))
		return $bin;
	elseif (is_executable('/usr/sbin/httpd'))
		return '/usr/sbin/httpd';
	elseif (is_executable('/usr/local/sbin/httpd'))
		return '/usr/local/sbin/httpd';
	elseif (is_executable('/usr/sbin/httpd2'))
		return '/usr/sbin/httpd2';
	elseif (is_executable('/usr/sbin/apache2'))
		return '/usr/sbin/apache2';

	return false;
}

function webserverFindConfig($webserverBin = null) {

    if (is_null($webserverBin)) {
        $webserverBin = webserverFindBin();
    }

	// Find default httpd.conf
	exec("$webserverBin -V", $output);

	foreach($output as $line)
	{
		if(preg_match('/SERVER_CONFIG_FILE="(.+?)"/', $line, $m))
			$httpdConf = $m[1];

		if(preg_match('/HTTPD_ROOT="(.+?)"/', $line, $m))
			$httpdRoot = $m[1];
	}

	if(substr($httpdConf, 0, 1) != '/')
		$httpdConf = "$httpdRoot/$httpdConf";

    return $httpdConf;

}

function webserverFindConfD($httpdConf)
{
	$confDir = dirname($httpdConf);

	// Check Redhat/CentOS style
	if(is_dir($confDir . "/../conf.d/"))
	{
		$confDir = realpath($confDir . "/../conf.d/");
	}
	// Check Ubuntu/Suse style
	else if(is_dir($confDir . "/conf.d/"))
	{
		$confDir = realpath($confDir . "/conf.d/");
	}
	else
	{
		$confDir = "";
	}

	return $confDir;
}

function webserverAppendConf($path, $lines, $check=0)
{
    webserverBackupConf($path);

	if($check)	{
		// First, check we do not already exist
		$fh = fopen($path, 'r');
		while (false !== $line = fgets($fh))
		{

		if(str_replace('\n', '', $line) == str_replace('\n', '', $lines[0]))	{
			return 0;
		}

		}

		fclose($fh);

	}

	$fh = fopen($path, 'a');

    foreach ($lines as $line)
		fwrite($fh, "$line\n");

    fclose($fh);

	return 0;
}

function webserverEditConf($path, $find, $replace)
{
	webserverBackupConf($path);
	$fh1 = fopen($path, 'r');
    if (false !== $fh2 = fopen("$path.new", 'w'))
	{
		while (false !== $line = fgets($fh1))
		{
			$line = preg_replace("/$find/", $replace, $line);
			fwrite($fh2, $line);
		}

		fclose($fh1);
		fclose($fh2);

		rename("$path.new", $path);
	}
	else
		echo "Could not auto edit httpd.conf!\n";

}

function webserverBackupConf($path)
{
    global $httpdConfBackedUp;

    // Only make a backup if we haven't already
    if (!$httpdConfBackedUp)
    {
		$backupFilename = $path . '.atmail_backup-' . date("Y-m-d_H:i:s");
        if (copy($path, $backupFilename))
		{
            $httpdConfBackedUp = true;
			print <<<EOF

\033[1;32mYour webserver configuration was backed up to : $backupFilename \033[0;39m


EOF;

		}
    }
}

function webserverRestart()
{
    if (file_exists("/usr/sbin/apache2ctl"))
		$hup = "/usr/sbin/apache2ctl";

    else if (file_exists("/usr/local/apache/bin/apachectl"))
		$hup = "/usr/local/apache/bin/apachectl";

    else if (file_exists("/etc/init.d/httpd"))
		$hup = "/etc/init.d/httpd";

    else if (file_exists("/usr/local/sbin/apachectl"))
		$hup = "/usr/local/sbin/apachectl";

    else if (file_exists("/etc/init.d/apache2"))
		$hup = "/etc/init.d/apache2 restart";

    if (isset($hup))
	{
        $success = system("$hup restart");
        fwrite(STDOUT, "\n");
    }
    else
	{
        $success = system("killall -v -HUP httpd");
        $success = system("killall -v -HUP apache");
        $success = system("killall -v -HUP apache2");
	    $success = system("/etc/init.d/apache2 restart");
    }

	if(file_exists("/sbin/chkconfig"))
	{
		system("/sbin/chkconfig httpd on >/dev/null 2>&1");
		system("/sbin/chkconfig apache on >/dev/null 2>&1");
	}
}

// Append the Atmail *DAV config file to Apache (Shared between server-install and server-update)
function appendApacheConf($apacheConfD, $httpdConf, $apacheAddedOnDate)
{
	
	if(is_dir($apacheConfD))
	{
		fwrite(STDOUT, "Copying DAV configuration file to /etc/httpd/conf.d/atmail-dav.conf\n\n");
		system("cp /usr/local/atmail/webmail/install/apache/atmail-dav.conf $apacheConfD/atmail-dav.conf");
	}
	else
	{
		$davConf = $apacheAddedOnDate;
		$davConf .= file_get_contents("/usr/local/atmail/webmail/install/apache/atmail-dav.conf");
		$fh = fopen($httpdConf, 'a');
		fwrite($fh, $davConf);
		fclose($fh);
	}

}