예제 #1
0
파일: plymouth.c 프로젝트: pkt/pkt-plymouth
static void
on_password_request_execute (password_answer_state_t *password_answer_state,
                             ply_boot_client_t       *client)
{
  ply_trace ("executing password request (command %s)",
             password_answer_state->command);

  if (password_answer_state->command != NULL)
    {
      ply_boot_client_ask_daemon_for_cached_passwords (client,
                                                       (ply_boot_client_multiple_answers_handler_t)
                                                       on_multiple_password_answers,
                                                       (ply_boot_client_response_handler_t)
                                                       on_password_answer_failure, password_answer_state);
    }
  else
    {
      ply_boot_client_ask_daemon_for_password (client,
                                               password_answer_state->prompt,
                                               (ply_boot_client_answer_handler_t)
                                               on_password_answer,
                                               (ply_boot_client_response_handler_t)
                                               on_password_answer_failure, password_answer_state);
    }
}
예제 #2
0
파일: plymouth.c 프로젝트: pkt/pkt-plymouth
static void
on_multiple_password_answers (password_answer_state_t     *answer_state,
                              const char * const          *answers)
{
  bool need_to_ask_user;
  int i;
  int exit_status;

  assert (answer_state->command != NULL);

  ply_trace ("on multiple password answers");

  need_to_ask_user = true;

  if (answers != NULL)
    {
      ply_trace ("daemon has a few candidate passwords for us to try");
      for (i = 0; answers[i] != NULL; i++)
        {
          bool command_started;
          exit_status = 127;
          command_started = answer_via_command (answer_state->command, answers[i],
                                                &exit_status);
          if (command_started && WIFEXITED (exit_status) &&
              WEXITSTATUS (exit_status) == 0)
            {
              need_to_ask_user = false;
              break;
            }
        }
    }
  else
    {
      ply_trace ("daemon has no candidate passwords for us to try");
    }

  if (need_to_ask_user)
    {
      ply_boot_client_ask_daemon_for_password (answer_state->state->client,
                                               answer_state->prompt,
                                               (ply_boot_client_answer_handler_t)
                                               on_password_answer,
                                               (ply_boot_client_response_handler_t)
                                               on_password_answer_failure, answer_state);
      return;
    }

  ply_event_loop_exit (answer_state->state->loop, 0);
}
예제 #3
0
Plymouth::answer_t Plymouth::askPassword(const std::string & prompt, std::string & answer){
    ply_boot_client_attach_to_event_loop(_ply_client, _ply_event_loop);

    auto answer_helper = [this, &answer] (const char * _answer, int exit_status) -> void {
	if(_answer == 0 || _answer[0] == KEY_CTRL_C){
	    exit_status = CANCELED;
	}
	if(exit_status == OK){
	    answer.assign(_answer);
	}
	ply_event_loop_exit(_ply_event_loop, exit_status);
    };
    typedef decltype(answer_helper) answer_helper_t;
    auto answer_hdl = [] (void * data, const char * answer, ply_boot_client_t *) -> void{
	(*reinterpret_cast<answer_helper_t*>(data))(answer, OK);
    };
    auto fail_hdl = [] (void *data, ply_boot_client_t*) -> void{
	(*reinterpret_cast<answer_helper_t*>(data))("", CANCELED);
    };
    ply_boot_client_ask_daemon_for_password(_ply_client, prompt.c_str(), answer_hdl, fail_hdl, &answer_helper);

    return static_cast<answer_t>(ply_event_loop_run(_ply_event_loop));
}
예제 #4
0
파일: plymouth.c 프로젝트: pkt/pkt-plymouth
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;
}
예제 #5
0
파일: plymouth.c 프로젝트: pkt/pkt-plymouth
static void
on_password_answer (password_answer_state_t   *answer_state,
                    const char                *answer,
                    ply_boot_client_t         *client)
{
  int exit_status;

  exit_status = 127;
  if (answer != NULL && answer[0] != KEY_CTRL_C)  /* a CTRL-C answer means the user canceled */
    {
      if (answer_state->command != NULL)
        {
          bool command_started = false;

          command_started = answer_via_command (answer_state->command, answer,
                                                &exit_status);

          if (command_started && (!WIFEXITED (exit_status) ||
              WEXITSTATUS (exit_status) != 0))
            {
              answer_state->number_of_tries_left--;

              if (answer_state->number_of_tries_left > 0)
                {
                  ply_boot_client_ask_daemon_for_password (answer_state->state->client,
                                                           answer_state->prompt,
                                                           (ply_boot_client_answer_handler_t)
                                                           on_password_answer,
                                                           (ply_boot_client_response_handler_t)
                                                           on_password_answer_failure,
                                                           answer_state);
                  return;
                }
            }
        }
      else
        {
          write (STDOUT_FILENO, answer, strlen (answer));
          exit_status = 0;
        }
    }
  else if (answer == NULL)
    {
      on_password_answer_failure (answer_state, answer_state->state->client);
    }

  if (WIFSIGNALED (exit_status))
    raise (WTERMSIG (exit_status));
  
  if (answer_state->pause)
    {
      ply_boot_client_tell_daemon_to_progress_unpause (client,
                                                       (ply_boot_client_response_handler_t)
                                                       (WEXITSTATUS (exit_status) ? on_failure : on_success),
                                                       (ply_boot_client_response_handler_t)
                                                       on_failure,
                                                       answer_state->state);
    }
  else
    ply_event_loop_exit (answer_state->state->loop, WEXITSTATUS (exit_status));
}