int
main (int    argc,
      char **argv)
{
  state_t state = { 0 };
  bool should_help, should_be_verbose;
  bool is_connected;
  int exit_code;

  exit_code = 0;

  signal (SIGPIPE, SIG_IGN);

  state.loop = ply_event_loop_new ();
  state.client = ply_boot_client_new ();
  state.command_parser = ply_command_parser_new ("plymouth-upstart-bridge", "Upstart job state bridge");

  ply_command_parser_add_options (state.command_parser,
                                  "help", "This help message", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  "debug", "Enable verbose debug logging", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  NULL);

  if (!ply_command_parser_parse_arguments (state.command_parser, state.loop, argv, argc))
    {
      char *help_string;

      help_string = ply_command_parser_get_help_string (state.command_parser);

      ply_error ("%s", help_string);

      free (help_string);
      return 1;
    }

  ply_command_parser_get_options (state.command_parser,
                                  "help", &should_help,
                                  "debug", &should_be_verbose,
                                  NULL);

  if (should_help)
    {
      char *help_string;

      help_string = ply_command_parser_get_help_string (state.command_parser);

      puts (help_string);

      free (help_string);
      return 0;
    }

  if (should_be_verbose && !ply_is_tracing ())
    ply_toggle_tracing ();

  setupterm (NULL, STDOUT_FILENO, NULL);

  is_connected = ply_boot_client_connect (state.client,
                                          (ply_boot_client_disconnect_handler_t)
                                          on_disconnect, &state);
  if (!is_connected)
    {
      ply_trace ("daemon not running");
      return 1;
    }

  ply_boot_client_attach_to_event_loop (state.client, state.loop);
  state.upstart = ply_upstart_monitor_new (state.loop);
  if (!state.upstart)
    return 1;
  ply_upstart_monitor_add_state_changed_handler (state.upstart,
                                                 (ply_upstart_monitor_state_changed_handler_t)
                                                 on_state_changed, &state);
  ply_upstart_monitor_add_failed_handler (state.upstart, on_failed, &state);

  exit_code = ply_event_loop_run (state.loop);

  ply_upstart_monitor_free (state.upstart);
  ply_boot_client_free (state.client);

  ply_event_loop_free (state.loop);

  return exit_code;
}
Esempio n. 2
0
int
main (int    argc,
      char **argv)
{
  state_t state = { 0 };
  bool should_help, should_quit, should_ping, should_check_for_active_vt, should_sysinit, should_ask_for_password, should_show_splash, should_hide_splash, should_wait, should_be_verbose, report_error, should_get_plugin_path;
  bool is_connected;
  char *status, *chroot_dir, *ignore_keystroke;
  int exit_code;

  exit_code = 0;

  signal (SIGPIPE, SIG_IGN);

  state.loop = ply_event_loop_new ();
  state.client = ply_boot_client_new ();
  state.command_parser = ply_command_parser_new ("plymouth", "Boot splash control client");

  ply_command_parser_add_options (state.command_parser,
                                  "help", "This help message", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  "debug", "Enable verbose debug logging", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  "get-splash-plugin-path", "Get directory where splash plugins are installed", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  "newroot", "Tell boot daemon that new root filesystem is mounted", PLY_COMMAND_OPTION_TYPE_STRING,
                                  "quit", "Tell boot daemon to quit", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  "ping", "Check of boot daemon is running", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  "has-active-vt", "Check if boot daemon has an active vt", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  "sysinit", "Tell boot daemon root filesystem is mounted read-write", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  "show-splash", "Show splash screen", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  "hide-splash", "Hide splash screen", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  "ask-for-password", "Ask user for password", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  "ignore-keystroke", "Remove sensitivity to a keystroke", PLY_COMMAND_OPTION_TYPE_STRING,
                                  "update", "Tell boot daemon an update about boot progress", PLY_COMMAND_OPTION_TYPE_STRING,
                                  "details", "Tell boot daemon there were errors during boot", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  "wait", "Wait for boot daemon to quit", PLY_COMMAND_OPTION_TYPE_FLAG,
                                  NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "update", "Tell daemon about boot status changes",
                                  (ply_command_handler_t)
                                  on_update_request, &state,
                                  "status", "Tell daemon the current boot status",
                                  PLY_COMMAND_OPTION_TYPE_STRING,
                                  NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "update-root-fs", "Tell daemon about root filesystem changes",
                                  (ply_command_handler_t)
                                  on_update_root_fs_request, &state,
                                  "new-root-dir", "Root filesystem is about to change",
                                  PLY_COMMAND_OPTION_TYPE_STRING,
                                  "read-write", "Root filesystem is no longer read-only",
                                  PLY_COMMAND_OPTION_TYPE_FLAG,
                                  NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "show-splash", "Tell daemon to show splash screen",
                                  (ply_command_handler_t)
                                  on_show_splash_request, &state,
                                  NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "hide-splash", "Tell daemon to hide splash screen",
                                  (ply_command_handler_t)
                                  on_hide_splash_request, &state,
                                  NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "ask-for-password", "Ask user for password",
                                  (ply_command_handler_t)
                                  on_password_request, &state,
                                  "command", "Command to send password to via standard input",
                                  PLY_COMMAND_OPTION_TYPE_STRING,
                                  "prompt", "Message to display when asking for password",
                                  PLY_COMMAND_OPTION_TYPE_STRING,
                                  "number-of-tries", "Number of times to ask before giving up (requires --command)",
                                  PLY_COMMAND_OPTION_TYPE_INTEGER,
                                  "dont-pause-progress", "Don't pause boot progress bar while asking",
                                  PLY_COMMAND_OPTION_TYPE_FLAG,
                                  NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "ask-question", "Ask user a question",
                                  (ply_command_handler_t)
                                  on_question_request, &state,
                                  "command", "Command to send the answer to via standard input",
                                  PLY_COMMAND_OPTION_TYPE_STRING,
                                  "prompt", "Message to display when asking the question",
                                  PLY_COMMAND_OPTION_TYPE_STRING,
                                  "dont-pause-progress", "Don't pause boot progress bar while asking",
                                  PLY_COMMAND_OPTION_TYPE_FLAG,
                                  NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "message", "Display a message",
                                  (ply_command_handler_t)
                                  on_message_request, &state,
                                  "text", "The message text",
                                  PLY_COMMAND_OPTION_TYPE_STRING,
                                  NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "watch-keystroke", "Become sensitive to a keystroke",
                                  (ply_command_handler_t)
                                  on_keystroke_request, &state,
                                  "command", "Command to send keystroke to via standard input",
                                  PLY_COMMAND_OPTION_TYPE_STRING,
                                  "keys", "Keys to become sensitive to",
                                  PLY_COMMAND_OPTION_TYPE_STRING,
                                  NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "pause-progress", "Pause boot progress bar",
                                  (ply_command_handler_t)
                                  on_progress_pause_request, &state,
                                  NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "unpause-progress", "Unpause boot progress bar",
                                  (ply_command_handler_t)
                                  on_progress_unpause_request, &state,
                                  NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "report-error", "Tell boot daemon there were errors during boot",
                                  (ply_command_handler_t)
                                  on_report_error_request, &state,
                                  NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "deactivate", "Tell boot daemon to deactivate",
                                  (ply_command_handler_t)
                                  on_deactivate_request, &state, NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "reactivate", "Tell boot daemon to reactivate",
                                  (ply_command_handler_t)
                                  on_reactivate_request, &state, NULL);

  ply_command_parser_add_command (state.command_parser,
                                  "quit", "Tell boot daemon to quit",
                                  (ply_command_handler_t)
                                  on_quit_request, &state,
                                  "retain-splash", "Don't explicitly hide boot splash on exit",
                                  PLY_COMMAND_OPTION_TYPE_FLAG, NULL);

  if (!ply_command_parser_parse_arguments (state.command_parser, state.loop, argv, argc))
    {
      char *help_string;

      help_string = ply_command_parser_get_help_string (state.command_parser);

      ply_error ("%s", help_string);

      free (help_string);
      return 1;
    }

  ply_command_parser_get_options (state.command_parser,
                                  "help", &should_help,
                                  "debug", &should_be_verbose,
                                  "get-splash-plugin-path", &should_get_plugin_path,
                                  "newroot", &chroot_dir,
                                  "quit", &should_quit,
                                  "ping", &should_ping,
                                  "has-active-vt", &should_check_for_active_vt,
                                  "sysinit", &should_sysinit,
                                  "show-splash", &should_show_splash,
                                  "hide-splash", &should_hide_splash,
                                  "ask-for-password", &should_ask_for_password,
                                  "ignore-keystroke", &ignore_keystroke,
                                  "update", &status,
                                  "wait", &should_wait,
                                  "details", &report_error,
                                  NULL);

  if (should_help || argc < 2)
    {
      char *help_string;

      help_string = ply_command_parser_get_help_string (state.command_parser);

      if (argc < 2)
        fprintf (stderr, "%s", help_string);
      else
        printf ("%s", help_string);

      free (help_string);
      return 0;
    }

  if (get_kernel_command_line (&state))
    {
      if (strstr (state.kernel_command_line, "plymouth:debug") != NULL
          && !ply_is_tracing ())
        ply_toggle_tracing ();
    }

  if (should_be_verbose && !ply_is_tracing ())
    ply_toggle_tracing ();

  if (should_get_plugin_path)
    {
      printf ("%s\n", PLYMOUTH_PLUGIN_PATH);
      return 0;
    }

  is_connected = ply_boot_client_connect (state.client,
                                          (ply_boot_client_disconnect_handler_t)
                                          on_disconnect, &state);
  if (!is_connected)
    {
      ply_trace ("daemon not running");

      if (should_ping)
        {
          ply_trace ("ping failed");
          return 1;
        }
      if (should_check_for_active_vt)
        {
          ply_trace ("has active vt? failed");
          return 1;
        }
    }

  ply_boot_client_attach_to_event_loop (state.client, state.loop);

  if (should_show_splash)
    ply_boot_client_tell_daemon_to_show_splash (state.client,
                                               (ply_boot_client_response_handler_t)
                                               on_success,
                                               (ply_boot_client_response_handler_t)
                                               on_failure, &state);
  else if (should_hide_splash)
    ply_boot_client_tell_daemon_to_hide_splash (state.client,
                                               (ply_boot_client_response_handler_t)
                                               on_success,
                                               (ply_boot_client_response_handler_t)
                                               on_failure, &state);
  else if (should_quit)
    ply_boot_client_tell_daemon_to_quit (state.client,
                                         false,
                                         (ply_boot_client_response_handler_t)
                                         on_success,
                                         (ply_boot_client_response_handler_t)
                                         on_failure, &state);
  else if (should_ping)
    ply_boot_client_ping_daemon (state.client,
                                 (ply_boot_client_response_handler_t)
                                 on_success, 
                                 (ply_boot_client_response_handler_t)
                                 on_failure, &state);
  else if (should_check_for_active_vt)
    ply_boot_client_ask_daemon_has_active_vt (state.client,
                                              (ply_boot_client_response_handler_t)
                                              on_success,
                                              (ply_boot_client_response_handler_t)
                                              on_failure, &state);
  else if (status != NULL)
    ply_boot_client_update_daemon (state.client, status,
                                   (ply_boot_client_response_handler_t)
                                   on_success, 
                                   (ply_boot_client_response_handler_t)
                                   on_failure, &state);
  else if (should_ask_for_password)
    {
      password_answer_state_t answer_state = { 0 };

      answer_state.state = &state;
      answer_state.number_of_tries_left = 1;
      ply_boot_client_ask_daemon_for_password (state.client,
                                               NULL,
                                               (ply_boot_client_answer_handler_t)
                                               on_password_answer,
                                               (ply_boot_client_response_handler_t)
                                               on_password_answer_failure, &answer_state);
    }
  else if (ignore_keystroke)
    {
      ply_boot_client_ask_daemon_to_ignore_keystroke (state.client,
                                           ignore_keystroke,
                                           (ply_boot_client_answer_handler_t)
                                           on_success,
                                           (ply_boot_client_response_handler_t)
                                           on_failure, &state);
    }
  else if (should_sysinit)
    ply_boot_client_tell_daemon_system_is_initialized (state.client,
                                   (ply_boot_client_response_handler_t)
                                   on_success, 
                                   (ply_boot_client_response_handler_t)
                                   on_failure, &state);
  else if (chroot_dir)
    ply_boot_client_tell_daemon_to_change_root (state.client, chroot_dir,
                                   (ply_boot_client_response_handler_t)
                                   on_success,
                                   (ply_boot_client_response_handler_t)
                                   on_failure, &state);

  else if (should_wait)
    {} // Do nothing
  else if (report_error)
    ply_boot_client_tell_daemon_about_error (state.client,
                                             (ply_boot_client_response_handler_t)
                                             on_success,
                                             (ply_boot_client_response_handler_t)
                                             on_failure, &state);

  exit_code = ply_event_loop_run (state.loop);

  ply_boot_client_free (state.client);

  ply_event_loop_free (state.loop);

  return exit_code;
}