// Copyright 2019 The Bazel Authors. All rights reserved.
//
// 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.

// daemonize [-a] -l log_path -p pid_path [-c cgroup] [-s systemd_wrapper_path]
// -- binary_path binary_name [args]
//
// daemonize spawns a program as a daemon, redirecting all of its output to the
// given log_path and writing the daemon's PID to pid_path.  binary_path
// specifies the full location of the program to execute and binary_name
// indicates its display name (aka argv[0], so the optional args do not have to
// specify it again).  log_path is created/truncated unless the -a (append) flag
// is specified.  Also note that pid_path is guaranteed to exists when this
// program terminates successfully.
//
// Some important details about the implementation of this program:
//
// * No threads to ensure the use of fork below does not cause trouble.
//
// * Pure C, no C++. This is intentional to keep the program low overhead
//   and to avoid the accidental introduction of heavy dependencies that
//   could spawn threads.
//
// * Error handling is extensive but there is no error propagation.  Given
//   that the goal of this program is just to spawn another one as a daemon,
//   we take the freedom to immediatey exit from anywhere as soon as we
//   hit an error.

#include <assert.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include "src/main/tools/logging.h"
#include "src/main/tools/process-tools.h"

// Configures std{in,out,err} of the current process to serve as a daemon.
//
// stdin is configured to read from /dev/null.
//
// stdout and stderr are configured to write to log_path, which is created and
// truncated unless log_append is set to true, in which case it is open for
// append if it exists.
static void SetupStdio(const char* log_path, bool log_append) {
  close(STDIN_FILENO);
  int fd = open("/dev/null", O_RDONLY);
  if (fd == -1) {
    err(EXIT_FAILURE, "Failed to open /dev/null");
  }
  assert(fd == STDIN_FILENO);

  close(STDOUT_FILENO);
  int flags = O_WRONLY | O_CREAT | (log_append ? O_APPEND : O_TRUNC);
  fd = open(log_path, flags, 0666);
  if (fd == -1) {
    err(EXIT_FAILURE, "Failed to create log file %s", log_path);
  }
  assert(fd == STDOUT_FILENO);

  close(STDERR_FILENO);
  fd = dup(STDOUT_FILENO);
  if (fd == -1) {
    err(EXIT_FAILURE, "dup failed");
  }
  assert(fd == STDERR_FILENO);

  global_debug = stderr;
}

// Writes the given pid to a new file at pid_path.
//
// Once the pid file has been created, this notifies pid_done_fd by writing a
// dummy character to it and closing it.
static void WritePidFile(pid_t pid, const char* pid_path, int pid_done_fd) {
  FILE* pid_file = fopen(pid_path, "w");
  if (pid_file == NULL) {
    err(EXIT_FAILURE, "Failed to create %s", pid_path);
  }
  if (fprintf(pid_file, "%d", pid) < 0) {
    err(EXIT_FAILURE, "Failed to write pid %d to %s", pid, pid_path);
  }
  if (fclose(pid_file) < 0) {
    err(EXIT_FAILURE, "Failed to write pid %d to %s", pid, pid_path);
  }

  char dummy = '\0';
  int ret = 0;
  while (ret == 0) {
    ret = write(pid_done_fd, &dummy, sizeof(dummy));
    if (ret == -1 && errno == EINTR) {
      ret = 0;
    }
  }
  if (ret != 1) {
    err(EXIT_FAILURE, "Failed to signal pid done");
  }
  close(pid_done_fd);
}

#ifdef __linux__
static bool ShellEscapeNeeded(const char* arg) {
  static const char kDontNeedShellEscapeChars[] =
      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      "abcdefghijklmnopqrstuvwxyz"
      "0123456789+-_.=/:,@";

  for (int i = 0; arg[i]; i++) {
    if (strchr(kDontNeedShellEscapeChars, arg[i]) == NULL) {
      // If any character is not in the list, we need to escape the string.
      return true;
    }
  }
  return false;
}

// Similar to what absl::ShellEscape does. We'd like to escape the arguments
// passed to the shell script, but we cannot use absl::ShellEscape because we
// want to keep this tool pure C.
static char* ShellEscape(const char* arg) {
  if (!arg) {
    return NULL;
  }

  if (!ShellEscapeNeeded(arg)) {
    return strdup(arg);
  }

  bool has_single_quotes = false;
  for (size_t i = 0; arg[i]; i++) {
    if (arg[i] == '\'') {
      has_single_quotes = true;
      break;
    }
  }

  if (!has_single_quotes) {
    // When there are no single quotes, we can just escape the string with
    // single quotes.
    char* escaped_string;
    asprintf(&escaped_string, "'%s'", arg);
    return escaped_string;
  }

  // For all other cases, we wrap everything in double quotes.
  size_t escaped_len = 0;

  for (size_t i = 0; arg[i]; i++) {
    switch (arg[i]) {
      case '\\':
      case '$':
      case '"':
      case '`':
        escaped_len++;
    }
    escaped_len++;
  }

  char* escaped_string = (char*)malloc(
      escaped_len +
      3);  // +2 for double quotes, and +1 for the null terminator.

  size_t j = 0;
  escaped_string[j++] = '"';
  for (size_t i = 0; arg[i]; i++) {
    switch (arg[i]) {
      case '\\':
      case '$':
      case '"':
      case '`':
        escaped_string[j++] = '\\';
    }
    escaped_string[j++] = arg[i];
  }
  escaped_string[j++] = '"';
  escaped_string[j] = '\0';

  return escaped_string;
}

