HEX
Server: Apache/2.4.67 (Debian)
System: Linux hosting103 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64
User: muzikaecom (1013)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: //usr/local/share/hostingplatform/API.class.php
<?php
require_once("/usr/local/share/hostingplatform/esrpc.php");

/**
 * Hosting Platform webservice definition.
 */

/**
 * Hosting Platform webservice.
 */
class HostingPlatformConnection {

 var $db;

 function __construct() {
  $this->db = new SQLite3("/var/local/hostingplatform/db.sqlite");
  $this->db->query("PRAGMA foreign_keys = ON");
 }

 /**
  * Create a new Hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param integer $storage the amount of megabytes of storage capacity.
  * @param integer $bandwidth the amount of megabytes of monthly bandwidth.
  * @param string $emailaddress the emailaddress of the webmaster of the hostingpackage
  * @return string Returns true creation was successfull.
  */
 function addHostingPackage($packagename, $storage, $bandwidth, $emailaddress = "") {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($storage) || !is_numeric($storage) || floor($storage) < 0) {
    throw new Exception ("Supplied storage amount is invalid");
  }
  if(!trim($bandwidth) || !is_numeric($bandwidth) || floor($bandwidth) < 0) {
    throw new Exception ("Supplied bandwidth amount is invalid");
  }
  if(posix_getpwnam($packagename)) {
    throw new Exception ("Packagename conflicts with user");
  }
  if($this->__checkIfHostingPackageExists($packagename)) {
    throw new Exception ("Hostingpackage already exists");
  }

  $packagename  = $this->db->escapeString($packagename);
  $storage      = $this->db->escapeString($storage);
  $bandwidth    = $this->db->escapeString($bandwidth);
  $emailaddress = $this->db->escapeString($emailaddress);

  shell_exec("sudo " . dirname(__FILE__) . "/scripts/addHostingPackage " . escapeshellcmd($packagename) . " " . escapeshellcmd($storage) . " " . escapeshellcmd($bandwidth));

  $insert_query = "INSERT INTO hosting (packagename, storage, bandwidth, suspended, emailaddress)
                               VALUES  ('$packagename', $storage, $bandwidth, 'false', NULLIF('$emailaddress',''))";

