public function __construct($new_values = null)
 {
     if (PTS_IS_DAEMONIZED_SERVER_PROCESS || is_file('/etc/phoronix-test-suite.xml') && is_writable('/etc/phoronix-test-suite.xml')) {
         $file = '/etc/phoronix-test-suite.xml';
     } else {
         if (PTS_IS_CLIENT && is_file(pts_config::get_config_file_location())) {
             $file = pts_config::get_config_file_location();
         } else {
             if (PTS_USER_PATH . 'user-config.xml' != pts_config::get_config_file_location() && is_file(PTS_USER_PATH . 'user-config.xml')) {
                 $file = PTS_USER_PATH . 'user-config.xml';
             } else {
                 if (PTS_IS_CLIENT && is_file($t = PTS_CORE_STATIC_PATH . phodevi::read_property('system', 'vendor-identifier') . '-user-config-template.xml')) {
                     $file = $t;
                 } else {
                     if (is_file(PTS_CORE_STATIC_PATH . 'user-config-template.xml')) {
                         $file = PTS_CORE_STATIC_PATH . 'user-config-template.xml';
                     } else {
                         if (is_file(PTS_CORE_STATIC_PATH . 'user-config-defaults.xml')) {
                             $file = PTS_CORE_STATIC_PATH . 'user-config-defaults.xml';
                         } else {
                             $file = null;
                         }
                     }
                 }
             }
         }
     }
     $this->override_values = is_array($new_values) ? $new_values : false;
     parent::__construct($file);
 }
 public static function run($r)
 {
     if (is_file(pts_config::get_config_file_location())) {
         copy(pts_config::get_config_file_location(), PTS_USER_PATH . 'user-config-old.xml');
         unlink(pts_config::get_config_file_location());
     }
     pts_config::user_config_generate();
 }
 public static function run($r)
 {
     pts_file_io::unlink(getenv('PTS_EXT_LAUNCH_SCRIPT_DIR') . '/web-server-launcher');
     if (PHP_VERSION_ID < 50400) {
         echo 'Running an unsupported PHP version. PHP 5.4+ is required to use this feature.' . PHP_EOL . PHP_EOL;
         return false;
     }
     $server_launcher = '#!/bin/sh' . PHP_EOL;
     $web_port = 0;
     $remote_access = pts_config::read_user_config('PhoronixTestSuite/Options/Server/RemoteAccessPort', 'FALSE');
     $remote_access = is_numeric($remote_access) && $remote_access > 1 ? $remote_access : false;
     $blocked_ports = array(2049, 3659, 4045, 6000);
     if ($remote_access) {
         // ALLOWING SERVER TO BE REMOTELY ACCESSIBLE
         $server_ip = '0.0.0.0';
         $fp = false;
         $errno = null;
         $errstr = null;
         if (($fp = fsockopen('127.0.0.1', $remote_access, $errno, $errstr, 5)) != false) {
             trigger_error('Port ' . $remote_access . ' is already in use by another server process. Close that process or change the Phoronix Test Suite server port via ' . pts_config::get_config_file_location() . ' to proceed.', E_USER_ERROR);
             fclose($fp);
             return false;
         } else {
             $web_port = $remote_access;
             $web_socket_port = pts_config::read_user_config('PhoronixTestSuite/Options/Server/WebSocketPort', '');
             if ($web_socket_port == null || !is_numeric($web_socket_port)) {
                 $web_socket_port = $web_port - 1;
             }
         }
     } else {
         echo PHP_EOL . PHP_EOL . 'You must first configure the remote GUI/WEBUI settings via:' . pts_config::get_config_file_location() . PHP_EOL . PHP_EOL;
         return false;
     }
     // WebSocket Server Setup
     $server_launcher .= 'export PTS_WEBSOCKET_PORT=' . $web_socket_port . PHP_EOL;
     $server_launcher .= 'export PTS_WEBSOCKET_SERVER=GUI' . PHP_EOL;
     $server_launcher .= 'cd ' . getenv('PTS_DIR') . ' && PTS_MODE="CLIENT" ' . getenv('PHP_BIN') . ' pts-core/phoronix-test-suite.php start-ws-server &' . PHP_EOL;
     $server_launcher .= 'websocket_server_pid=$!' . PHP_EOL;
     // HTTP Server Setup
     if (strpos(getenv('PHP_BIN'), 'hhvm')) {
         echo PHP_EOL . 'Unfortunately, the HHVM built-in web server has abandoned upstream. Users will need to use the PHP binary or other alternatives.' . PHP_EOL . PHP_EOL;
         return false;
     } else {
         $server_launcher .= getenv('PHP_BIN') . ' -S ' . $server_ip . ':' . $web_port . ' -t ' . PTS_CORE_PATH . 'web-interface/ 2> /dev/null  &' . PHP_EOL;
         //2> /dev/null
     }
     $server_launcher .= 'http_server_pid=$!' . PHP_EOL;
     $server_launcher .= 'sleep 1' . PHP_EOL;
     $server_launcher .= 'echo "The Web Interface Is Accessible At: http://localhost:' . $web_port . '"' . PHP_EOL;
     $server_launcher .= PHP_EOL . 'echo -n "Press [ENTER] to kill server..."' . PHP_EOL . 'read var_name';
     // Shutdown / Kill Servers
     $server_launcher .= PHP_EOL . 'kill $http_server_pid';
     $server_launcher .= PHP_EOL . 'kill $websocket_server_pid';
     $server_launcher .= PHP_EOL . 'rm -f ~/.phoronix-test-suite/run-lock*';
     file_put_contents(getenv('PTS_EXT_LAUNCH_SCRIPT_DIR') . '/web-server-launcher', $server_launcher);
 }
 public static function render_page_process($PATH)
 {
     if ($_SESSION['AdminLevel'] != -40) {
         header('Location: /?main');
     }
     $main = null;
     if (isset($_POST['new_phoromatic_path']) && !empty($_POST['new_phoromatic_path'])) {
         $new_dir = dirname($_POST['new_phoromatic_path']);
         if (!is_dir($new_dir)) {
             $main .= '<h2 style="color: red;"><em>' . $new_dir . '</em> must be a valid directory.</h2>';
         } else {
             if (!is_writable($new_dir)) {
                 $main .= '<h2 style="color: red;"><em>' . $new_dir . '</em> is not a writable location.</h2>';
             } else {
                 if (!is_dir($_POST['new_phoromatic_path'])) {
                     if (mkdir($_POST['new_phoromatic_path']) == false) {
                         $main .= '<h2 style="color: red;">Failed to make directory <em>' . $_POST['new_phoromatic_path'] . '</em>.</h2>';
                     }
                 }
                 if (is_dir($_POST['new_phoromatic_path'])) {
                     $new_phoromatic_dir = pts_strings::add_trailing_slash($_POST['new_phoromatic_path']);
                     $d = glob($new_phoromatic_dir . '*');
                     if (!empty($d)) {
                         $new_phoromatic_dir .= 'phoromatic/';
                         pts_file_io::mkdir($new_phoromatic_dir);
                     }
                     $d = glob($new_phoromatic_dir . '*');
                     if (!empty($d)) {
                         $main .= '<h2 style="color: red;"><em>' . $new_phoromatic_dir . '</em> must be an empty directory.</h2>';
                     } else {
                         if (pts_file_io::copy(phoromatic_server::phoromatic_path(), $new_phoromatic_dir)) {
                             pts_config::user_config_generate(array('PhoromaticStorage' => $new_phoromatic_dir));
                             header('Location: /?admin');
                         } else {
                             $main .= '<h2 style="color: red;"><em>Failed to copy old Phoromatic data to new location.</h2>';
                         }
                     }
                 }
             }
         }
     }
     if (isset($_POST['new_dc_path']) && !empty($_POST['new_dc_path'])) {
         $new_dir = dirname($_POST['new_dc_path']);
         if (!is_dir($new_dir)) {
             $main .= '<h2 style="color: red;"><em>' . $new_dir . '</em> must be a valid directory.</h2>';
         } else {
             if (!is_writable($new_dir)) {
                 $main .= '<h2 style="color: red;"><em>' . $new_dir . '</em> is not a writable location.</h2>';
             } else {
                 if (!is_dir($_POST['new_dc_path'])) {
                     if (mkdir($_POST['new_dc_path']) == false) {
                         $main .= '<h2 style="color: red;">Failed to make directory <em>' . $_POST['new_dc_path'] . '</em>.</h2>';
                     }
                 }
                 if (is_dir($_POST['new_dc_path'])) {
                     $new_dc_dir = pts_strings::add_trailing_slash($_POST['new_dc_path']);
                     if (pts_file_io::copy(pts_strings::add_trailing_slash(pts_client::parse_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH))), $new_dc_dir)) {
                         pts_config::user_config_generate(array('CacheDirectory' => $new_dc_dir));
                         header('Location: /?admin');
                     } else {
                         $main .= '<h2 style="color: red;"><em>Failed to copy old Phoromatic data to new location.</h2>';
                     }
                 }
             }
         }
     }
     if (isset($_POST['new_proxy_address']) && isset($_POST['new_proxy_port'])) {
         if (pts_network::http_get_contents('http://www.phoronix-test-suite.com/PTS', $_POST['new_proxy_address'], $_POST['new_proxy_port']) == 'PTS') {
             pts_config::user_config_generate(array('PhoronixTestSuite/Options/Networking/ProxyAddress' => $_POST['new_proxy_address'], 'PhoronixTestSuite/Options/Networking/ProxyPort' => $_POST['new_proxy_port']));
         } else {
             $main .= '<h2 style="color: red;">Failed to connect via proxy server.</h2>';
         }
     }
     if (isset($_POST['new_http_port']) && isset($_POST['new_ws_port'])) {
         if (empty($_POST['new_http_port']) || !is_numeric($_POST['new_http_port']) && $_POST['new_http_port'] != 'RANDOM') {
             $main .= '<h2 style="color: red;">The HTTP port must be a valid port number or <em>RANDOM</em>.</h2>';
         }
         if (empty($_POST['new_ws_port']) || !is_numeric($_POST['new_ws_port']) && $_POST['new_ws_port'] != 'RANDOM') {
             $main .= '<h2 style="color: red;">The WebSocket port must be a valid port number or <em>RANDOM</em>.</h2>';
         }
         pts_config::user_config_generate(array('PhoronixTestSuite/Options/Server/RemoteAccessPort' => $_POST['new_http_port'], 'PhoronixTestSuite/Options/Server/WebSocketPort' => $_POST['new_ws_port']));
     }
     if (isset($_POST['add_new_users_to_account'])) {
         if (empty($_POST['add_new_users_to_account'])) {
             phoromatic_server::save_setting('add_new_users_to_account', null);
         } else {
             $stmt = phoromatic_server::$db->prepare('SELECT COUNT(AccountID) AS AccountHitCount FROM phoromatic_accounts WHERE AccountID = :account_id');
             $stmt->bindValue(':account_id', $_POST['add_new_users_to_account']);
             $result = $stmt->execute();
             $row = $result->fetchArray();
             if (empty($row['AccountHitCount'])) {
                 $main .= '<h2 style="color: red;"><em>' . $_POST['add_new_users_to_account'] . '</em> is not a valid account ID.</h2>';
             } else {
                 phoromatic_server::save_setting('add_new_users_to_account', $_POST['add_new_users_to_account']);
             }
         }
     }
     if (isset($_POST['account_creation_alt'])) {
         phoromatic_server::save_setting('account_creation_alt', $_POST['account_creation_alt']);
     }
     if (isset($_POST['main_page_message'])) {
         phoromatic_server::save_setting('main_page_message', $_POST['main_page_message']);
     }
     if (isset($_POST['force_result_sharing'])) {
         phoromatic_server::save_setting('force_result_sharing', $_POST['force_result_sharing']);
     }
     if (isset($_POST['show_local_tests_only'])) {
         phoromatic_server::save_setting('show_local_tests_only', $_POST['show_local_tests_only']);
     }
     if (isset($_POST['new_admin_support_email'])) {
         phoromatic_server::save_setting('admin_support_email', $_POST['new_admin_support_email']);
     }
     if (isset($_POST['rebuild_results_db'])) {
         foreach (pts_file_io::glob(phoromatic_server::phoromatic_path() . 'accounts/*/results/*/composite.xml') as $composite_xml) {
             $account_id = basename(dirname(dirname(dirname($composite_xml))));
             $upload_id = basename(dirname($composite_xml));
             $result_file = new pts_result_file($composite_xml);
             // Validate the XML
             $relative_id = 0;
             foreach ($result_file->get_result_objects() as $result_object) {
                 $relative_id++;
                 $stmt = phoromatic_server::$db->prepare('INSERT INTO phoromatic_results_results (AccountID, UploadID, AbstractID, TestProfile, ComparisonHash) VALUES (:account_id, :upload_id, :abstract_id, :test_profile, :comparison_hash)');
                 $stmt->bindValue(':account_id', $account_id);
                 $stmt->bindValue(':upload_id', $upload_id);
                 $stmt->bindValue(':abstract_id', $relative_id);
                 $stmt->bindValue(':test_profile', $result_object->test_profile->get_identifier());
                 $stmt->bindValue(':comparison_hash', $result_object->get_comparison_hash(true, false));
                 $result = $stmt->execute();
             }
             if ($relative_id > 0) {
                 foreach ($result_file->get_systems() as $s) {
                     $stmt = phoromatic_server::$db->prepare('INSERT INTO phoromatic_results_systems (AccountID, UploadID, SystemIdentifier, Hardware, Software) VALUES (:account_id, :upload_id, :system_identifier, :hardware, :software)');
                     $stmt->bindValue(':account_id', $account_id);
                     $stmt->bindValue(':upload_id', $upload_id);
                     $stmt->bindValue(':system_identifier', $s->get_identifier());
                     $stmt->bindValue(':hardware', $s->get_hardware());
                     $stmt->bindValue(':software', $s->get_software());
                     $result = $stmt->execute();
                 }
             }
         }
     }
     $main .= '<h1>Phoromatic Server Configuration</h1>';
     $main .= '<h2>Phoromatic Storage Location</h2>';
     $main .= '<p>The Phoromatic Storage location is where all Phoromatic-specific test results, account data, and other information is archived. This path is controlled via the <em>' . pts_config::get_config_file_location() . '</em> configuration file with the <em>PhoromaticStorage</em> element. Adjusting the directory from the user configuration XML file is the recommended way to adjust the Phoromatic storage path when the Phoromatic Server is not running, while using the below form is an alternative method to attempt to live migrate the storage path.</p>';
     $main .= '<p><strong>Current Storage Path:</strong> ' . phoromatic_server::phoromatic_path() . '</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="update_phoromatic_path" method="post">';
     $main .= '<p><input type="text" name="new_phoromatic_path" value="' . (isset($_POST['new_phoromatic_path']) ? $_POST['new_phoromatic_path'] : null) . '" /></p>';
     $main .= '<p><input name="submit" value="Update Phoromatic Storage Location" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h2>Download Cache Location</h2>';
     $main .= '<p>The download cache is where the Phoronix Test Suite is able to make an archive of files needed by test profiles. The Phoromatic Server is then able to allow Phoronix Test Suite client systems on the intranet. To add test files to this cache on the Phoromatic Server, run <strong>phoronix-test-suite make-download-cache <em>&lt;the test identifers you wish to download and cache&gt;</em></strong>.</p>';
     $main .= '<p><strong>Current Download Cache Path:</strong> ' . pts_strings::add_trailing_slash(pts_client::parse_home_directory(pts_config::read_user_config('PhoronixTestSuite/Options/Installation/CacheDirectory', PTS_DOWNLOAD_CACHE_PATH))) . '</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="update_dc_path" method="post">';
     $main .= '<p><input type="text" name="new_dc_path" value="' . (isset($_POST['new_dc_path']) ? $_POST['new_dc_path'] : null) . '" /></p>';
     $main .= '<p><input name="submit" value="Update Download Cache Location" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h2>Network Proxy</h2>';
     $main .= '<p>If a network proxy is needed for the Phoromatic Server to access the open Internet, please provide the IP address and HTTP port address below.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="update_proxy" method="post">';
     $main .= '<p><strong>Proxy HTTP Port:</strong> <input type="text" name="new_proxy_port" size="4" value="' . (isset($_POST['new_proxy_port']) ? $_POST['new_proxy_port'] : pts_config::read_user_config('PhoronixTestSuite/Options/Networking/ProxyPort')) . '" /></p>';
     $main .= '<p><strong>Proxy IP Address:</strong> <input type="text" name="new_proxy_address" value="' . (isset($_POST['new_proxy_address']) ? $_POST['new_proxy_address'] : pts_config::read_user_config('PhoronixTestSuite/Options/Networking/ProxyAddress')) . '" /></p>';
     $main .= '<p><input name="submit" value="Update Network Proxy" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h2>Phoromatic Server Ports</h2>';
     $main .= '<p>The HTTP and WebSocket ports for the Phoromatic Server can be adjusted via this form or the user configuration XML file. The new ports will not go into effect until the Phoromatic Server instance has been restarted.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="update_ports" method="post">';
     $main .= '<p><strong>HTTP Port:</strong> <input type="text" name="new_http_port" size="4" value="' . (isset($_POST['new_http_port']) ? $_POST['new_http_port'] : pts_config::read_user_config('PhoronixTestSuite/Options/Server/RemoteAccessPort')) . '" /></p>';
     $main .= '<p><strong>WebSocket Port:</strong> <input type="text" name="new_ws_port" size="4" value="' . (isset($_POST['new_ws_port']) ? $_POST['new_ws_port'] : pts_config::read_user_config('PhoronixTestSuite/Options/Server/WebSocketPort')) . '" /></p>';
     $main .= '<p><input name="submit" value="Update Web Ports" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h2>Support Email Address</h2>';
     $main .= '<p>This email address will be shown as the sender of emails regarding new account registration and other non-group-related messages. This email address may also be shown as a support email address in case of user problems.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="support_email" method="post">';
     $main .= '<p><strong>E-Mail:</strong> <input type="text" name="new_admin_support_email" value="' . phoromatic_server::read_setting('admin_support_email') . '" /></p>';
     $main .= '<p><input name="submit" value="Update E-Mail Address" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h1>Account Creation</h1>';
     $main .= '<h2>Add To Existing Account</h2><p>Whenever a new account is created via the main log-in page, rather than creating a new group account, you can opt to have the account added as a viewer to an existing group of accounts. To do so, enter the account ID in the field below. The user is added to that account ID with viewer privileges while the main administrator for that account can elevate the privileges from their account\'s Users page. You can find the list of account IDs via the main rootadmin page account listing. Leave this field blank to disable the feature. This option only affects the creation of new accounts.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="add_accounts_to_one" method="post">';
     $main .= '<p><strong>Main Account ID:</strong> <input type="text" name="add_new_users_to_account" size="6" value="' . phoromatic_server::read_setting('add_new_users_to_account') . '" /></p>';
     $main .= '<p><input name="submit" value="Update Account Handling" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h1>Account Creation</h1>';
     $main .= '<p>By default, new accounts can be created at-will from the main page of the Phoromatic Server web interface. <strong>To disable the ability to create new accounts from the main welcome page</strong>, enter a message in the field below -- e.g. account creation disabled, contact XYZ department via email to request a new account, or other string to present to the user in place of the account creation box. Leave this box empty to allow new accounts to be created. HTML input is allowed.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="account_creation_text" method="post">';
     $main .= '<p><strong>Account Creation String:</strong> <textarea name="account_creation_alt" cols="50" rows="4">' . phoromatic_server::read_setting('account_creation_alt') . '</textarea></p>';
     $main .= '<p><input name="submit" value="Update Account Handling" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h1>Main Page Message</h1>';
     $main .= '<p>If you wish to present users with a custom message once logging into their Phoromatic account, set the HTML-allowed string below and it will be shown on the main page once logging in.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="main_page_message" method="post">';
     $main .= '<p><strong>Main Page Message String:</strong> <textarea name="main_page_message" cols="50" rows="4">' . phoromatic_server::read_setting('main_page_message') . '</textarea></p>';
     $main .= '<p><input name="submit" value="Update Main Page Message" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h1>Force Results To Be Shared</h1>';
     $main .= '<p>If you wish to force that all accounts/groups on this Phoromatic Server instance are shared/viewable amongst other groups on this server, set this value to True. Otherwise the result sharing is limited to each group\'s selected option on the account settings page.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="force_result_share" method="post">';
     $main .= '<p><strong>Force Result Sharing:</strong> <select name="force_result_sharing"><option value="0">False</option><option value="1" ' . (phoromatic_server::read_setting('force_result_sharing') ? 'selected="selected"' : null) . '>True</option></select></p>';
     $main .= '<p><input name="submit" value="Update" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h1>Only Advertise Tests With Files Locally Cached</h1>';
     $main .= '<p>Enabling this option will only advertise test profiles on the Phoromatic Server web interface if the needed files for that test are present within the Phoromatic Server\'s PTS download cache. This feature is particularly useful for environments where the client test system lacks direct Internet access.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="show_local_tests_only" method="post">';
     $main .= '<p><strong>Only Advertise Cached Tests:</strong> <select name="show_local_tests_only"><option value="0">False</option><option value="1" ' . (phoromatic_server::read_setting('show_local_tests_only') ? 'selected="selected"' : null) . '>True</option></select></p>';
     $main .= '<p><input name="submit" value="Update" type="submit" /></p>';
     $main .= '</form>';
     $main .= '<hr /><h1>Rebuild Results/Systems SQLite Tables</h1>';
     $main .= '<p>If you somehow damaged some of your SQLite tables, this option will attempt to rebuild the phoromatic_results_results and phoromatic_results_systems tables.</p>';
     $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="rebuild_results_db" method="post">';
     $main .= '<p><strong>Force Results Table Rebuild:</strong> <select name="rebuild_results_db"><option value="0">False</option><option value="1" ' . (phoromatic_server::read_setting('rebuild_results_db') ? 'selected="selected"' : null) . '>True</option></select></p>';
     $main .= '<p><input name="submit" value="Rebuild Results Table" type="submit" /></p>';
     $main .= '</form>';
     echo phoromatic_webui_header_logged_in();
     echo phoromatic_webui_main($main, phoromatic_webui_right_panel_logged_in());
     echo phoromatic_webui_footer();
 }
    public static function run($r)
    {
        if (pts_client::create_lock(PTS_USER_PATH . 'phoromatic_server_lock') == false) {
            trigger_error('The Phoromatic Server is already running.', E_USER_ERROR);
            return false;
        }
        pts_file_io::unlink(getenv('PTS_EXT_LAUNCH_SCRIPT_DIR') . '/phoromatic-server-launcher');
        if (PHP_VERSION_ID < 50400) {
            echo 'Running an unsupported PHP version. PHP 5.4+ is required to use this feature.' . PHP_EOL . PHP_EOL;
            return false;
        }
        if (!function_exists('socket_create_listen')) {
            echo 'PHP Sockets support is needed to use the Phoromatic Server.' . PHP_EOL . PHP_EOL;
            return false;
        }
        $server_launcher = '#!/bin/sh' . PHP_EOL;
        $web_port = 0;
        $remote_access = pts_config::read_user_config('PhoronixTestSuite/Options/Server/RemoteAccessPort', 'RANDOM');
        $fp = false;
        $errno = null;
        $errstr = null;
        if ($remote_access == 'RANDOM') {
            do {
                if ($fp) {
                    fclose($fp);
                }
                $remote_access = rand(8000, 8999);
            } while (($fp = fsockopen('127.0.0.1', $remote_access, $errno, $errstr, 5)) != false);
            echo 'Port ' . $remote_access . ' chosen as random port for this instance. Change the default port via the Phoronix Test Suite user configuration file.' . PHP_EOL;
        }
        $remote_access = is_numeric($remote_access) && $remote_access > 1 ? $remote_access : false;
        $blocked_ports = array(2049, 3659, 4045, 6000, 9000);
        if ($remote_access) {
            // ALLOWING SERVER TO BE REMOTELY ACCESSIBLE
            $server_ip = '0.0.0.0';
            if (($fp = fsockopen('127.0.0.1', $remote_access, $errno, $errstr, 5)) != false) {
                fclose($fp);
                trigger_error('Port ' . $remote_access . ' is already in use by another server process. Close that process or change the Phoronix Test Suite server port via' . pts_config::get_config_file_location() . ' to proceed.', E_USER_ERROR);
                return false;
            } else {
                $web_port = $remote_access;
                $web_socket_port = pts_config::read_user_config('PhoronixTestSuite/Options/Server/WebSocketPort', '');
                while ($web_socket_port == null || !is_numeric($web_socket_port) || ($fp = fsockopen('127.0.0.1', $web_socket_port, $errno, $errstr, 5)) != false) {
                    if ($fp) {
                        fclose($fp);
                    }
                    $web_socket_port = rand(8000, 8999);
                }
            }
        } else {
            echo PHP_EOL . PHP_EOL . 'You must first configure the remote web / Phoromatic settings via:' . PHP_EOL . '    ' . pts_config::get_config_file_location() . PHP_EOL . PHP_EOL . 'The RemoteAccessPort should be a network port to use for HTTP communication while WebSocketPort should be set to another available network port. Set to RANDOM if wishing to use randomly chosen available ports.' . PHP_EOL . PHP_EOL;
            return false;
        }
        if (!extension_loaded('sqlite3')) {
            echo PHP_EOL . PHP_EOL . 'PHP SQLite3 support must first be enabled before accessing the Phoromatic server (e.g. installing the php5-sqlite or php-pdo package depending on the distribution).' . PHP_EOL . PHP_EOL;
            return false;
        }
        // Setup server logger
        define('PHOROMATIC_SERVER', true);
        // Just create the logger so now it will flush it out
        $pts_logger = new pts_logger();
        $pts_logger->clear_log();
        echo pts_core::program_title(true) . ' starting Phoromatic Server' . PHP_EOL;
        $pts_logger->log(pts_core::program_title(true) . ' starting Phoromatic Server on ' . pts_network::get_local_ip());
        echo 'Phoronix Test Suite User-Data Directory Path: ' . PTS_USER_PATH . PHP_EOL;
        echo 'Phoronix Test Suite Configuration File: ' . pts_config::get_config_file_location() . PHP_EOL;
        echo 'Phoromatic Server Log File: ' . $pts_logger->get_log_file_location() . PHP_EOL;
        $pts_logger->log('PTS_USER_PATH = ' . PTS_USER_PATH);
        $pts_logger->log('PTS_DOWNLOAD_CACHE_PATH = ' . PTS_DOWNLOAD_CACHE_PATH);
        $pts_logger->log('XML Configuration File = ' . pts_config::get_config_file_location());
        // WebSocket Server Setup
        $server_launcher .= 'export PTS_WEB_PORT=' . $web_port . PHP_EOL;
        $server_launcher .= 'export PTS_WEBSOCKET_PORT=' . $web_socket_port . PHP_EOL;
        $server_launcher .= 'export PTS_WEBSOCKET_SERVER=PHOROMATIC' . PHP_EOL;
        $server_launcher .= 'export PTS_NO_FLUSH_LOGGER=1' . PHP_EOL;
        $server_launcher .= 'export PTS_PHOROMATIC_SERVER=1' . PHP_EOL;
        $server_launcher .= 'export PTS_PHOROMATIC_LOG_LOCATION=' . $pts_logger->get_log_file_location() . PHP_EOL;
        $server_launcher .= 'cd ' . getenv('PTS_DIR') . ' && PTS_MODE="CLIENT" ' . getenv('PHP_BIN') . ' pts-core/phoronix-test-suite.php start-ws-server &' . PHP_EOL;
        $server_launcher .= 'websocket_server_pid=$!' . PHP_EOL;
        $pts_logger->log('Starting WebSocket process on port ' . $web_socket_port);
        $server_launcher .= 'cd ' . getenv('PTS_DIR') . ' && PTS_MODE="CLIENT" ' . getenv('PHP_BIN') . ' pts-core/phoronix-test-suite.php start-phoromatic-event-server &' . PHP_EOL;
        $server_launcher .= 'event_server_pid=$!' . PHP_EOL;
        // HTTP Server Setup
        if (false && pts_client::executable_in_path('nginx') && is_file('/run/php-fpm/php-fpm.pid')) {
            // NGINX
            $nginx_conf = 'error_log /tmp/error.log;
			pid /tmp/nginx.pid;
			worker_processes 1;

			events {
			  worker_connections 1024;
			}

			http {
			  client_body_temp_path /tmp/client_body;
			  fastcgi_temp_path /tmp/fastcgi_temp;
			  proxy_temp_path /tmp/proxy_temp;
			  scgi_temp_path /tmp/scgi_temp;
			  uwsgi_temp_path /tmp/uwsgi_temp;
			  tcp_nopush on;
			  tcp_nodelay on;
			  keepalive_timeout 180;
			  types_hash_max_size 2048;
			  include /etc/nginx/mime.types;
			  index index.php;

			  server {
			    listen ' . $web_port . ';
			    listen [::]:' . $web_port . ' default ipv6only=on;
			    access_log /tmp/access.log;
			    error_log /tmp/error.log;
			    root ' . PTS_CORE_PATH . 'phoromatic/public_html;
				index index.php;
			      try_files $uri $uri/ /index.php;
				location / {
				autoindex on;
				}
				location ~ \\.php$ {
				     include        /etc/nginx/fastcgi_params;
				     fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
				     fastcgi_split_path_info ^(.+\\.php)(/.+)$;
				     fastcgi_pass   127.0.0.1:9000;
				     fastcgi_index  index.php;
				}
			  }
			}';
            $nginx_conf_file = tempnam(PTS_USER_PATH, 'nginx_conf_');
            file_put_contents($nginx_conf_file, $nginx_conf);
            $server_launcher .= 'nginx -c ' . $nginx_conf_file . PHP_EOL . 'rm -f ' . $nginx_conf_file . PHP_EOL;
        } else {
            if (($mongoose = pts_client::executable_in_path('mongoose')) && ($php_cgi = pts_client::executable_in_path('php-cgi'))) {
                // Mongoose Embedded Web Server
                $server_launcher .= $mongoose . ' -p ' . $web_port . ' -r ' . PTS_CORE_PATH . 'phoromatic/public_html/ -I ' . $php_cgi . ' -i index.php > /dev/null 2>> $PTS_PHOROMATIC_LOG_LOCATION &' . PHP_EOL;
                //2> /dev/null
            } else {
                if (strpos(getenv('PHP_BIN'), 'hhvm')) {
                    echo PHP_EOL . 'Unfortunately, the HHVM built-in web server has abandoned upstream. Users will need to use the PHP binary or other alternatives.' . PHP_EOL . PHP_EOL;
                    return;
                } else {
                    // PHP Web Server
                    $server_launcher .= getenv('PHP_BIN') . ' -S ' . $server_ip . ':' . $web_port . ' -t ' . PTS_CORE_PATH . 'phoromatic/public_html/ > /dev/null 2>> $PTS_PHOROMATIC_LOG_LOCATION &' . PHP_EOL;
                    //2> /dev/null
                }
            }
        }
        $server_launcher .= 'http_server_pid=$!' . PHP_EOL;
        $server_launcher .= 'sleep 1' . PHP_EOL;
        $server_launcher .= 'echo "The Phoromatic Web Interface Is Accessible At: http://localhost:' . $web_port . '"' . PHP_EOL;
        $pts_logger->log('Starting HTTP process @ http://localhost:' . $web_port);
        // Avahi for zeroconf network discovery support
        if (pts_config::read_user_config('PhoronixTestSuite/Options/Server/AdvertiseServiceZeroConf', 'TRUE')) {
            if (is_dir('/etc/avahi/services') && is_writable('/etc/avahi/services')) {
                file_put_contents('/etc/avahi/services/phoromatic-server.service', '<?xml version="1.0" standalone=\'no\'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
  <name replace-wildcards="yes">phoromatic-server-%h</name>
  <service>
    <type>_http._tcp</type>
    <port>' . $web_port . '</port>
  </service>
</service-group>');
            } else {
                if (pts_client::executable_in_path('avahi-publish')) {
                    $hostname = phodevi::read_property('system', 'hostname');
                    $hostname = $hostname == null ? rand(0, 99) : $hostname;
                    $server_launcher .= 'avahi-publish -s phoromatic-server-' . $hostname . ' _http._tcp ' . $web_port . ' "Phoronix Test Suite Phoromatic" > /dev/null 2> /dev/null &' . PHP_EOL;
                    $server_launcher .= 'avahi_publish_pid=$!' . PHP_EOL;
                }
            }
        }
        // Wait for input to shutdown process..
        if (!PTS_IS_DAEMONIZED_SERVER_PROCESS) {
            $server_launcher .= PHP_EOL . 'echo -n "Press [ENTER] to kill server..."' . PHP_EOL;
            $server_launcher .= PHP_EOL . 'read var_name';
        } else {
            $server_launcher .= PHP_EOL . 'while [ ! -f "/var/lib/phoronix-test-suite/end-phoromatic-server" ];';
            $server_launcher .= PHP_EOL . 'do';
            $server_launcher .= PHP_EOL . 'sleep 1';
            $server_launcher .= PHP_EOL . 'done';
            $server_launcher .= PHP_EOL . 'rm -f /var/lib/phoronix-test-suite/end-phoromatic-server' . PHP_EOL;
        }
        // Shutdown / Kill Servers
        $server_launcher .= PHP_EOL . 'kill $http_server_pid';
        $server_launcher .= PHP_EOL . 'kill $websocket_server_pid';
        $server_launcher .= PHP_EOL . 'kill $event_server_pid';
        if (is_writable('/etc/avahi/services') && is_file('/etc/avahi/services/phoromatic-server.service')) {
            $server_launcher .= PHP_EOL . 'rm -f /etc/avahi/services/phoromatic-server.service';
        } else {
            $server_launcher .= PHP_EOL . 'kill $avahi_publish_pid';
        }
        $server_launcher .= PHP_EOL . 'rm -f ~/.phoronix-test-suite/run-lock*';
        file_put_contents(getenv('PTS_EXT_LAUNCH_SCRIPT_DIR') . '/phoromatic-server-launcher', $server_launcher);
    }
 public static function user_config_generate($new_config_values = null)
 {
     // Validate the config files, update them (or write them) if needed, and other configuration file tasks
     $read_config = new pts_config_nye_XmlReader($new_config_values);
     $config = new nye_XmlWriter('xsl/pts-user-config-viewer.xsl');
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/OpenBenchmarking/AnonymousUsageReporting', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/OpenBenchmarking/IndexCacheTTL', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/OpenBenchmarking/AlwaysUploadSystemLogs', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/General/DefaultBrowser', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/General/UsePhodeviCache', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/General/DefaultDisplayMode', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/General/PhoromaticServers', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Modules/LoadModules', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Installation/RemoveDownloadFiles', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Installation/SearchMediaForCache', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Installation/SymLinkFilesFromCache', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Installation/PromptForDownloadMirror', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Installation/EnvironmentDirectory', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Installation/CacheDirectory', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Testing/SaveSystemLogs', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Testing/SaveInstallationLogs', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Testing/SaveTestLogs', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Testing/RemoveTestInstallOnCompletion', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Testing/ResultsDirectory', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Testing/AlwaysUploadResultsToOpenBenchmarking', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Testing/AutoSortRunQueue', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/TestResultValidation/DynamicRunCount', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/TestResultValidation/LimitDynamicToTestLength', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/TestResultValidation/StandardDeviationThreshold', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/TestResultValidation/ExportResultsTo', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/BatchMode/SaveResults', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/BatchMode/OpenBrowser', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/BatchMode/UploadResults', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/BatchMode/PromptForTestIdentifier', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/BatchMode/PromptForTestDescription', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/BatchMode/PromptSaveName', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/BatchMode/RunAllTestCombinations', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/BatchMode/Configured', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Networking/NoInternetCommunication', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Networking/NoNetworkCommunication', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Networking/Timeout', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Networking/ProxyAddress', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Networking/ProxyPort', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Server/RemoteAccessPort', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Server/Password', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Server/WebSocketPort', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Server/AdvertiseServiceZeroConf', $read_config);
     $config->addXmlNodeFromReader('PhoronixTestSuite/Options/Server/PhoromaticStorage', $read_config);
     $config_file = pts_config::get_config_file_location();
     if ($read_config->times_fallback() > 0 || !is_file($config_file)) {
         // Something changed, so write out file, otherwise don't bother writing file
         $config->saveXMLFile($config_file);
     }
 }
    public static function render_page_process($PATH)
    {
        if ($_SESSION['AdminLevel'] != -40) {
            header('Location: /?main');
        }
        $main = null;
        if (isset($_POST['disable_user'])) {
            $stmt = phoromatic_server::$db->prepare('UPDATE phoromatic_users SET AdminLevel = (AdminLevel * -1) WHERE UserName = :user_name');
            $stmt->bindValue(':user_name', $_POST['disable_user']);
            $result = $stmt->execute();
            $main .= '<h2>Disabled Account: ' . $_POST['disable_user'] . '</h2>';
        } else {
            if (isset($_POST['register_username']) && isset($_POST['register_password']) && isset($_POST['register_password_confirm']) && isset($_POST['register_email'])) {
                $new_account = create_new_phoromatic_account($_POST['register_username'], $_POST['register_password'], $_POST['register_password_confirm'], $_POST['register_email'], isset($_POST['seed_accountid']) ? $_POST['seed_accountid'] : null);
            }
        }
        $main .= '<h1>Phoromatic Server Administration</h1>';
        $main .= '<hr /><h2>Server Information</h2>';
        $main .= '<p><strong>HTTP Server Port:</strong> ' . getenv('PTS_WEB_PORT') . '<br /><strong>WebSocket Server Port:</strong> ' . getenv('PTS_WEBSOCKET_PORT') . '<br /><strong>Phoromatic Server Path:</strong> ' . phoromatic_server::phoromatic_path() . '<br /><strong>Configuration File:</strong>: ' . pts_config::get_config_file_location() . '</p>';
        $main .= '<hr /><h2>Statistics</h2>';
        $stmt = phoromatic_server::$db->prepare('SELECT COUNT(Title) AS SystemCount FROM phoromatic_systems WHERE State >= 0');
        $result = $stmt->execute();
        $row = $result->fetchArray();
        $stats['Total System Count'] = $row['SystemCount'];
        $stmt = phoromatic_server::$db->prepare('SELECT COUNT(Title) AS ScheduleCount FROM phoromatic_schedules WHERE State >= 1');
        $result = $stmt->execute();
        $row = $result->fetchArray();
        $stats['Total Schedule Count'] = $row['ScheduleCount'];
        $stmt = phoromatic_server::$db->prepare('SELECT COUNT(UploadID) AS ResultCount FROM phoromatic_results');
        $result = $stmt->execute();
        $row = $result->fetchArray();
        $stats['Total Result Count'] = $row['ResultCount'];
        $stmt = phoromatic_server::$db->prepare('SELECT COUNT(ActivityTime) AS ActivityCount FROM phoromatic_activity_stream');
        $stmt->bindValue(':today_date', date('Y-m-d') . '%');
        $result = $stmt->execute();
        $row = $result->fetchArray();
        $stats['Total Activity Count'] = $row['ActivityCount'];
        $main .= '<p>';
        foreach ($stats as $what => $c) {
            $main .= '<strong>' . $what . ':</strong> ' . $c . '<br />';
        }
        $main .= '<hr /><h2>Account Topology</h2>';
        $stmt = phoromatic_server::$db->prepare('SELECT * FROM phoromatic_users ORDER BY AccountID,AdminLevel ASC');
        $result = $stmt->execute();
        $plevel = -1;
        $user_list = array();
        while ($row = $result->fetchArray()) {
            switch ($row['AdminLevel']) {
                case 1:
                    $level = 'Group Administrator';
                    $offset = null;
                    break;
                case 2:
                    $level = 'Administrator';
                    $offset = str_repeat('-', 10);
                    break;
                case 3:
                    $level = 'Power User';
                    $offset = str_repeat('-', 20);
                    break;
                case 10:
                    $level = 'Viewer';
                    $offset = str_repeat('-', 30);
                    break;
                default:
                    if ($row['AdminLevel'] < 1) {
                        $level = 'Disabled';
                    } else {
                        $level = 'Unknown';
                    }
                    $offset = null;
                    break;
            }
            if ($row['AdminLevel'] == 1) {
                if ($plevel != -1) {
                    $main .= '</p>';
                }
                $main .= '<p>';
            }
            $main .= $offset . ' <strong>' . $row['UserName'] . '</strong> (<em>' . $level . '</em>) <strong>Created On:</strong> ' . phoromatic_user_friendly_timedate($row['CreatedOn']) . ' <strong>Last Log-In:</strong> ' . ($row['LastLogin'] != null ? phoromatic_user_friendly_timedate($row['LastLogin']) : 'N/A') . ($row['AdminLevel'] == 1 ? ' [<strong>ACCOUNT ID:</strong> ' . $row['AccountID'] . ']' : null) . '<br />';
            $plevel = $row['AdminLevel'];
            $user_list[$row['UserName']] = $row['AdminLevel'];
        }
        if ($plevel != -1) {
            $main .= '</p>';
        }
        $main .= '<hr /><h2>Disable Account</h2>';
        $main .= '<form action="' . $_SERVER['REQUEST_URI'] . '" name="disable_user" id="disable_user" method="post"><p><select name="disable_user">';
        foreach ($user_list as $user_name => $user_level) {
            if ($user_level > 0) {
                $main .= '<option value="' . $user_name . '">' . $user_name . '</option>';
            }
        }
        $main .= '</select></p><p><input name="submit" value="Disable User" type="submit" /></p></form>';
        $main .= '<hr /><h2>Create New Account Group</h2>';
        $main .= '<form name="register_form" id="register_form" action="?admin" method="post" onsubmit="return phoromatic_initial_registration(this);">
		<h3>Username</h3>
		<p><input type="text" name="register_username" /> <sup>1</sup></p>
		<h3>Password</h3>
		<p><input type="password" name="register_password" /> <sup>2</sup></p>
		<h3>Confirm Password</h3>
		<p><input type="password" name="register_password_confirm" /></p>
		<h3>Email</h3>
		<p><input type="text" name="register_email" /> <sup>3</sup></p>
		<h3>Account ID</h3>
		<p><input type="text" name="seed_accountid" /> <sup>4</sup></p>
		<p><input type="submit" value="Create Account" /></p>
		</form>
		<p style="font-size: 11px;"><sup>1</sup> Usernames shall be at least four characters long, not contain any spaces, and only be composed of normal ASCII characters.<br />
		<sup>2</sup> Passwords shall be at least six characters long.<br />
		<sup>3</sup> A valid email address is required for notifications, password reset, and other verification purposes.<br />
		<sup>4</sup> The account ID field is optional and is used to pre-seed the account identifier for advanced purposes. The field must be six characters. Leave this field blank if you are unsure.<br />
						</p>';
        //
        $server_log = explode(PHP_EOL, file_get_contents(getenv('PTS_PHOROMATIC_LOG_LOCATION')));
        foreach ($server_log as $i => $line_item) {
            if (strpos($line_item, '[200]') !== false || strpos($line_item, '[302]') !== false) {
                unset($server_log[$i]);
            }
        }
        $server_log = implode(PHP_EOL, $server_log);
        $main .= '<hr /><h2>Phoromatic Server Log</h2>';
        $main .= '<p><textarea style="width: 80%; height: 400px;">' . $server_log . '</textarea></p>';
        echo phoromatic_webui_header_logged_in();
        echo phoromatic_webui_main($main, phoromatic_webui_right_panel_logged_in());
        echo phoromatic_webui_footer();
    }