// Prepares the shell script for systemd-run to execute.
//
// We wrap everything inside a shell script file for systemd-run in order to
// create a transient cgroup for the Java server to use. With a user cgroup
// created like this, we can control the resources without root permission.
//
// We cannot do this directly with a command because we'll get a "Filename too
// long" error, which indicates that the command is too long as we have almost
// 100 arguments in the list.
static void WriteSystemdWrapper(const char* systemd_wrapper_path,
                                const char* exe, char** argv) {
  FILE* systemd_wrapper_fp = fopen(systemd_wrapper_path, "w");
  if (systemd_wrapper_fp == NULL) {
    err(EXIT_FAILURE, "Failed to create %s", systemd_wrapper_path);
  }

  char* escaped_argv0 = ShellEscape(argv[0]);
  if (fprintf(systemd_wrapper_fp, "#!/bin/bash\nexec -a %s %s", escaped_argv0,
              exe) < 0) {
    err(EXIT_FAILURE, "Failed to write content to %s", systemd_wrapper_path);
  }
  free(escaped_argv0);

  int argc = 1;
  while (argv[argc]) {
    char* escaped_arg = ShellEscape(argv[argc]);
    if (fprintf(systemd_wrapper_fp, " %s", escaped_arg) < 0) {
      err(EXIT_FAILURE, "Failed to write content to %s", systemd_wrapper_path);
    }
    free(escaped_arg);
    argc++;
  }

  if (fclose(systemd_wrapper_fp) < 0) {
    err(EXIT_FAILURE, "Failed to fclose file %s", systemd_wrapper_path);
  }
}

static bool IsBinaryExecutable(const char* binary_path) {
  return access(binary_path, X_OK) == 0;
}
#endif

static void ExecAsDaemon(const char* log_path, bool log_append,
                         const char* systemd_wrapper_path, int pid_done_fd,
                         const char* exe, char** argv)
    __attribute__((noreturn));

// Executes the requested binary configuring it to behave as a daemon.
//
// The stdout and stderr of the current process are redirected to the given
// log_path.  See SetupStdio for details on how this is handled.
//
// This blocks execution until pid_done_fd receives a write.  We do this
// because the Bazel server process (which is what we start with this helper
// binary) requires the PID file to be present at startup time so we must
// wait until the parent process has created it.
//
// This function never returns.
static void ExecAsDaemon(const char* log_path, bool log_append,
                         const char* systemd_wrapper_path, int pid_done_fd,
                         const char* exe, char** argv) {
  char dummy;
  if (read(pid_done_fd, &dummy, sizeof(dummy)) == -1) {
    err(EXIT_FAILURE, "Failed to wait for pid file creation");
  }
  close(pid_done_fd);

  if (signal(SIGHUP, SIG_IGN) == SIG_ERR) {
    err(EXIT_FAILURE, "Failed to install SIGHUP handler");
  }

  if (setsid() == -1) {
    err(EXIT_FAILURE, "setsid failed");
  }

  SetupStdio(log_path, log_append);

#ifdef __linux__
  // When it's running on linux, and the systemd wrapper path is provided, we
  // try to replace the current process with systemd-run. In all other cases,
  // including the cases when systemd-run is not available, we replace it with
  // the original exe.
  const char* systemd_run_path = "/usr/bin/systemd-run";
  if (systemd_wrapper_path != NULL && IsBinaryExecutable(systemd_run_path)) {
    // Even if systemd-run is present and executable, we still need to run a
    // command first to check if we can use it. There are some cases when the
    // environment is not set up correctly, e.g. no DBUS available.
    char* systemd_test_command;
    asprintf(&systemd_test_command, "%s --user --scope -- /bin/true",
             systemd_run_path);
    int status = system(systemd_test_command);
    free(systemd_test_command);

    if (status == 0) {
      WriteSystemdWrapper(systemd_wrapper_path, exe, argv);

      execl(systemd_run_path, systemd_run_path, "--user", "--scope", "--",
            "/bin/bash", systemd_wrapper_path, NULL);
      err(EXIT_FAILURE, "Failed to execute %s with systemd-run.", exe);
    }
  }

#endif

  execv(exe, argv);
  err(EXIT_FAILURE, "Failed to execute %s", exe);
}