  if($this->db->query($insert_query)) {
   $this->__generateEximHostingEmailAddresses();
   return true;
  }
  else {
   return false;
  }
 }
 
 /**
  * Modify a Hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param integer $storage the amount of megabytes of storage capacity.
  * @param integer $bandwidth the amount of megabytes of monthly bandwidth.
  * @param string $emailaddress the emailaddress of the webmaster of the hostingpackage
  * @return string Returns true modification was successfull.
  */
 function updateHostingPackage($packagename, $storage, $bandwidth, $emailaddress = null) {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($storage) || !is_numeric($storage) || floor($storage) < 0) {
    throw new Exception ("Supplied storage amount is invalid");
  }
  if(!trim($bandwidth) || !is_numeric($bandwidth) || floor($bandwidth) < 0) {
    throw new Exception ("Supplied bandwidth amount is invalid");
  }

  if(!$this->__checkIfHostingPackageExists($packagename)) {
    $this->addHostingPackage($packagename, $storage, $bandwidth, $emailaddress);
    return true;
  }

  $packagename  = $this->db->escapeString($packagename);
  $storage      = $this->db->escapeString($storage);
  $bandwidth    = $this->db->escapeString($bandwidth);
  $emailaddress = $this->db->escapeString($emailaddress);

  $query = "UPDATE hosting SET storage      = $storage,
                               bandwidth    = $bandwidth,
                               emailaddress = NULLIF('$emailaddress','')
                           WHERE
                               packagename  = '$packagename'";

  if($this->db->query($query)) {
   shell_exec("sudo " . dirname(__FILE__) . "/scripts/updateHostingPackage " . escapeshellcmd($packagename) . " " . escapeshellcmd($storage) . " " . escapeshellcmd($bandwidth));
   $this->__generateEximHostingEmailAddresses();
   return true;
  }
  else {
   return false;
  }
 }

 /**
  * Remove a Hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @return string Returns true when the package was succesfully marked to be removed.
  */
 function removeHostingPackage($packagename) {
  $packagename = strtolower($packagename);
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $packagename  = $this->db->escapeString($packagename);

  $mysql_users = $this->listMySQLUsers($packagename);
  foreach($mysql_users as $details) {
   $this->removeMySQLUser($packagename, $details["shortusername"]);
  }

  $mysql_databases = $this->listMySQLDatabases($packagename);
  foreach($mysql_databases as $mysql_database) {
   $this->removeMySQLDatabase($packagename, substr($mysql_database,strlen($packagename) + 1));
  }

  $query = "DELETE FROM hosting WHERE packagename='$packagename'";  
  $this->db->query($query);

  shell_exec("sudo " . dirname(__FILE__) . "/scripts/removeHostingPackage " . escapeshellcmd($packagename));

  $this->__reloadApache();
  $this->__reloadProFTPd();
  $this->__generateEximHostingEmailAddresses();

  return true;
 }

 /**
  * Suspend a Hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @return string Returns true when the package was suspended.
  */
 function suspendHostingPackage($packagename) {
  $packagename = strtolower($packagename);
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $packagename  = $this->db->escapeString($packagename);

  $query = "UPDATE hosting SET suspended = 'true' WHERE packagename='$packagename'";
  $this->db->query($query);

  shell_exec("sudo " . dirname(__FILE__) . "/scripts/suspendHostingPackage " . escapeshellcmd($packagename));  

  $this->disableSSH($packagename);

  $this->__reloadApache();
  $this->__generateProFTPdConfig();

  return true;
 }

 /**
  * Unsuspend a Hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @return string Returns true when the package is unsuspended.
  */
 function unsuspendHostingPackage($packagename) {
  $packagename = strtolower($packagename);
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $packagename  = $this->db->escapeString($packagename);

  $query = "UPDATE hosting SET suspended = 'false' WHERE packagename='$packagename'";  
  $this->db->query($query);

  shell_exec("sudo " . dirname(__FILE__) . "/scripts/unsuspendHostingPackage " . escapeshellcmd($packagename));  

  $this->__reloadApache();
  $this->__generateProFTPdConfig();

  return true;
 }

 /**
  * List the existing hosting packages.
  * @return array Returns an aray containing the currently defined hostingpackages.
  */
 function listHostingPackages() {
  $query = "SELECT packagename FROM hosting ORDER BY packagename";
  $result = $this->db->query($query);
  $return = array();
  while($data = $result->fetchArray(SQLITE3_ASSOC)) {
   if($data["packagename"]) {
    $return[$data["packagename"]] = $this->getHostingPackageDetails($data["packagename"]);
   }
  }
  return $return;
 }

 /**
  * Get the details for the specified Hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @return array Returns an aray containing the current hostingpackage with their details.
  */
 function getHostingPackageDetails($packagename) {
  $packagename = strtolower($packagename);
  $packagename = $this->db->escapeString($packagename);

  $query = "SELECT hosting.packagename as packagename,
                   hosting.storage as storage,
                   hosting.bandwidth as bandwidth,
                   hosting.suspended as suspended
            FROM   hosting
            WHERE  packagename = '$packagename'
            LIMIT  1";

  $result = $this->db->query($query);
  $data = $result->fetchArray(SQLITE3_ASSOC);
  if(count($data)) {
   $data["domains"] = $this->listHostingDomainNames($packagename);
  }
  return $data;
 }

 /**
  * Get the usage details for a specific Hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @return array Returns an aray containing the current used storage and traffic (in MiB).
  */
 function getHostingPackageUsage($packagename) {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $storage = json_decode(shell_exec("sudo " . dirname(__FILE__) . "/scripts/getHostingPackageUsage " . escapeshellcmd($packagename)),true);
  $bandwidth = json_decode(shell_exec("sudo " . dirname(__FILE__) . "/scripts/__getHostingPackageBandwidth " . escapeshellcmd($packagename)),true);

  if ($storage['storage'] >= 0) $storage['storage'] += $this->__getPostgreSQLUsage($packagename);
  if ($storage['storage'] >= 0) $storage['storage'] += $this->__getMySQLUsage($packagename);

  return array_merge($storage, $bandwidth);
 }

 /**
  * Get the usage details for all hostingpackages on the specified server.
  * @return array Returns an aray containing the current used storage (in MiB) per hostingpackage.
  */
 function getHostingPackagesUsage() {
  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/getHostingPackagesUsage"
  );
  $client->setTarget($this);
  $target = $client->get();
  $storage = $target->getHostingPackagesUsage();
  return $storage;

  if ($storage['storage'] >= 0) $storage['storage'] += $this->__getPostgreSQLUsage($packagename);
  if ($storage['storage'] >= 0) $storage['storage'] += $this->__getMySQLUsage($packagename);

  return array_merge($storage, $bandwidth);
 }

 /**
  * Get the cron of a specific hosting package
  * @param string $packagename (unique)name of the hostingpackage.
  * @return string Returns a string with the crontab file of a hostingpackage.
  */
 function getHostingPackageCron($packagename) {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/getHostingPackageCron"
  );
  $client->setTarget($this);
  $target = $client->get();
  $cron = $target->getHostingPackageCron($packagename);
  return $cron;
 }

 /**
  * Set the cron of a specific hosting package
  * @param string $packagename (unique)name of the hostingpackage.
  * @param string $crontab the to be installed crontab.
  * @return boolean Returns a boolean with the result
  */
 function setHostingPackageCron($packagename, $crontab) {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/setHostingPackageCron"
  );
  $client->setTarget($this);
  $target = $client->get();
  return $target->setHostingPackageCron($packagename, $crontab);
 }

 /**
  * Calculate the usage of the PostgreSQL Databases of the specified hosting package.
  * @param string $packagename (unique)name of the hostingpackage.
  * @return array Returns the total storage usage of the PostgreSQL Databases (in MiB) within the specifeid hostingpackage.
  */
 function __getPostgreSQLUsage($packagename) {
  $databases = $this->listPostgreSQLDatabases($packagename);
  $size = 0;

  $postgres = $this->__connectPostgreSQL();
  
  foreach ($databases as $database) {
   $size_query = "SELECT pg_database_size('" . pg_escape_string($database) . "');";
   if(!$result = pg_query($postgres, $size_query)) {
    throw new Exception ("Unable to retrieve the size of PostgreSQL database: " . $database);
   } else {
    $row = pg_fetch_row($result);
    $size += $row[0];
   }
  }

  return round($size/1024/1024);
 }

 /**
  * Calculate the usage of the MySQL Databases of the specified hosting package.
  * @param string $packagename (unique)name of the hostingpackage.
  * @return array Returns the total storage usage of the MySQL Databases (in MiB) within the specifeid hostingpackage.
  */
 function __getMySQLUsage($packagename) {
  $databases = $this->listMySQLDatabases($packagename);
  $size = 0;

  $mysql = $this->__connectMySQL();

  foreach ($databases as $database) {
   $query = $mysql->prepare("USE :db");
   $result = $query->execute(array("db" => $database));

   $size_query = $mysql->prepare("SHOW TABLE STATUS");
   if(!$size_result = $size_query->execute()) {
    throw new Exception ("Unable to retrieve the size of MySQL database: " . $database);
   }
   else {
    while($size_row = $size_query->fetch(PDO::FETCH_ASSOC)) {
     $size += $size_row['Data_length'];
     $size += $size_row['Index_length'];
    }
   }
  }

  return round($size/1024/1024);
 }

 /**
  * Export hostingpackage data
  * @param string $packagename (unique)name of the new hostingpackage.
  * @return string Returns URL of hostingpackage data archive
  */
 function exportHostingPackage($packagename) {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
    throw new Exception ("Hostingpackage does not exist");
  }

  do {
   $token = trim(`dd if=/dev/urandom bs=1k count=1 2>/dev/null |sha224sum |awk '{ print $1 }'`);
  } while (file_exists("/usr/local/share/thomsoft-cloud/api/export/$token.tar.gz"));

  if (!is_dir("/usr/local/share/thomsoft-cloud/api/export")) {
   shell_exec("mkdir -p /usr/local/share/thomsoft-cloud/api/export");
  }

  $this->__archiveHostingPackage(
	$packagename,
	"/usr/local/share/thomsoft-cloud/api/export/$token.tar.gz"
  );

  return "/export/$token.tar.gz";
 }
 

 /**
  * Archive hostingpackage data
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $path path for the archive to be saved.
  * @return boolean True iff archive was successful.
  */
 function __archiveHostingPackage($packagename, $path = "") {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
    throw new Exception ("Hostingpackage does not exist");
  }
  if (strlen($path) == 0) {
	$path = "/var/local/hostingplatform/backups/";
	$path .= $packagename;
	$path .= "_";
	$path .= date("Y-m-d_H-i");
	$path .= ".tar.gz";
  }

  $client = new ESRPCConnection();
  $client->connect(
	"sudo /usr/local/share/hostingplatform/scripts/__backupHostingPackage"
  );
  $client->setTarget($this);
  $target = $client->get();
  $target->createArchive($packagename, $path);

  return file_exists($path);
 }
 

 /**
  * Create snapshot of hostingpackage data
  * @param string $packagename (unique)name of the new hostingpackage.
  * @return string snapshot name
  */
 function __snapshotHostingPackage($packagename) {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
    throw new Exception ("Hostingpackage does not exist");
  }

  $client = new ESRPCConnection();
  $client->connect(
	"sudo /usr/local/share/hostingplatform/scripts/__snapshotHostingPackage"
  );
  $client->setTarget($this);
  $target = $client->get();
  return $target->run($packagename);
 }
 

 /**
  * Purge snapshots of hostingpackage data
  * @param string $packagename (unique)name of the new hostingpackage.
  * @return string snapshot name
  */
 function __purgeSnapshots($packagename) {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
    throw new Exception ("Hostingpackage does not exist");
  }

  $client = new ESRPCConnection();
  $client->connect(
	"sudo /usr/local/share/hostingplatform/scripts/__purgeSnapshots"
  );
  $client->setTarget($this);
  $target = $client->get();
  return $target->run($packagename);
 }
 

 /**
  * Import hostingpackage data
  * @param string $packagename (unique)name of the new hostingpackage.
  * @return string $url URL of hostingpackage data archive
  * @return boolean Returns true on success
  */
 function importHostingPackage($packagename, $url) {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }

  if(!strlen(trim($url))) {
    throw new Exception ("No url supplied");
  }

  $client = new ESRPCConnection();
  $client->connect(
	"sudo /usr/local/share/hostingplatform/scripts/__restoreHostingPackage"
  );
  $client->setTarget($this);
  $target = $client->get();
  $target->restoreArchive($packagename, $url);
 
  return true;
 }
 

 /**
  * Add a domainname to an existing hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $domainname the domainname.
  * @param string $operationmode the operation mode of the domain (ie. http, https, mixed, redirect).
  * @param string $ipv4 the IPv4 address to bind the domainname to.
  * @param string $ipv6 the IPv6 address to bind the domainname to.
  * @param string $platform the Platform version to use (default '8.2' for PHP 8.2)
  * @return boolean Returns true adding was successfull.
  */
 function addDomainName($packagename, $domainname, $operationmode = "http", $ipv4 = "", $ipv6 = "", $platform = "8.2") {
  $packagename = strtolower($packagename);
  $domainname  = strtolower($domainname);
  $operationmode = strtolower($operationmode);
  $operationmodes = array("http", "https", "mixed", "redirect");
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($domainname) || !stripos($domainname, ".")) {
    throw new Exception ("No or invalid domainname supplied");
  }
  if(!in_array($operationmode,$operationmodes)) {
    throw new Exception ("The supplied operation mode '" . $operationmode . "' is invalid");
  }

  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $packagename   = $this->db->escapeString($packagename);
  $domainname    = $this->db->escapeString($domainname);
  $operationmode = $this->db->escapeString($operationmode);
  $ipv4          = $this->db->escapeString($ipv4);
  $ipv6          = $this->db->escapeString($ipv6);
  $platform      = $this->db->escapeString($platform);

  $check_query = "SELECT count(hosting_domains.domainname) as matched FROM hosting_domains WHERE hosting_domains.domainname = '$domainname'";
  $check_result = $this->db->query($check_query);
  $check_data = $check_result->fetchArray(SQLITE3_ASSOC);
  if($check_data["matched"]) {
    throw new Exception ("Domainname is already connected to a hostingpackage on this server");
  }

  //Assign the server default IP's when no IP-addresses are specified
  if(empty($ipv4) || empty($ipv6)) {
   $query = "SELECT setting, value FROM server_settings WHERE setting IN ('ipv4', 'ipv6')";
   $result = $this->db->query($query);
   $server_settings = array();
   while($server_settings_data = $result->fetchArray(SQLITE3_ASSOC)) {
    $server_settings[$server_settings_data["setting"]] = $server_settings_data["value"];
   }
   if(empty($ipv4) && !empty($server_settings["ipv4"])) {
    $ipv4 = $server_settings["ipv4"];
   }
   if(empty($ipv6) && !empty($server_settings["ipv6"])) {
    $ipv6 = $server_settings["ipv6"];
   }
  }

  shell_exec("sudo " . dirname(__FILE__) . "/scripts/addDomainName " . escapeshellcmd($packagename) . " " . escapeshellcmd($domainname) . " " . escapeshellcmd($operationmode) . " " . escapeshellcmd($ipv4) . " " . escapeshellcmd($ipv6));

  $insert_query = "INSERT INTO hosting_domains (packagename, domainname, operationmode, ipv4, ipv6, platform)
                               VALUES          ('$packagename', '$domainname', '$operationmode', nullif('$ipv4',''), nullif('$ipv6',''), nullif('$platform',''))";

  $this->db->query($insert_query);

  $this->__generateApacheVHOST($packagename);

  return $this->__createInitialPage($domainname);
 }

 /**
  * Get the Snapshot Hours
  * @return array Returns a list of the snapshot hours
  */
 function getSnapshotHours() {
   $query = "SELECT hour FROM backup_schedule ORDER BY hour";
   $result = $this->db->query($query);
   while($data = $result->fetchArray(SQLITE3_ASSOC)) {
    $hours[] = $data["hour"];
   }
   return $hours;
 }

 /**
  * Delete / Flush the Snapshot Hours
  * @return boolean Returns true if succesfull
  */
 function deleteSnapshotHours() {
   $query = "DELETE FROM backup_schedule";
   $result = $this->db->query($query);
   return true;
 }

 /**
  * Add a Snapshot Hour
  * @param integer $hour
  * @return boolean Returns true if succesfull
  */
 function addSnapshotHour($hour) {
   $hour = $this->db->escapeString($hour);
   $insert_query = "INSERT INTO backup_schedule (hour) VALUES ($hour)";
   $this->db->query($insert_query);
   return true;
 }

 /**
  * Set Snapshot Hours
  * @param array $hours
  * @return boolean Returns true if succesfull
  */
 function setSnapshotHours($hours) {   
   foreach($hours as $hour) {
    $hour = $this->db->escapeString($hour);
    $insert_query = "INSERT INTO backup_schedule (hour) VALUES ($hour)";
    $this->db->query($insert_query);
   }
   return true;
 }

 /**
  * Get the private key for the specified domainname.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $domainname the domainname.
  * @return string Returns the private key
  */
 function getDomainPrivateKey($packagename, $domainname) {
  $packagename = strtolower($packagename);
  $domainname  = strtolower($domainname);

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($domainname) || !stripos($domainname, ".")) {
    throw new Exception ("No or invalid domainname supplied");
  }

  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/getDomainPrivateKey"
  );
  $client->setTarget($this);
  $target = $client->get();
  return $target->getDomainPrivateKey($packagename, $domainname);
 }

 /**
  * Set the private key for a specified domainname.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $domainname the domainname.
  * @param string $key the private key.
  * @return boolean Returns true key was set successfull.
  */
 function setDomainPrivateKey($packagename, $domainname, $key) {
  $packagename = strtolower($packagename);
  $domainname  = strtolower($domainname);
  $key         = trim($key);

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($domainname) || !stripos($domainname, ".")) {
    throw new Exception ("No or invalid domainname supplied");
  }

  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/setDomainPrivateKey"
  );
  $client->setTarget($this);
  $target = $client->get();
  $target->setDomainPrivateKey($packagename, $domainname, $key);

  $this->__generateApacheVHOST($packagename);
  return true;
 }

 /**
  * Get the private key for the server.
  * @return string Returns the private key
  */
 function getServerPrivateKey() {
  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/getServerPrivateKey"
  );
  $client->setTarget($this);
  $target = $client->get();
  return $target->getServerPrivateKey();
 }

 /**
  * Get the SSL Certificate for a specified domainname.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $domainname the domainname.
  * @return string Returns the certificate
  */
 function getDomainCertificate($packagename, $domainname) {
  $packagename = strtolower($packagename);
  $domainname  = strtolower($domainname);

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($domainname) || !stripos($domainname, ".")) {
    throw new Exception ("No or invalid domainname supplied");
  }

  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/getDomainCertificate"
  );
  $client->setTarget($this);
  $target = $client->get();
  return $target->getDomainCertificate($packagename, $domainname);
 }

 /**
  * Set the SSL Certificate for a specified domainname.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $domainname the domainname.
  * @param string $certificate the certificate.
  * @return boolean Returns true certificate was set successfull.
  */
 function setDomainCertificate($packagename, $domainname, $certificate) {
  $packagename = strtolower($packagename);
  $domainname  = strtolower($domainname);
  $certificate = trim($certificate);

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($domainname) || !stripos($domainname, ".")) {
    throw new Exception ("No or invalid domainname supplied");
  }

  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/setDomainCertificate"
  );
  $client->setTarget($this);
  $target = $client->get();
  $target->setDomainCertificate($packagename, $domainname, $certificate);

  $this->__generateApacheVHOST($packagename);
  return true;
 }

 /**
  * Get the SSL Certificate for the server.
  * @return string Returns the certificate
  */
 function getServerCertificate() {
  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/getServerCertificate"
  );
  $client->setTarget($this);
  $target = $client->get();
  return $target->getServerCertificate();
 }

 /**
  * Set the SSL Certificate for the server.
  * @param string $certificate the certificate.
  * @param string $key the private key.
  * @return boolean Returns true certificate was set successfull.
  */
 function setServerCertificate($certificate, $key) {
  $certificate = trim($certificate);
  $key         = trim($key);

  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/setServerCertificate"
  );
  $client->setTarget($this);
  $target = $client->get();
  $target->setServerCertificate($certificate);

  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/setServerPrivateKey"
  );
  $client->setTarget($this);
  $target = $client->get();
  $target->setServerPrivateKey($key);

  $this->__reloadHostingPlatformApache();
  $this->__generateApacheDefaultVHOST();
  $this->__reloadApache();
  $this->__generateProFTPdConfig();
  return true;
 }

 /**
  * Get the SSL operation mode for a specified domainname.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $domainname the domainname.
  * @return string Returns the operation mode of the specified domain.
  */
 function getSSLOperationMode($packagename, $domainname) {
  $packagename  = $this->db->escapeString(strtolower($packagename));
  $domainname  = $this->db->escapeString(strtolower($domainname));

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($domainname) || !stripos($domainname, ".")) {
    throw new Exception ("No or invalid domainname supplied");
  }

  $query = "SELECT operationmode FROM hosting_domains WHERE packagename = '$packagename' AND domainname = '$domainname'

            UNION

            SELECT operationmode FROM domain_aliases WHERE alias = '$domainname'";

  $result = $this->db->query($query);
  $data = $result->fetchArray(SQLITE3_ASSOC);
  return $data["operationmode"];
 }

 /**
  * Set the SSL operation mode for a specified domainname.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $domainname the domainname.
  * @param string $operationmode the operation mode (http, https, redirect or mixed)
  * @return boolean Returns true mode was set successfull.
  */
 function setSSLOperationMode($packagename, $domainname, $operationmode) {
  $packagename   = strtolower($packagename);
  $domainname    = strtolower($domainname);
  $operationmode = trim(strtolower($operationmode));
  $modes         = array("http","https","redirect","mixed");

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($domainname) || !stripos($domainname, ".")) {
    throw new Exception ("No or invalid domainname supplied");
  }
  if(!in_array($operationmode, $modes)) {
    throw new Exception ("Operationmode is not valid, valid values are 'http','https','redirect' and 'mixed'");
  }

  $query = "UPDATE hosting_domains SET operationmode = '$operationmode'
                                   WHERE
                                       packagename  = '$packagename' AND
                                       domainname   = '$domainname'";
  $this->db->query($query);

  $query = "UPDATE domain_aliases SET operationmode = '$operationmode'
                                  WHERE
                                      domain IN (SELECT domainname FROM hosting_domains WHERE packagename = '$packagename') AND
                                      alias = '$domainname'";
  $this->db->query($query);
  $this->__generateApacheVHOST($packagename);
  return true;
 }

 /**
  * Get the PHP version for a specified domainname.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $domainname the domainname.
  * @return string Returns the operation mode of the specified domain.
  */
 function getPHPVersion($packagename, $domainname) {
  $packagename  = $this->db->escapeString(strtolower($packagename));
  $domainname  = $this->db->escapeString(strtolower($domainname));

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($domainname) || !stripos($domainname, ".")) {
    throw new Exception ("No or invalid domainname supplied");
  }

  $query = "SELECT php FROM hosting_domains WHERE packagename = '$packagename' AND domainname = '$domainname'

            UNION

            SELECT php FROM domain_aliases WHERE alias = '$domainname'";

  $result = $this->db->query($query);
  $data = $result->fetchArray(SQLITE3_ASSOC);
  return $data["php"];
 }

 /**
  * Set the Platform for a specified domainname.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $domainname the domainname.
  * @param string $platform the php version or python
  * @return boolean Returns true mode was set successfull.
  */
 function setDomainPlatform($packagename, $domainname, $platform) {
  $packagename   = strtolower($packagename);
  $domainname    = strtolower($domainname);
  $platform      = trim(strtolower($platform));
  $versions      = array("", "python");

  //Detect installed PHP versions
  if($dh = opendir("/etc/php/")) {
   while(($version = readdir($dh)) !== false) {
    if(is_numeric($version)) {
     $versions[] = $version;
    }
   }
  }

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($domainname) || !stripos($domainname, ".")) {
    throw new Exception ("No or invalid domainname supplied");
  }
  if(!in_array($platform, $versions)) {
    throw new Exception ("Platform version is not valid, valid values are '" . implode("', '", $versions) . "'");
  }

  $query = "UPDATE hosting_domains SET platform = NULLIF('$platform','')
                                   WHERE
                                       packagename  = '$packagename' AND
                                       domainname   = '$domainname'";
  $this->db->query($query);

  $query = "UPDATE domain_aliases SET platform = NULLIF('$platform','')
                                  WHERE
                                      domain IN (SELECT domainname FROM hosting_domains WHERE packagename = '$packagename') AND
                                      alias = '$domainname'";
  $this->db->query($query);
  $this->__generateApacheVHOST($packagename);
  return true;
 }

 /**
  * Add an domainalais for an existing domain in a hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $domainname the primary domainname.
  * @param string $alias the alias domainname.
  * @return string Returns true adding was successfull.
  */
 function addDomainAlias($packagename, $domainname, $alias) {
  $packagename = strtolower($packagename);
  $domainname  = strtolower($domainname);
  $alias       = strtolower($alias);

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($domainname) || !stripos($domainname, ".")) {
    throw new Exception ("No or invalid domainname supplied");
  }

  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $domainname = $this->db->escapeString($domainname);
  $alias      = $this->db->escapeString($alias);

  $check_query = "SELECT count(hosting_domains.domainname) as domain_connected FROM hosting_domains WHERE domainname = '$domainname' AND packagename = '$packagename'";
  $check_result = $this->db->query($check_query);
  $check_data = $check_result->fetchArray(SQLITE3_ASSOC);

  if(!$check_data["domain_connected"]) {
   throw new Exception ("Specified domainname is not connected to the hostingpackage");
  }

  $check_query = "SELECT count(domain_aliases.domain) as already_exists FROM domain_aliases WHERE domain = '$domainname' AND alias = '$alias'";
  $check_result = $this->db->query($check_query);
  $check_data = $check_result->fetchArray(SQLITE3_ASSOC);
  if(!$check_data["already_exists"]) {
   $insert_query = "INSERT INTO domain_aliases (domain, alias) VALUES ('$domainname', '$alias')";
   $this->db->query($insert_query);
  }

  $this->__generateApacheVHOST($packagename);

  return true;
 }
 
 /**
  * Remove an domainalais of an existing domain in a hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $domainname the primary domainname.
  * @param string $alias the alias domainname.
  * @return string Returns true adding was successfull.
  */
 function removeDomainAlias($packagename, $domainname, $alias) {
  $packagename = strtolower($packagename);
  $domainname  = strtolower($domainname);
  $alias       = strtolower($alias);

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($domainname) || !stripos($domainname, ".")) {
    throw new Exception ("No or invalid domainname supplied");
  }

  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $domainname = $this->db->escapeString($domainname);
  $alias      = $this->db->escapeString($alias);

  $delete_query = "DELETE FROM domain_aliases WHERE domain = '$domainname' AND alias = '$alias'";
  $this->db->query($delete_query);

  $this->__generateApacheVHOST($packagename);

  return true;
 }

 /**
  * List the domains connected to the specified hosting package.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @return array Returns an aray containing the currently connected domainnames.
  */
 function listHostingDomainNames($packagename) {
  $packagename = strtolower($packagename);
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $packagename  = $this->db->escapeString($packagename);

  $query = "SELECT hosting_domains.domainname as domainname,
                   hosting_domains.operationmode as operationmode,
                   hosting_domains.stats as stats
            FROM   hosting_domains
            WHERE  hosting_domains.packagename = '$packagename'
            ORDER BY
                   hosting_domains.domainname";
  $result = $this->db->query($query);
  $return = array();
  while($data = $result->fetchArray(SQLITE3_ASSOC)) {
   if($data["domainname"]) {
    $return[$data["domainname"]] = $data;
    $domain = $this->db->escapeString($data["domainname"]);
    $alias_query = "SELECT alias FROM domain_aliases WHERE domain = '$domain'";
    $alias_result = $this->db->query($alias_query);
    while($alias_data = $alias_result->fetchArray(SQLITE3_ASSOC)) {
     $return[$data["domainname"]]["aliasses"][] = $alias_data["alias"];
    }
   }
  }
  return $return;
 }

 /**
  * Remove a domainname from a Hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $domainname the domainname.
  * @return string Returns true when the package was succesfully marked to be removed.
  */
 function removeDomainName($packagename, $domainname) {
  $packagename = strtolower($packagename);
  $domainname  = strtolower($domainname);
  
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $packagename  = $this->db->escapeString($packagename);

  $check_query = "SELECT count(hosting_domains.domainname) as matched FROM hosting_domains WHERE hosting_domains.packagename = '$packagename' AND hosting_domains.domainname = '$domainname'";
  $check_result = $this->db->query($check_query);
  $check_data = $check_result->fetchArray(SQLITE3_ASSOC);
  if(!$check_data["matched"]) {
    throw new Exception ("Specified domainname is not connected to the hostingpackage");
  }

  $query = "DELETE FROM hosting_domains WHERE hosting_domains.packagename='$packagename' AND hosting_domains.domainname = '$domainname'";
  $this->db->query($query);

  $this->__generateApacheVHOST($packagename);

  shell_exec("sudo " . dirname(__FILE__) . "/scripts/removeDomainName " . escapeshellcmd($packagename) . " " . escapeshellcmd($domainname));

  return true;
 }

 /**
  * List the FTP users connected to the specified hosting package.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @return array Returns an aray containing the FTP Users.
  */
 function listFTPUsers($packagename) {
  $packagename = strtolower($packagename);

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }

  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $packagename  = $this->db->escapeString($packagename);

  $query = "SELECT hosting_ftpusers.username as username,
                   hosting_ftpusers.password as password,
                   hosting_ftpusers.chroot as chroot
            FROM   hosting_ftpusers
            WHERE  hosting_ftpusers.packagename = '$packagename'
            ORDER BY
                   hosting_ftpusers.username";
  $result = $this->db->query($query);
  $return = array();
  while($data = $result->fetchArray(SQLITE3_ASSOC)) {
   $return[$data["username"]] = $data;
  }
  return $return;
 }

 /**
  * Add a FTP User to an existing hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $username the username.
  * @param string $password the password.
  * @param string $chroot the chroot for the FTP user (optional).
  * @return string Returns true when adding was successfull.
  */
 function addFTPUser($packagename, $username, $password, $chroot = null) {
  $packagename = strtolower($packagename);
  $username    = strtolower($username);

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($username)) {
    throw new Exception ("No or invalid username supplied");
  }
  if(!trim($password)) {
    throw new Exception ("No or invalid password supplied");
  }
  elseif(trim($password) && substr($password,0,3) != "$1$") {
   $password = crypt($password);
  }
  if(!trim($chroot)) {
   $chroot = "/home/" . $packagename . "/";
  }

  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $packagename = $this->db->escapeString($packagename);
  $username    = $this->db->escapeString($username);
  $password    = $this->db->escapeString($password);
  $chroot      = $this->db->escapeString($chroot);

  $check_query = "SELECT count(hosting_ftpusers.username) as matched FROM hosting_ftpusers WHERE hosting_ftpusers.username = '$username'";
  $check_result = $this->db->query($check_query);
  $check_data = $check_result->fetchArray(SQLITE3_ASSOC);
  if($check_data["matched"]) {
    throw new Exception ("Username already exists on this server");
  }

  $insert_query = "INSERT INTO hosting_ftpusers (packagename, username, password, chroot)
                               VALUES           ('$packagename', '$username', '$password', '$chroot')";

  $this->db->query($insert_query);

  $this->__generateProFTPdConfig();

  return true;
 }

 /**
  * Update an existing FTP User.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $username the username.
  * @param string $password the password.
  * @param string $chroot the chroot for the FTP user (optional).
  * @return string Returns true when the modification was successfull.
  */
 function updateFTPUser($packagename, $username, $password, $chroot = null) {
  $packagename = strtolower($packagename);
  $username    = strtolower($username);

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($username)) {
    throw new Exception ("No or invalid username supplied");
  }
  if(!trim($password) || substr($password,0,3) != "$1$") {
    throw new Exception ("No or invalid password supplied, password needs to be supplied as Crypt()");
  }
  if(!trim($chroot)) {
   $chroot = "/home/" . $packagename . "/";
  }

  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $packagename = $this->db->escapeString($packagename);
  $username    = $this->db->escapeString($username);
  $password    = $this->db->escapeString($password);
  $chroot      = $this->db->escapeString($chroot);

  $check_query = "SELECT count(hosting_ftpusers.username) as matched FROM hosting_ftpusers WHERE hosting_ftpusers.username = '$username'";
  $check_result = $this->db->query($check_query);
  $check_data = $check_result->fetchArray(SQLITE3_ASSOC);
  if(!$check_data["matched"]) {
   $this->addFTPUser($packagename, $username, $password, $chroot);
   return true;
  }

  $update_query = "UPDATE hosting_ftpusers SET password = '$password',
                                               chroot   = '$chroot'
                          WHERE                packagename = '$packagename' AND
                                               username    = '$username'";
  $this->db->query($update_query);

  $this->__generateProFTPdConfig();

  return true;
 }

 /**
  * Remove an FTP User from an existing hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $username the username.
  * @return string Returns true when removal was successfull.
  */
 function removeFTPUser($packagename, $username) {
  $packagename = strtolower($packagename);
  $username    = strtolower($username);

  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!trim($username)) {
    throw new Exception ("No or invalid username supplied");
  }

  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $packagename = $this->db->escapeString($packagename);
  $username    = $this->db->escapeString($username);

  $check_query = "SELECT count(hosting_ftpusers.username) as matched FROM hosting_ftpusers WHERE hosting_ftpusers.username = '$username'";
  $check_result = $this->db->query($check_query);
  $check_data = $check_result->fetchArray(SQLITE3_ASSOC);
  if(!$check_data["matched"]) {
    throw new Exception ("Username does not exist");
  }

  $delete_query = "DELETE FROM hosting_ftpusers WHERE hosting_ftpusers.username = '$username' AND hosting_ftpusers.packagename = '$packagename'";

  $this->db->query($delete_query);

  $this->__generateProFTPdConfig();

  return true;
 }

 /**
  * Add a MySQL User to an existing hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $username the MySQL username.
  * @param string $password the password.
  * @return string Returns true when removal was successfull.
  */
 function addMySQLUser($packagename, $username, $password) {
  $packagename = strtolower($packagename);
  $username    = strtolower($username);

  $mysql_user = ($username ? $packagename . "_" . $username : $packagename);
  if(strlen($mysql_user) > 16) {
   throw new Exception ("MySQL username is too long, combination of packagename and username cannot exceed 16 characters");
  }
  $mysql = $this->__connectMySQL();

  $check_query  = $mysql->prepare("SELECT count(User) as `check` FROM user WHERE User = :mysql_user LIMIT 1");
  $check_result = $check_query->execute(array("mysql_user" => $mysql_user));
  $check_data   = $check_query->fetch(PDO::FETCH_ASSOC);
  $check        = $check_data["check"];
  if($check) {
   throw new Exception ("MySQL user already exists");
  }

  if(substr($password,0,1) != "*" || strlen($password) != 41) {
   $password_query  = $mysql->prepare("SELECT PASSWORD(:password) AS password");
   $password_result = $password_query->execute(array("password" => $password));
   $password_data   = $password_query->fetch(PDO::FETCH_ASSOC);
   $password        = $password_data["password"];
  }

  $user_query = $mysql->prepare("CREATE OR REPLACE USER :mysql_user@:host IDENTIFIED BY PASSWORD :password");
  if(!$user_result = $user_query->execute(array("host" => "localhost", "mysql_user" => $mysql_user, "password" => $password))) {
   $this->removeMySQLUser($packagename, $username);
   throw new Exception ("MySQL user creation failed");
  }
  $this->__reloadMySQL();
  return true;
 }

 /**
  * Update the details (password) of a MySQL User.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $username the MySQL username.
  * @param string $password the new password.
  * @return string Returns true when removal was successfull.
  */
 function updateMySQLUser($packagename, $username, $password) {
  $packagename = strtolower($packagename);
  $username    = strtolower($username);

  $mysql_user = ($username ? $packagename . "_" . $username : $packagename);
  if(strlen($mysql_user) > 16) {
   throw new Exception ("MySQL username is too long, combination of packagename and username cannot exceed 16 characters");
  }
  $mysql = $this->__connectMySQL();

  $check_query  = $mysql->prepare("SELECT count(User) as `check` FROM user WHERE User = :mysql_user LIMIT 1");
  $check_result = $check_query->execute(array("mysql_user" => $mysql_user));
  $check_data   = $check_query->fetch(PDO::FETCH_ASSOC);
  $check        = $check_data["check"];
  if(!$check) {
   $this->addMySQLUser($packagename, $username, $password);
  }
  else {
   if(substr($password,0,1) != "*" || strlen($password) != 41) {
    $user_query = $mysql->prepare("SET PASSWORD FOR :mysql_user@:host = PASSWORD(:password)");
   }
   else {
    $user_query = $mysql->prepare("SET PASSWORD FOR :mysql_user@:host = :password");
   }
   if(!$user_result = $user_query->execute(array("mysql_user" => $mysql_user, "host" => "localhost", "password" => $password))) {
    throw new Exception ("MySQL user update failed");
   }
   $this->__reloadMySQL();
   return true;
  }
 }

 /**
  * Remove an MySQL User from an existing hostingpackage.
  * @param string $packagename (unique)name of the new hostingpackage.
  * @param string $username the MySQL username.
  * @return string Returns true when removal was successfull.
  */
 function removeMySQLUser($packagename, $username) {
  $packagename = strtolower($packagename);
  $username    = strtolower($username);

  $mysql_user = ($username ? $packagename . "_" . $username : $packagename);

  $mysql = $this->__connectMySQL();

  $user_delete_query = $mysql->prepare("DROP USER IF EXISTS :mysql_user");
  if(!$user_delete_query->execute(array("mysql_user" => $mysql_user))) {
   throw new Exception ("MySQL removal from user failed");
  }

  $user_delete_query = $mysql->prepare("DROP USER IF EXISTS :mysql_user@:host");
  if(!$user_delete_query->execute(array("mysql_user" => $mysql_user, "host" => "localhost"))) {
   throw new Exception ("MySQL removal from user failed");
  }

  $this->__reloadMySQL();
  return true;
 }

 /**
  * List the existing MySQL Users for the specified hosting package.
  * @param string $packagename (unique)name of the hostingpackage.
  * @return array Returns an aray containing the currently defined MySQL Users within the specifeid hostingpackage.
  */
 function listMySQLUsers($packagename) {
  $packagename = strtolower($packagename);

  if(!$packagename) {
   throw new Exception ("No hosting packagename supplied");
  }

  $mysql = $this->__connectMySQL();

  $list_query = $mysql->prepare("SELECT User FROM user WHERE User = :packagename OR User LIKE :db_prefix ORDER BY User");
  $return = array();
  $list_result = $list_query->execute(array("packagename" => $packagename, "db_prefix" => $packagename . "\_%"));
  while($list_data = $list_query->fetch(PDO::FETCH_ASSOC)) {
   $parts = explode("_", $list_data["User"]);
   $return[] = array("fullusername" => $list_data["User"], "shortusername" => (isset($parts[1]) ? $parts[1] : ""));
  }
  return $return;
 }

 /**
  * List the existing PostgreSQL Users for the specified hosting package.
  * @param string $packagename (unique)name of the hostingpackage.
  * @return array Returns an aray containing the currently defined PostgreSQL Users within the specifeid hostingpackage.
  */
 function listPostgreSQLUsers($packagename) {
  $packagename = strtolower($packagename);

  $postgresql = $this->__connectPostgreSQL();

  if(!$packagename) {
   throw new Exception ("No hosting packagename supplied");
  }

  $list_query = "SELECT usename as username FROM pg_user WHERE usename ILIKE '" . pg_escape_string($packagename) . "' OR usename ILIKE '" . pg_escape_string($packagename) . "_%' ORDER BY usename";
  return $list_query;
  $return = array();
  $list_result = pg_query($list_query);
  while($list_data = pg_fetch_assoc($list_result)) {
   $parts = explode("_", $list_data["username"]);
   $return[] = array("fullusername" => $list_data["username"], "shortusername" => (isset($parts[1]) ? $parts[1] : ""));
  }
  return $return;
 }

 /**
  * List the existing MySQL Databases for the specified hosting package.
  * @param string $packagename (unique)name of the hostingpackage.
  * @return array Returns an aray containing the currently defined MySQL Databases within the specifeid hostingpackage.
  */
 function listMySQLDatabases($packagename) {
  $packagename = strtolower($packagename);

  if(!$packagename) {
   throw new Exception ("No hosting packagename supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $mysql = $this->__connectMySQL();

  $list_query = $mysql->prepare("SHOW DATABASES LIKE :db_prefix");
  $list_result = $list_query->execute(array("db_prefix" => $packagename . "\_%"));
  $return = array();
  while($list_data = $list_query->fetch(PDO::FETCH_NUM)) {
   $return[] = $list_data[0];
  }
  return $return;
 }

 /**
  * List the tables of a MySQL Databases for the specified hosting package.
  * @param string $packagename (unique)name of the hostingpackage.
  * @return array Returns an aray containing the currently defined MySQL Databases within the specifeid hostingpackage.
  */
 function listMySQLTables($database) {
  $database = strtolower($database);

  $mysql = $this->__connectMySQL();

  $list_query = $mysql->prepare("SELECT TABLE_NAME, COALESCE(UPDATE_TIME, CREATE_TIME) AS UPDATE_TIME FROM information_schema.tables WHERE TABLE_SCHEMA = :database");
  $list_result = $list_query->execute(array("database" => $database));
  $return = array();
  while($list_data = $list_query->fetch(PDO::FETCH_ASSOC)) {
   $return[$list_data["TABLE_NAME"]] = array("name"     => $list_data["TABLE_NAME"],
                                             "modified" => $list_data["UPDATE_TIME"]);
  }
  return $return;
 }

 /**
  * Check if a MySQL database exists for a hostingpackage.
  * @param string $packagename Name of the hostingpackage
  * @param string $database Name of the database
  * @return boolean True iff database exists
  */
 function isMySQLDatabase($packagename, $database) {
	$databases = $this->listMySQLDatabases($packagename);
	return in_array($database, $databases);
 }

 /**
  * List the existing PostgreSQL Databases for the specified hosting package.
  * @param string $packagename (unique)name of the hostingpackage.
  * @return array Returns an aray containing the currently defined PostgreSQL Databases within the specifeid hostingpackage.
  */
 function listPostgreSQLDatabases($packagename) {
  $packagename = strtolower($packagename);

  if(!$packagename) {
   throw new Exception ("No hosting packagename supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $postgresql = $this->__connectPostgreSQL();

  $list_query = "SELECT d.datname as Name,
                        r.rolname as Owner,
                        pg_catalog.pg_encoding_to_char(d.encoding) as Encoding
                 FROM pg_catalog.pg_database d
                 JOIN pg_catalog.pg_roles r ON d.datdba = r.oid
                 WHERE  d.datname ILIKE '" . pg_escape_string($packagename . "_%") . "'
                 ORDER BY 1";

  if(!$list_result = pg_query($list_query)) {
   throw new Exception ("Unable to retrieve the list of databases");
  }
  $return = array();
  while($list_data = pg_fetch_row($list_result)) {
   $return[] = $list_data[0];
  }
  return $return;
 }

 /**
  * Check if a PostgreSQL database exists for a hostingpackage.
  * @param string $packagename Name of the hostingpackage
  * @param string $database Name of the database
  * @return boolean True iff database exists
  */
 function isPostgreSQLDatabase($packagename, $database) {
	$databases = $this->listPostgreSQLDatabases($packagename);
	return in_array($database, $databases);
 }

 /**
  * Create a MySQL Database within an existing hostingpackage.
  * @param string $packagename (unique)name of the hostingpackage.
  * @param string $database the MySQL database name (this is will start with the packagename).
  * @return string Returns true when creation was successfull.
  */
 function addMySQLDatabase($packagename, $database) {
  $packagename = strtolower($packagename);
  $database    = strtolower($database);

  if(!$packagename) {
   throw new Exception ("No hosting packagename supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $mysql = $this->__connectMySQL();

  $database = preg_replace("/[^A-Za-z0-9-_]/", '', strlen($database) ? $packagename . '_' . $database : $packagename);

  $check_query = $mysql->prepare("SHOW DATABASES LIKE :database");
  $check_result = $check_query->execute(array("database" => $database));
  $check = $check_query->fetchAll();
  if(count($check)) {
   throw new Exception ("The specified database already exists");
  }

  $db_query = $mysql->prepare("CREATE DATABASE " . $database);
  $db_result = $db_query->execute();

  return true;
 }

 /**
  * Create a PostgreSQL Database within an existing hostingpackage.
  * @param string $packagename (unique)name of the hostingpackage.
  * @param string $database the PostgreSQL database name (this is will start with the packagename).
  * @return string Returns true when creation was successfull.
  */
 function addPostgreSQLDatabase($packagename, $database) {
  $packagename = strtolower($packagename);
  $database    = strtolower($database);
  $database = strlen($database) ? $packagename . '_' . $database : $packagename;

  if(!$packagename) {
   throw new Exception ("No hosting packagename supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $postgresql = $this->__connectPostgreSQL();

  $check_query = "SELECT d.datname as Name,
                         r.rolname as Owner,
                         pg_catalog.pg_encoding_to_char(d.encoding) as Encoding
                  FROM pg_catalog.pg_database d
                  JOIN pg_catalog.pg_roles r ON d.datdba = r.oid
                  WHERE  d.datname ILIKE '" . pg_escape_string($database) . "'
                  ORDER BY 1";
  $check_result = pg_query($check_query);
  $check = pg_num_rows($check_result);
  if($check) {
   throw new Exception ("The specified database already exists");
  }
  $db_query = "CREATE DATABASE " . pg_escape_string($database);
  if(!$db_result = pg_query($db_query)) {
   $this->removePostgreSQLDatabase($packagename, $database);
   throw new Exception ("PostgreSQL database creation failed");
  }

  $db_query = "GRANT ALL PRIVILEGES ON DATABASE " . pg_escape_string($database) . " TO " . pg_escape_string($packagename);
  if(!$db_result = pg_query($db_query)) {
   shell_exec("sudo " . dirname(__FILE__) . "/scripts/__addPostgreSQLUser " . escapeshellcmd($packagename));
   if(!$db_result = pg_query($db_query)) {
    $this->removePostgreSQLDatabase($packagename, $database);
    throw new Exception ("Clould not grant privileges on PostgreSQL database to the user.");
   }
  }

  return true;
 }

 /**
  * List the permissions for a specific user for the specified Database
  * @param string $packagename (unique)name of the hostingpackage.
  * @param string $username the MySQL username
  * @param string $database the MySQL database name
  * @return string Return an associative array with permissions and booleans.
  */
 function listMySQLUserPermissions($packagename,$username = "",$database =  "") {
  $packagename = strtolower($packagename);
  $username    = strtolower($username);
  $database    = strtolower($database);

  $permissions = array("SELECT","INSERT","UPDATE","DELETE","CREATE","DROP","REFERENCES","INDEX","ALTER","CREATE_TMP_TABLE","LOCK_TABLES","CREATE_VIEW","SHOW_VIEW");
  if(!$packagename) {
   throw new Exception ("No hosting packagename supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $mysql_user = ($username ? $packagename . "_" . $username : $packagename);

  $mysql = $this->__connectMySQL();

  $username = strlen($username) ? $packagename . "_" . $username : $packagename;
  $database = strlen($database) ? $packagename . "_" . $database : $packagename;

  $user_check_query  = $mysql->prepare("SELECT count(*) as `check` FROM user WHERE user = :username LIMIT 1");
  $user_check_result = $user_check_query->execute(array(":username" => $username));
  $user_check_data   = $user_check_query->fetch(PDO::FETCH_ASSOC);
  $user_check        = $user_check_data["check"];
  if(!$user_check_result) {
   throw new Exception ("Specified MySQL user does not exists");
  }

  $db_check_query = $mysql->prepare("SHOW DATABASES LIKE :database");
  $db_check_result = $db_check_query->execute();
  $db_check = $db_check_query->fetchAll();
  if(!count($db_check)) {
   throw new Exception ("Specified MySQL database does not exists");
  }

  $query = $mysql->prepare("SELECT * FROM db WHERE user = :username AND db = :database LIMIT 1");
  $result = $query->execute(array("username" => $username, "database" => $database));
  $data   = $query->fetch(PDO::FETCH_ASSOC);

  $return = array();
  foreach($permissions as $permission) {
   $return[$permission] = ($data[ucfirst(strtolower($permission)) . "_priv"] == "Y" ? true : false);
  }
  return $return;
 }

 /**
  * Grant Database Permissions to a specific MySQL User
  * @param string $packagename (unique)name of the hostingpackage.
  * @param string $username the MySQL username
  * @param string $database the MySQL database name
  * @param array $permissions the MySQL permissions
  * @return string Returns true when creation was successfull.
  */
 function grantPermissionsToMySQLUser($packagename, $username, $database, $permissions) {
  $packagename = strtolower($packagename);
  $username    = strtolower($username);
  $database    = strtolower($database);
  
  if(!$packagename) {
   throw new Exception ("No hosting packagename supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $mysql_user = ($username ? $packagename . "_" . $username : $packagename);

  if(!$permissions || (is_array($permissions) && !count($permissions))) {
   $permissions = array("SELECT","INSERT","UPDATE","DELETE","CREATE","DROP","REFERENCES","INDEX","ALTER","CREATE_TMP_TABLE","LOCK_TABLES","CREATE_VIEW","SHOW_VIEW");
  }
  elseif(strlen($permissions) >= 1 && !is_array($permissions)) {
   $permissions = array($permissions);
  }

  $mysql = $this->__connectMySQL();

  $db_permissions_exist_query  = $mysql->prepare("SELECT count(*) as exist FROM db WHERE User = :mysql_user AND db = :db LIMIT 1");
  $db_permissions_exits_result = $db_permissions_exist_query->execute(array("mysql_user" => $mysql_user, "db" => $packagename . "_" . $database));
  $db_permissions_exist_data   = $db_permissions_exist_query->fetch(PDO::FETCH_ASSOC);
  $db_permissions_exist        = $db_permissions_exist_data["exist"];

  if(!$db_permissions_exist) {
   $db_permissions_query = $mysql->prepare("INSERT INTO db (Host, User, Db) VALUES (:host, :mysql_user, :mysql_db)");
   if(!$db_permissions_query->execute(array("host" => "localhost", "mysql_user" => $mysql_user, "mysql_db" => $packagename . "_" . $database))) {
    throw new Exception ("Failed to set Basic-permissions on '" . $packagename . "_" . $database . "' to '" . $mysql_user . "'");
   }
  }

  foreach($permissions as $permission) {
   $grant_query = $mysql->prepare("UPDATE db SET "  . preg_replace("/[^A-Za-z0-9-_]/", '', ucfirst(strtolower($permission)) . "_priv") . " = 'Y' WHERE User = :mysql_user AND Db = :mysql_db");
   if(!$grant_query->execute(array("mysql_user" => $mysql_user, "mysql_db" => $packagename . "_" . $database))) {
    throw new Exception ("Failed to set " . $permission . "-permissions on '" . $packagename . "_" . $database . "' to '" . $mysql_user . "'");
   }
  }
  $this->__reloadMySQL();
  return true;
 }
 
 /**
  * Revoke Database Permissions from a specific MySQL User
  * @param string $packagename (unique)name of the hostingpackage.
  * @param string $username the MySQL username
  * @param string $database the MySQL database name
  * @param array $permissions the MySQL permissions
  * @return string Returns true when creation was successfull.
  */
 function revokePermissionsFromMySQLUser($packagename, $username, $database, $permissions) {
  $packagename = strtolower($packagename);
  $username    = strtolower($username);
  $database    = strtolower($database);

  if(!$packagename) {
   throw new Exception ("No hosting packagename supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $mysql_user = ($username ? $packagename . "_" . $username : $packagename);

  if(strlen($permissions) >= 1 && !is_array($permissions)) {
   $permissions = array($permissions);
  }
  
  if(!is_array($permissions) || !count($permissions)) {
   throw new Exception ("No permission supplied");
  }

  $mysql = $this->__connectMySQL();

  $db_permissions_exist_query  = $mysql->prepare("SELECT count(*) as exist FROM db WHERE User = :mysql_user AND db = :db LIMIT 1");
  $db_permissions_exits_result = $db_permissions_exist_query->execute(array("mysql_user" => $mysql_user, "db" => $packagename . "_" . $database));
  $db_permissions_exist_data   = $db_permissions_exist_query->fetch(PDO::FETCH_ASSOC);
  $db_permissions_exist        = $db_permissions_exist_data["exist"];

  foreach($permissions as $permission) {
   $grant_query = $mysql->prepare("UPDATE db SET "  . preg_replace("/[^A-Za-z0-9-_]/", '', ucfirst(strtolower($permission)) . "_priv") . " = 'N' WHERE User = :mysql_user AND Db = :mysql_db");
   if(!$grant_query->execute(array("mysql_user" => $mysql_user, "mysql_db" => $packagename . "_" . $database))) {
    throw new Exception ("Failed to revoke " . $permission . "-permissions on '" . $packagename . "_" . $database . "' from '" . $mysql_user . "'");
   }
  }

  $this->__reloadMySQL();
  return true;
 }

 /**
  * Remove a MySQL database.
  * @param string $packagename (unique)name of the hostingpackage.
  * @param string $database the MySQL database name (this is will start with the packagename).
  * @return string Returns true when creation was successfull.
  */
 function removeMySQLDatabase($packagename, $database) {
  $packagename = strtolower($packagename);
  $database    = strtolower($database);

  if(!$packagename) {
   throw new Exception ("No hosting packagename supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $mysql = $this->__connectMySQL();

  $database = preg_replace("/[^A-Za-z0-9-_]/", '', strlen($database) ? $packagename . '_' . $database : $packagename);

  $check_query = $mysql->prepare("SHOW DATABASES LIKE :database");
  $check_result = $check_query->execute(array("database" => $database));
  $check = $check_query->fetchAll();
  if(!count($check)) {
   throw new Exception ("The specified database does not exists");
  }
  $db_query = $mysql->prepare("DROP DATABASE " . $database);
  $db_result = $db_query->execute();

  return true;
 }

 /**
  * Remove a PostgreSQL database.
  * @param string $packagename (unique)name of the hostingpackage.
  * @param string $database the PostgreSQL database name (the databasename begins with the packagename).
  * @return string Returns true when removal was successfull.
  */
 function removePostgreSQLDatabase($packagename, $database) {
  $packagename = strtolower($packagename);
  $database    = strtolower($database);

  if(!$packagename) {
   throw new Exception ("No hosting packagename supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $postgresql = $this->__connectPostgreSQL();

  $check_query = "SELECT d.datname as Name,
                         r.rolname as Owner,
                         pg_catalog.pg_encoding_to_char(d.encoding) as Encoding
                  FROM pg_catalog.pg_database d
                  JOIN pg_catalog.pg_roles r ON d.datdba = r.oid
                  WHERE  d.datname ILIKE '" . pg_escape_string($packagename . "_" .  $database) . "'
                  ORDER BY 1";

  $check_result = pg_query($check_query);
  $check = pg_num_rows($check_result);
  if(!$check) {
   throw new Exception ("The specified database does not exists");
  }
  $db_query = "DROP DATABASE " . pg_escape_string($packagename . "_" . $database);
  if(!$db_result = pg_query($db_query)) {
   throw new Exception ("PostgreSQL database removal failed");
  }
  return true;
 }

 /**
  * Enable SSH for a specific hostingpakacge.
  * @param string $packagename (unique)name of the hostingpackage.
  * @param string $password the password in either crypted format or plain-text.
  * @param string $type the 'optional'-type of the supplied password (either 'plain' or 'crypt'), default is 'crypt'
  * @return string Returns true when enabling was succesfull
  */
 function enableSSH($packagename, $password, $type = "crypt") {
  if($type != "crypt") {
   $password = crypt($password, "$6$" . rand(1000000000000000000,9999999999999999999));
  }
  shell_exec("sudo " . dirname(__FILE__) . "/scripts/enableSSH " . escapeshellcmd($packagename) . " " . escapeshellcmd($password));
  return true;
 }

 /**
  * Disable SSH for a specific hostingpakacge.
  * @param string $packagename (unique)name of the hostingpackage.
  * @return string Returns true when disabling was succesfull.
  */
 function disableSSH($packagename) {
  shell_exec("sudo " . dirname(__FILE__) . "/scripts/disableSSH " . escapeshellcmd($packagename));
  return true;
 }

 /**
  * Checks the MD5 Hash of Binaries to verify that no infected binary is installed.
  * @param array $check_array An associative array where the key is the filename and the value is the correct hash.
  * @return array Returns an array containing the files with a MD5 mismatch.
  */
 function verifyBinaries($check_array) {
  $return = array();
  foreach($check_array as $file => $correct_md5hash) {
   $check = shell_exec("sudo " . dirname(__FILE__) . "/scripts/verifyBinaries " . escapeshellcmd($file) . " " . escapeshellcmd($correct_md5hash));
   if($check) {
    $return[$file] = $check;
   }
   else {
    $return[$file] = "";
   }
  }
  return $return;
 }

 /**
  * Sets the master FTP prefix and password.
  * @param string $prefix the prefix for the master FTP username.
  * @param string $password the password for the master FTP usernames.
  * @return array Returns an array containing the files with a MD5 mismatch.
  */
 function setMasterFTPAccess($prefix,$password) {
  if(strlen($prefix) < 32) {
   throw new Exception ("The supplied prefix is too short (prefix must be at least 32 chars)");
  }
  if(strlen($password) != 32) {
   throw new Exception ("The supplied password is too short (password must be exact 32 chars)");
  }

  $prefix   = $this->db->escapeString($prefix);
  $password = $this->db->escapeString(crypt($password));

  $delete_query  = "DELETE FROM server_settings WHERE setting IN ('master_ftp_prefix', 'master_ftp_password')";
  $this->db->query($delete_query);

  $insert_query = "INSERT INTO server_settings (setting, value) VALUES ('master_ftp_prefix', '$prefix')";
  $this->db->query($insert_query);

  $insert_query = "INSERT INTO server_settings (setting, value) VALUES ('master_ftp_password', '$password')";
  $this->db->query($insert_query);

  $this->__generateProFTPdConfig();

  return true;
 }

 /**
  * Enable (webalizer) statistics for a specific domainname.
  * @param string $packagename (unique)name of the hostingpackage.
  * @param string $domainname (unique)name of the hostingpackage.
  * @return string Returns true when enabling was succesfull
  */
 function enableStatistics($packagename,$domainname) {
  $domains = $this->listHostingDomainNames($packagename);
  foreach($domains as $domain => $details) {
   if($domain == $domainname) {
    $packagename  = $this->db->escapeString($packagename);
    $domainname   = $this->db->escapeString($domainname);
    $query = "UPDATE hosting_domains SET stats = 1 WHERE packagename = '$packagename' AND domainname = '$domainname'";
    if($this->db->query($query)) {
     return true;
    }
   }
  }
  throw new Exception ("The specified domainname is not connected to the specified hosting package");
 }

 /**
  * Disable (webalizer) statistics for a specific domainname.
  * @param string $packagename (unique)name of the hostingpackage.
  * @param string $domainname (unique)name of the hostingpackage.
  * @return string Returns true when disabling was succesfull
  */
 function disableStatistics($packagename,$domainname) {
  $domains = $this->listHostingDomainNames($packagename);
  foreach($domains as $domain => $details) {
   if($domain == $domainname) {
    $packagename  = $this->db->escapeString($packagename);
    $domainname   = $this->db->escapeString($domainname);
    $query = "UPDATE hosting_domains SET stats = 0 WHERE packagename = '$packagename' AND domainname = '$domainname'";
    if($this->db->query($query)) {
     return true;
    }
   }
  }
  throw new Exception ("The specified domainname is not connected to the specified hosting package");
 }

 /**
  * get Disk Usage for this server
  * @return array Returns array with the details
  */
 function getServerStorage() {
  $df = shell_exec("sudo df -m");
  $df = strtolower($df);
  $lines = explode("\n", $df);
  $return = array();
  foreach($lines as $seq => $line) {
   $line = preg_replace('!\s+!', ' ', $line);
   $line = str_replace("%", "", $line);
   if($seq == 0) {
    $line = str_replace("mounted on", "mount", $line);
    $line = str_replace("1m-blocks", "capacity", $line);
    $keys = explode(" ", $line);
   }
   else {
    $fields = explode(" ", $line);
    if(count($fields) == count($keys)) {
     $return[] = array_combine($keys, $fields);
    }
   }
  }
  return $return;
 }

 /**
  * detect CMS installations
  * @param string $packagename (unique)name of the hostingpackage.
  * @return array Returns array with the details
  */
 function detectCMS($packagename) {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/detectCMS"
  );
  $client->setTarget($this);
  $target = $client->get();

  $return = $target->detectCMS($packagename);
  return $return;
 }

 /**
  * migrate MySQL databases
  * @param string $packagename (unique)name of the source hostingpackage.
  * @param string $password the password of the hostingpackage.
  * @param string $dst_server name of the destination server.
  * @param string $dst_packagename (unique)name of the destination hostingpackage.
  * @return array Returns array with the details
  */
 function migrateMySQLDatabases($packagename, $password, $dst_server, $dst_packagename) {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  if($packagename != $dst_packagename) {
   shell_exec("((mysqldump -u'" . escapeshellcmd($packagename) . "' -p'" . addslashes(preg_replace('/\s+/', '', $password)) . "' --all-databases --no-create-db --skip-comments |  sed --expression='s/USE `" . escapeshellcmd($packagename) . "_/USE `" . escapeshellcmd($dst_packagename) . "_/g' | SSHPASS='" . addslashes(preg_replace('/\s+/', '', $password)) . "' sshpass -e ssh -o 'StrictHostKeyChecking no' " . escapeshellcmd($dst_packagename) . "@" . escapeshellcmd($dst_server) . " mysql -u'" . escapeshellcmd($dst_packagename) . "' -p'" . escapeshellcmd($password) . "') && SSHPASS='" . addslashes(preg_replace('/\s+/', '', $password)) . "' sshpass -e ssh -o 'StrictHostKeyChecking no' " . escapeshellcmd($dst_packagename) . "@" . escapeshellcmd($dst_server) . " wget -q -O /dev/null 'https://mijn.hostingu2.nl/update_migration_status.php?task=databases\\&packagename=" . escapeshellcmd($dst_packagename) . "') &");
  }
  else {
   shell_exec("((mysqldump -u'" . escapeshellcmd($packagename) . "' -p'" . addslashes(preg_replace('/\s+/', '', $password)) . "' --all-databases --no-create-db --skip-comments | SSHPASS='" . addslashes(preg_replace('/\s+/', '', $password)) . "' sshpass -e ssh -o 'StrictHostKeyChecking no' " . escapeshellcmd($dst_packagename) . "@" . escapeshellcmd($dst_server) . " mysql -u'" . escapeshellcmd($dst_packagename) . "' -p'" . escapeshellcmd($password) . "') && SSHPASS='" . addslashes(preg_replace('/\s+/', '', $password)) . "' sshpass -e ssh -o 'StrictHostKeyChecking no' " . escapeshellcmd($dst_packagename) . "@" . escapeshellcmd($dst_server) . " wget -q -O /dev/null 'https://mijn.hostingu2.nl/update_migration_status.php?task=databases\\&packagename=" . escapeshellcmd($dst_packagename) . "') &");
  }
  return true;
 }

 /**
  * migrate Crontab
  * @param string $packagename (unique)name of the source hostingpackage.
  * @param string $password the password of the hostingpackage.
  * @param string $dst_server name of the destination server.
  * @param string $dst_packagename (unique)name of the destination hostingpackage.
  * @return array Returns array with the details
  */
 function migrateCron($packagename, $password, $dst_server, $dst_packagename) {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }
  return("((sudo -u " . escapeshellcmd($packagename) . " /usr/bin/crontab -l | SSHPASS='" . addslashes(preg_replace('/\s+/', '', $password)) . "' sshpass -e ssh -o 'StrictHostKeyChecking no' " . escapeshellcmd($dst_packagename) . "@" . escapeshellcmd($dst_server) . " /usr/bin/crontab -) && SSHPASS='" . addslashes(preg_replace('/\s+/', '', $password)) . "' sshpass -e ssh -o 'StrictHostKeyChecking no' " . escapeshellcmd($dst_packagename) . "@" . escapeshellcmd($dst_server) . " wget -q -O /dev/null 'https://mijn.hostingu2.nl/update_migration_status.php?task=cron\\&packagename=" . escapeshellcmd($dst_packagename) . "') &");
  shell_exec("((sudo -u " . escapeshellcmd($packagename) . " /usr/bin/crontab -l | SSHPASS='" . addslashes(preg_replace('/\s+/', '', $password)) . "' sshpass -e ssh -o 'StrictHostKeyChecking no' " . escapeshellcmd($dst_packagename) . "@" . escapeshellcmd($dst_server) . " /usr/bin/crontab -) && SSHPASS='" . addslashes(preg_replace('/\s+/', '', $password)) . "' sshpass -e ssh -o 'StrictHostKeyChecking no' " . escapeshellcmd($dst_packagename) . "@" . escapeshellcmd($dst_server) . " wget -q -O /dev/null 'https://mijn.hostingu2.nl/update_migration_status.php?task=cron\\&packagename=" . escapeshellcmd($dst_packagename) . "') &");
//  shell_exec("((/usr/bin/crontab -l | SSHPASS='" . addslashes(preg_replace('/\s+/', '', $password)) . "' sshpass -e ssh -o 'StrictHostKeyChecking no' " . escapeshellcmd($dst_packagename) . "@" . escapeshellcmd($dst_server) . " mysql -u'" . escapeshellcmd($dst_packagename) . "' -p'" . escapeshellcmd($password) . "') && SSHPASS='" . addslashes(preg_replace('/\s+/', '', $password)) . "' sshpass -e ssh -o 'StrictHostKeyChecking no' " . escapeshellcmd($dst_packagename) . "@" . escapeshellcmd($dst_server) . " wget -q -O /dev/null 'https://mijn.hostingu2.nl/update_migration_status.php?task=cron\\&packagename=" . escapeshellcmd($dst_packagename) . "') &");
  return true;
 }

 /**
  * migrate Files
  * @param string $packagename (unique)name of the source hostingpackage.
  * @param string $password the password of the hostingpackage.
  * @param string $dst_server name of the destination server.
  * @param string $dst_packagename (unique)name of the destination hostingpackage.
  * @return array Returns array with the details
  */
 function migrateFiles($packagename, $password, $dst_server, $dst_packagename) {
  $packagename = strtolower($packagename);
  if(!strlen(trim($packagename))) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  shell_exec("((sudo sshpass -p '" . addslashes(preg_replace('/\s+/', '', $password)) . "' rsync -avzhe \"ssh -o 'StrictHostKeyChecking no'\" /home/" . escapeshellcmd($packagename) . "/ " . escapeshellcmd($dst_packagename) . "@" . escapeshellcmd($dst_server) . ":/home/" . escapeshellcmd($dst_packagename) . "/ --delete) && SSHPASS='" . addslashes(preg_replace('/\s+/', '', $password)) . "' sshpass -e ssh -o 'StrictHostKeyChecking no' " . escapeshellcmd($dst_packagename) . "@" . escapeshellcmd($dst_server) . " wget -q -O /dev/null 'https://mijn.hostingu2.nl/update_migration_status.php?task=files\\&packagename=" . escapeshellcmd($dst_packagename) . "') &");
  return true;
 }

 /**
  * restore Files
  * @param string $packagename (unique)name of the hostingpackage.
  * @param string $version the version of the snapshot to restore
  * @return array Returns array with the details
  */
 function restoreFiles($packagename, $version) {
  $packagename = trim(mb_strtolower($packagename));
  $version     = trim(mb_strtolower($version));

  if(!strlen($packagename)) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/restoreFiles"
  );
  $client->setTarget($this);
  $target = $client->get();
  $target->restoreFiles($packagename, $version);

  file_get_contents("https://mijn.hostingu2.nl/update_restore_status.php?task=files&packagename=" . urlencode($packagename));
  return true;
 }

 /**
  * restore MySQL Databases
  * @param string $packagename (unique)name of the hostingpackage.
  * @param string $version the version of the snapshot to restore
  * @param string $password the mysql password
  * @return array Returns array with the details
  */
 function restoreMySQLDatabases($packagename, $version, $password) {
  $packagename = trim(mb_strtolower($packagename));
  $version     = trim(mb_strtolower($version));

  if(!strlen($packagename)) {
    throw new Exception ("No hostingpackage name supplied");
  }
  if(!$this->__checkIfHostingPackageExists($packagename)) {
   throw new Exception ("Specified hostingpackage does not exists");
  }

  $client = new ESRPCConnection();
  $client->connect(
    "sudo /usr/local/share/hostingplatform/scripts/restoreMySQLDatabases"
  );
  $client->setTarget($this);
  $target = $client->get();
  $target->restoreMySQLDatabases($packagename, $version, $password);

  file_get_contents("https://mijn.hostingu2.nl/update_restore_status.php?task=databases&packagename=" . urlencode($packagename));
  return true;
 }

 /**
  * Run webalizer for all packages and domains.
  * @return boolean True iff archive was successful.
  */
 function __runWebalizer() {
  $client = new ESRPCConnection();
  $client->connect(
	"sudo /usr/local/share/hostingplatform/scripts/__runWebalizer"
  );
  $client->setTarget($this);
  $target = $client->get();
  return $target->run();
 }


 function __connectMySQL() {
  $config_json = shell_exec("sudo " . dirname(__FILE__) . "/scripts/__connectMySQL");
  $config = json_decode($config_json,true);
  $db = new PDO('mysql:host=localhost;dbname=mysql', $config["user"], $config["password"]);
  if (!$db) {
   throw new Exception(
    "Could not connect to MySQL server: " . $db->errorInfo()
   );
  }
  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
  return $db;
 }

 function __connectPostgreSQL($databaseName = null) {
  $db = pg_connect("dbname=" . ($databaseName ? $databaseName : "postgres"));
  if (!$db) {
   throw new Exception(
    "Could not connect to PostgreSQL server."
   );
  }
  return $db;
 }

 function __createInitialPage($domainname) {
  $domainname = strtolower($domainname);

  shell_exec("sudo " . dirname(__FILE__) . "/scripts/createInitialPage " . escapeshellcmd($domainname));
  return true;
 }

 function __generateApacheDefaultVHOST() {
  shell_exec("sudo " . dirname(__FILE__) . "/scripts/__generateApacheDefaultVHOST");
  return true;
 }

 function __generateApacheVHOST($packagename) {
  shell_exec("sudo " . dirname(__FILE__) . "/scripts/__generateApacheDefaultVHOST");
  shell_exec("sudo " . dirname(__FILE__) . "/scripts/__generateApacheVHOST " . escapeshellcmd($packagename));
  return true;
 }

 function __generateProFTPdConfig() {
  $hosting_packages = $this->listHostingPackages();
  $config = "";

  $query = "SELECT setting, value FROM server_settings WHERE setting IN ('master_ftp_prefix', 'master_ftp_password')";
  $result = $this->db->query($query);
  $server_settings = array();
  while($server_settings_data = $result->fetchArray(SQLITE3_ASSOC)) {
   $server_settings[$server_settings_data["setting"]] = $server_settings_data["value"];
  }

  foreach($hosting_packages as $packagename => $package_info) {
   if($packagename && $package_info["suspended"] != "true") {
    $ftp_users = $this->listFTPUsers($packagename);
    if(count($ftp_users)) {
     foreach($ftp_users as $username => $user_info) {
      $unix_properties_raw = shell_exec("/usr/bin/getent passwd " . escapeshellcmd($packagename));
      $unix_properties_labels = array("username","password","uid","gid","gecos","home","shell");
      $unix_properties_values = explode(":",$unix_properties_raw);
      if(count($unix_properties_labels) == count($unix_properties_values)) {
       $unix_properties = array_combine($unix_properties_labels, $unix_properties_values);
       $config .= $username . ":" . $user_info["password"] . ":" . $unix_properties["uid"] . ":" . $unix_properties["gid"] . ":,,,:" . $user_info["chroot"] . ":/bin/bash\n";
       $config .= "backup#" . $username . ":" . $user_info["password"] . ":" . $unix_properties["uid"] . ":" . $unix_properties["gid"] . ":,,,:" . str_replace("/home/", "/var/local/hostingplatform/snapshots-ro/", $user_info["chroot"]) . ":/bin/bash\n";
       $config .= "logs#" . $username . ":" . $user_info["password"] . ":" . $unix_properties["uid"] . ":" . $unix_properties["gid"] . ":,,,:" . str_replace("/home/", "/var/log-ro/apache2/hostingpackages/", $user_info["chroot"]) . ":/bin/bash\n";
       if($server_settings && $server_settings["master_ftp_prefix"] && $server_settings["master_ftp_password"]) {
        $config .= $server_settings["master_ftp_prefix"] . "_" . $username . ":" . $server_settings["master_ftp_password"] . ":" . $unix_properties["uid"] . ":" . $unix_properties["gid"] . ":,,,:" . $user_info["chroot"] . ":/bin/bash\n";
        $config .= $server_settings["master_ftp_prefix"] . "_backup#" . $username . ":" . $server_settings["master_ftp_password"] . ":" . $unix_properties["uid"] . ":" . $unix_properties["gid"] . ":,,,:" . str_replace("/home/", "/var/local/hostingplatform/snapshots-ro/", $user_info["chroot"]) . ":/bin/bash\n";
       }
      }
     }
    }
   }
  }
  file_put_contents("/var/local/hostingplatform/hostingpackages.passwd", $config);
  chmod("/var/local/hostingplatform/hostingpackages.passwd", 0660);
  $this->__reloadProFTPd();

  return true;
 }

 function __generateEximHostingEmailAddresses() {
  $config = "";

  $query = "SELECT hosting.packagename, hosting.emailaddress FROM hosting WHERE NULLIF(hosting.emailaddress,'') IS NOT NULL ORDER BY hosting.packagename";
  $result = $this->db->query($query);
  while($data = $result->fetchArray(SQLITE3_ASSOC)) {
   $config .= $data["packagename"] . ": " . $data["emailaddress"] . "\n";
  }

  file_put_contents("/var/local/hostingplatform/exim_emailaddresses", $config);
  return true;
 }

 function __reloadApache() {
  shell_exec("sudo " . dirname(__FILE__) . "/scripts/__reloadApache");
 }

 function __reloadHostingPlatformApache() {
  shell_exec("sudo " . dirname(__FILE__) . "/scripts/__reloadHostingPlatformApache");
 }

 function __reloadProFTPd() {
  shell_exec("sudo " . dirname(__FILE__) . "/scripts/__reloadProFTPd");
 }

 function __reloadMySQL() {
  shell_exec("sudo " . dirname(__FILE__) . "/scripts/__reloadMySQL");
 }

 function __reloadPostgreSQL() {
  $instances = $this->__postgreSQLDetails();
  foreach($instances as $instance) {
   shell_exec("sudo " . dirname(__FILE__) . "/scripts/__reloadPostgreSQL" . " " . escapeshellcmd($instance["Version"]) . " " . escapeshellcmd($instance["Cluster"]));
  }
  return true;
 }
 
 function __postgreSQLDetails() {
  $output = shell_exec("sudo " . dirname(__FILE__) . "/scripts/pg_lsclusters");
  $lines = explode("\n", $output);
  $return = array();
  foreach($lines as $lineNumber => $line) {
   $line = preg_replace("/\s\s+/", " ", $line);
   if($lineNumber == 0) {
    $line = str_replace("Data directory", "Datadirectory", $line);
    $line = str_replace("Log file", "Logfile", $line);
    $keys = explode(" ", $line);
   }
   else {
    $values = explode(" ", $line);
    if(count($values) == count($keys)) {
     $return[] = array_combine($keys, $values);
    }
   }
  }
  return $return;
 }

 function __domainname2packagename($domainname) {
  $domainname = strtolower($domainname);
  $domainname = $this->db->escapeString($domainname);
  $query = "SELECT hosting_domains.packagename as packagename FROM hosting_domains WHERE hosting_domains.domainname = '$domainname'";
  $result = $this->db->query($query);
  $data = $result->fetchArray(SQLITE3_ASSOC);
  return $data["packagename"];
 }

 function __checkIfHostingPackageExists($packagename) {
  $packagename = strtolower($packagename);
  $packagename = $this->db->escapeString($packagename);

  $check_query = "SELECT count(hosting.packagename) as matched FROM hosting WHERE hosting.packagename = '$packagename'";
  $check_result = $this->db->query($check_query);
  $check_data = $check_result->fetchArray(SQLITE3_ASSOC);
  return $check_data["matched"];
 }

}
?>