<commit_before><?php

/*
 * Copyright 2011 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

class PhabricatorSetup {

  public static function runSetup() {
    header("Content-Type: text/plain");
    self::write("PHABRICATOR SETUP\n\n");

    // Force browser to stop buffering.
    self::write(str_repeat(' ', 2048));
    usleep(250000);

    self::write("This setup mode will guide you through setting up your ".
                "Phabricator configuration.\n");

    self::writeHeader("CORE CONFIGURATION");

    // NOTE: Test this first since other tests depend on the ability to
    // execute system commands and will fail if safe_mode is enabled.
    $safe_mode = ini_get('safe_mode');
    if ($safe_mode) {
      self::writeFailure();
      self::write(
        "Setup failure! You have 'safe_mode' enabled. Phabricator will not ".
        "run in safe mode, and it has been deprecated in PHP 5.3 and removed ".
        "in PHP 5.4.\n");
      return;
    } else {
      self::write(" okay  PHP's deprecated 'safe_mode' is disabled.\n");
    }

    // NOTE: Also test this early since we can't include files from other
    // libraries if this is set strictly.

    $open_basedir = ini_get('open_basedir');
    if ($open_basedir) {

      // 'open_basedir' restricts which files we're allowed to access with
      // file operations. This might be okay -- we don't need to write to
      // arbitrary places in the filesystem -- but we need to access certain
      // resources. This setting is unlikely to be providing any real measure
      // of security so warn even if things look OK.

      try {
        phutil_require_module('phutil', 'utils');
        $open_libphutil = true;
      } catch (Exception $ex) {
        $message = $ex->getMessage();
        self::write("Unable to load modules from libphutil: {$message}\n");
        $open_libphutil = false;
      }

      try {
        phutil_require_module('arcanist', 'workflow/base');
        $open_arcanist = true;
      } catch (Exception $ex) {
        $message = $ex->getMessage();
        self::write("Unable to load modules from Arcanist: {$message}\n");
        $open_arcanist = false;
      }

      $open_urandom = @fopen('/dev/urandom', 'r');
      if (!$open_urandom) {
        self::write("Unable to open /dev/urandom!\n");
      }

      try {
        $tmp = new TempFile();
        file_put_contents($tmp, '.');
        $open_tmp = @fopen((string)$tmp, 'r');
      } catch (Exception $ex) {
        $message = $ex->getMessage();
        $dir = sys_get_temp_dir();
        self::write("Unable to open temp files from '{$dir}': {$message}\n");
        $open_tmp = false;
      }

      if (!$open_urandom || !$open_tmp || !$open_libphutil || !$open_arcanist) {
        self::writeFailure();
        self::write(
          "Setup failure! Your server is configured with 'open_basedir' in ".
          "php.ini which prevents Phabricator from opening files it needs to ".
          "access. Either make the setting more permissive or remove it. It ".
          "is unlikely you derive significant security benefits from having ".
          "this configured; files outside this directory can still be ".
          "accessed through system command execution.");
        return;
      } else {
        self::write(
          "[WARN] You have an 'open_basedir' configured in your php.ini. ".
          "Although the setting seems permissive enough that Phabricator ".
          "will run properly, you may run into problems because of it. It is ".
          "unlikely you gain much real security benefit from having it ".
          "configured, because the application can still access files outside ".
          "the 'open_basedir' by running system commands.\n");
      }
    } else {
      self::write(" okay  'open_basedir' is not set.\n");
    }

    if (!PhabricatorEnv::getEnvConfig('security.alternate-file-domain')) {
      self::write(
        "[WARN] You have not configured 'security.alternate-file-domain'. ".
        "This may make your installation vulnerable to attack. Make sure ".
        "you read the documentation for this parameter and understand the ".
        "consequences of leaving it unconfigured.\n");
    }

    self::write("[OKAY] Core configuration OKAY.\n");

    self::writeHeader("REQUIRED PHP EXTENSIONS");
    $extensions = array(
      'mysql',
      'hash',
      'json',
      'openssl',

      // There is a chance we might not need this, but some configurations (like
      // Amazon SES) will require it. Just mark it 'required' since it's widely
      // available and relatively core.
      'curl',
    );
    foreach ($extensions as $extension) {
      $ok = self::requireExtension($extension);
      if (!$ok) {
        self::writeFailure();
        self::write("Setup failure! Install PHP extension '{$extension}'.");
        return;
      }
    }

    $root = dirname(phutil_get_library_root('phabricator'));

    // On RHEL6, doing a distro install of pcntl makes it available from the
    // CLI binary but not from the Apache module. This isn't entirely
    // unreasonable and we don't need it from Apache, so do an explicit test
    // for CLI availability.
    list($err, $stdout, $stderr) = exec_manual(
      '%s/scripts/setup/pcntl_available.php',
      $root);
    if ($err) {
      self::writeFailure();
      self::write("Unable to execute scripts/setup/pcntl_available.php.");
      return;
    } else {
      if (trim($stdout) == 'YES') {
        self::write(" okay  pcntl is available from the command line.\n");
        self::write("[OKAY] All extensions OKAY\n");
      } else {<commit_msg>Make "pcntl" script error more explicit<commit_after><?php

/*
 * Copyright 2011 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

class PhabricatorSetup {

  public static function runSetup() {
    header("Content-Type: text/plain");
    self::write("PHABRICATOR SETUP\n\n");

    // Force browser to stop buffering.
    self::write(str_repeat(' ', 2048));
    usleep(250000);

    self::write("This setup mode will guide you through setting up your ".
                "Phabricator configuration.\n");

    self::writeHeader("CORE CONFIGURATION");

    // NOTE: Test this first since other tests depend on the ability to
    // execute system commands and will fail if safe_mode is enabled.
    $safe_mode = ini_get('safe_mode');
    if ($safe_mode) {
      self::writeFailure();
      self::write(
        "Setup failure! You have 'safe_mode' enabled. Phabricator will not ".
        "run in safe mode, and it has been deprecated in PHP 5.3 and removed ".
        "in PHP 5.4.\n");
      return;
    } else {
      self::write(" okay  PHP's deprecated 'safe_mode' is disabled.\n");
    }

    // NOTE: Also test this early since we can't include files from other
    // libraries if this is set strictly.

    $open_basedir = ini_get('open_basedir');
    if ($open_basedir) {

      // 'open_basedir' restricts which files we're allowed to access with
      // file operations. This might be okay -- we don't need to write to
      // arbitrary places in the filesystem -- but we need to access certain
      // resources. This setting is unlikely to be providing any real measure
      // of security so warn even if things look OK.

      try {
        phutil_require_module('phutil', 'utils');
        $open_libphutil = true;
      } catch (Exception $ex) {
        $message = $ex->getMessage();
        self::write("Unable to load modules from libphutil: {$message}\n");
        $open_libphutil = false;
      }

      try {
        phutil_require_module('arcanist', 'workflow/base');
        $open_arcanist = true;
      } catch (Exception $ex) {
        $message = $ex->getMessage();
        self::write("Unable to load modules from Arcanist: {$message}\n");
        $open_arcanist = false;
      }

      $open_urandom = @fopen('/dev/urandom', 'r');
      if (!$open_urandom) {
        self::write("Unable to open /dev/urandom!\n");
      }

      try {
        $tmp = new TempFile();
        file_put_contents($tmp, '.');
        $open_tmp = @fopen((string)$tmp, 'r');
      } catch (Exception $ex) {
        $message = $ex->getMessage();
        $dir = sys_get_temp_dir();
        self::write("Unable to open temp files from '{$dir}': {$message}\n");
        $open_tmp = false;
      }

      if (!$open_urandom || !$open_tmp || !$open_libphutil || !$open_arcanist) {
        self::writeFailure();
        self::write(
          "Setup failure! Your server is configured with 'open_basedir' in ".
          "php.ini which prevents Phabricator from opening files it needs to ".
          "access. Either make the setting more permissive or remove it. It ".
          "is unlikely you derive significant security benefits from having ".
          "this configured; files outside this directory can still be ".
          "accessed through system command execution.");
        return;
      } else {
        self::write(
          "[WARN] You have an 'open_basedir' configured in your php.ini. ".
          "Although the setting seems permissive enough that Phabricator ".
          "will run properly, you may run into problems because of it. It is ".
          "unlikely you gain much real security benefit from having it ".
          "configured, because the application can still access files outside ".
          "the 'open_basedir' by running system commands.\n");
      }
    } else {
      self::write(" okay  'open_basedir' is not set.\n");
    }

    if (!PhabricatorEnv::getEnvConfig('security.alternate-file-domain')) {
      self::write(
        "[WARN] You have not configured 'security.alternate-file-domain'. ".
        "This may make your installation vulnerable to attack. Make sure ".
        "you read the documentation for this parameter and understand the ".
        "consequences of leaving it unconfigured.\n");
    }

    self::write("[OKAY] Core configuration OKAY.\n");

    self::writeHeader("REQUIRED PHP EXTENSIONS");
    $extensions = array(
      'mysql',
      'hash',
      'json',
      'openssl',

      // There is a chance we might not need this, but some configurations (like
      // Amazon SES) will require it. Just mark it 'required' since it's widely
      // available and relatively core.
      'curl',
    );
    foreach ($extensions as $extension) {
      $ok = self::requireExtension($extension);
      if (!$ok) {
        self::writeFailure();
        self::write("Setup failure! Install PHP extension '{$extension}'.");
        return;
      }
    }

    $root = dirname(phutil_get_library_root('phabricator'));

    // On RHEL6, doing a distro install of pcntl makes it available from the
    // CLI binary but not from the Apache module. This isn't entirely
    // unreasonable and we don't need it from Apache, so do an explicit test
    // for CLI availability.
    list($err, $stdout, $stderr) = exec_manual(
      '%s/scripts/setup/pcntl_available.php',
      $root);
    if ($err) {
      self::writeFailure();
      self::write("Unable to execute scripts/setup/pcntl_available.php to ".
                  "test for the availability of pcntl from the CLI.\n".
                  "   err: {$err}\n".
                  "stdout: {$stdout}\n".
                  "stderr: {$stderr}\n");
      return;
    } else {
      if (trim($stdout) == 'YES') {
        self::write(" okay  pcntl is available from the command line.\n");
        self::write("[OKAY] All extensions OKAY\n");
      } else {
{'fraction_non_alphanumeric': 0.11665203861804835, 'fraction_numerical': 0.0036703103805952285, 'mean_word_length': 2.526730444569499, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5992037', 'n_tokens_mistral': 3538, 'n_tokens_neox': 3432, 'n_words': 1253}