#ifdef __linux__
// Moves the bazel server into the specified cgroup for all the discovered
// cgroups. This is useful when using the cgroup features in bazel and thus the
// server must be started in a user-writable cgroup. Users can specify a
// pre-setup cgroup where the server will be moved to. This is enabled by
// the --experimental_cgroup_parent startup flag.
static void MoveToCgroup(pid_t pid, const char* cgroup_path) {
  FILE* mounts_fp = fopen("/proc/self/mounts", "r");
  if (mounts_fp == NULL) {
    err(EXIT_FAILURE, "Failed to open /proc/self/mounts");
  }

  char* line = NULL;
  size_t len = 0;
  while (getline(&line, &len, mounts_fp) != -1) {
    char* saveptr;
    strtok_r(line, " ", &saveptr);
    char* fs_file = strtok_r(NULL, " ", &saveptr);
    char* fs_vfstype = strtok_r(NULL, " ", &saveptr);
    if (strcmp(fs_vfstype, "cgroup") == 0 ||
        strcmp(fs_vfstype, "cgroup2") == 0) {
      char* procs_path;
      asprintf(&procs_path, "%s%s/cgroup.procs", fs_file, cgroup_path);
      FILE* procs = fopen(procs_path, "w");
      if (procs == NULL) {
        PRINT_DEBUG(
            "Failed to open %s. Falling back to running without cgroups",
            procs_path);
      } else if (fprintf(procs, "%d", pid) < 0) {
        PRINT_DEBUG(
            "Failed to write %s. Falling back to running without cgroups",
            procs_path);
      } else if (fclose(procs) < 0) {
        PRINT_DEBUG(
            "Failed to close %s. Falling back to running without cgroups",
            procs_path);
      }
      free(procs_path);
    }
  }
  free(line);
  fclose(mounts_fp);
}
#endif

// Starts the given process as a daemon.
//
// This spawns a subprocess that will be configured to run the desired program
// as a daemon.  The program to run is supplied in exe and the arguments to it
// are given in the NULL-terminated argv.  argv[0] must be present and
// contain the program name (which may or may not match the basename of exe).
static void Daemonize(const char* log_path, bool log_append,
                      const char* pid_path, const char* cgroup_path,
                      const char* systemd_wrapper_path, const char* exe,
                      char** argv) {
  assert(argv[0] != NULL);

  int pid_done_fds[2];
  if (pipe(pid_done_fds) == -1) {
    err(EXIT_FAILURE, "pipe failed");
  }

  pid_t pid = fork();
  if (pid == -1) {
    err(EXIT_FAILURE, "fork failed");
  } else if (pid == 0) {
    close(pid_done_fds[1]);
#ifdef __linux__
    if (cgroup_path != NULL) {
      MoveToCgroup(pid, cgroup_path);
    }
#endif
    ExecAsDaemon(log_path, log_append, systemd_wrapper_path, pid_done_fds[0],
                 exe, argv);
    abort();  // NOLINT Unreachable.
  }
  close(pid_done_fds[0]);

  WritePidFile(pid, pid_path, pid_done_fds[1]);
}

// Program entry point.
//
// The primary responsibility of this function is to parse program options.
// Once that is done, delegates all work to Daemonize.
int main(int argc, char** argv) {
  bool log_append = false;
  const char* log_path = NULL;
  const char* pid_path = NULL;
  const char* cgroup_path = NULL;
  const char* systemd_wrapper_path = NULL;
  int opt;
  while ((opt = getopt(argc, argv, ":al:p:c:s:")) != -1) {
    switch (opt) {
      case 'a':
        log_append = true;
        break;

      case 'l':
        log_path = optarg;
        break;

      case 'p':
        pid_path = optarg;
        break;

      case 'c':
        cgroup_path = optarg;
        break;

      case 's':
        systemd_wrapper_path = optarg;
        break;

      case ':':
        errx(EXIT_FAILURE, "Option -%c requires an argument", optopt);

      case '?':
      default:
        errx(EXIT_FAILURE, "Unknown option -%c", optopt);
    }
  }
  argc -= optind;
  argv += optind;

  if (log_path == NULL) {
    errx(EXIT_FAILURE, "Must specify a log file with -l");
  }
  if (pid_path == NULL) {
    errx(EXIT_FAILURE, "Must specify a pid file with -p");
  }

  if (argc < 2) {
    errx(EXIT_FAILURE, "Must provide at least an executable name and arg0");
  }
  Daemonize(log_path, log_append, pid_path, cgroup_path, systemd_wrapper_path,
            argv[0], argv + 1);
  return EXIT_SUCCESS;
}
