static void ply_boot_connection_send_answer (ply_boot_connection_t *connection, const char *answer) { uint32_t size; /* splash plugin isn't able to ask for password, * punt to client */ if (answer == NULL) { if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER))) ply_error ("could not write bytes: %m"); } else { size = strlen (answer); if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER)) || !ply_write_uint32 (connection->fd, size) || !ply_write (connection->fd, answer, size)) ply_error ("could not write bytes: %m"); } }
static void script_parse_error (script_debug_location_t *location, const char *message) { ply_error ("Parser error \"%s\" L:%d C:%d : %s\n", location->name, location->line_index, location->column_index, message); }
static void ply_boot_connection_on_quit_complete (ply_boot_connection_t *connection) { ply_trace ("quit complete"); if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK))) { ply_error ("could not write bytes: %m"); } }
static void on_disconnect (state_t *state) { bool wait; int status = 0; wait = false; ply_command_parser_get_options (state->command_parser, "wait", &wait, NULL ); if (! wait) { ply_error ("error: unexpectedly disconnected from boot status daemon"); status = 2; } ply_trace ("disconnect"); ply_event_loop_exit (state->loop, status); }
script_op_t *script_parse_file (const char *filename) { script_scan_t *scan = script_scan_file (filename); if (!scan) { ply_error ("Parser error : Error opening file %s\n", filename); return NULL; } script_scan_token_t *curtoken = script_scan_get_current_token (scan); script_debug_location_t location = curtoken->location; ply_list_t *list = script_parse_op_list (scan); curtoken = script_scan_get_current_token (scan); if (curtoken->type != SCRIPT_SCAN_TOKEN_TYPE_EOF) { script_parse_error (&curtoken->location, "Unparsed characters at end of file"); return NULL; } script_op_t *op = script_parse_new_op_block (list, &location); script_scan_free (scan); return op; }
static void ply_boot_connection_on_request (ply_boot_connection_t *connection) { ply_boot_server_t *server; char *command, *argument; assert (connection != NULL); assert (connection->fd >= 0); server = connection->server; assert (server != NULL); if (!ply_boot_connection_read_request (connection, &command, &argument)) { ply_trace ("could not read connection request"); return; } if (!ply_boot_connection_is_from_root (connection)) { ply_error ("request came from non-root user"); if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK))) ply_error ("could not write bytes: %m"); free (command); return; } if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_UPDATE) == 0) { ply_trace ("got update request"); if (server->update_handler != NULL) server->update_handler (server->user_data, argument, server); free (argument); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_SYSTEM_INITIALIZED) == 0) { ply_trace ("got system initialized notification"); if (server->system_initialized_handler != NULL) server->system_initialized_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_ERROR) == 0) { ply_trace ("got error notification"); if (server->error_handler != NULL) server->error_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_SHOW_SPLASH) == 0) { ply_trace ("got show splash request"); if (server->show_splash_handler != NULL) server->show_splash_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_HIDE_SPLASH) == 0) { ply_trace ("got hide splash request"); if (server->hide_splash_handler != NULL) server->hide_splash_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_DEACTIVATE) == 0) { ply_trigger_t *deactivate_trigger; ply_trace ("got deactivate request"); deactivate_trigger = ply_trigger_new (NULL); ply_trigger_add_handler (deactivate_trigger, (ply_trigger_handler_t) ply_boot_connection_on_deactivated, connection); if (server->deactivate_handler != NULL) server->deactivate_handler (server->user_data, deactivate_trigger, server); free (argument); free (command); return; } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_REACTIVATE) == 0) { ply_trace ("got reactivate request"); if (server->reactivate_handler != NULL) server->reactivate_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUIT) == 0) { bool retain_splash; ply_trigger_t *quit_trigger; retain_splash = (bool) argument[0]; ply_trace ("got quit %srequest", retain_splash? "--retain-splash " : ""); quit_trigger = ply_trigger_new (NULL); ply_trigger_add_handler (quit_trigger, (ply_trigger_handler_t) ply_boot_connection_on_quit_complete, connection); if (server->quit_handler != NULL) server->quit_handler (server->user_data, retain_splash, quit_trigger, server); free(argument); free(command); return; } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD) == 0) { ply_trigger_t *answer; ply_trace ("got password request"); answer = ply_trigger_new (NULL); ply_trigger_add_handler (answer, (ply_trigger_handler_t) ply_boot_connection_on_password_answer, connection); if (server->ask_for_password_handler != NULL) server->ask_for_password_handler (server->user_data, argument, answer, server); /* will reply later */ free(command); return; } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_CACHED_PASSWORD) == 0) { ply_list_node_t *node; ply_buffer_t *buffer; size_t buffer_size; uint32_t size; ply_trace ("got cached password request"); buffer = ply_buffer_new (); node = ply_list_get_first_node (server->cached_passwords); ply_trace ("There are %d cached passwords", ply_list_get_length (server->cached_passwords)); /* Add each answer separated by their NUL terminators into * a buffer that we write out to the client */ while (node != NULL) { ply_list_node_t *next_node; const char *password; next_node = ply_list_get_next_node (server->cached_passwords, node); password = (const char *) ply_list_node_get_data (node); ply_buffer_append_bytes (buffer, password, strlen (password) + 1); node = next_node; } buffer_size = ply_buffer_get_size (buffer); /* splash plugin doesn't have any cached passwords */ if (buffer_size == 0) { if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER))) ply_error ("could not write bytes: %m"); } else { size = buffer_size; ply_trace ("writing %d cached answers", ply_list_get_length (server->cached_passwords)); if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_MULTIPLE_ANSWERS, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_MULTIPLE_ANSWERS)) || !ply_write_uint32 (connection->fd, size) || !ply_write (connection->fd, ply_buffer_get_bytes (buffer), size)) ply_error ("could not write bytes: %m"); } ply_buffer_free (buffer); free(command); return; } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUESTION) == 0) { ply_trigger_t *answer; ply_trace ("got question request"); answer = ply_trigger_new (NULL); ply_trigger_add_handler (answer, (ply_trigger_handler_t) ply_boot_connection_on_question_answer, connection); if (server->ask_question_handler != NULL) server->ask_question_handler (server->user_data, argument, answer, server); /* will reply later */ free(command); return; } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_MESSAGE) == 0) { ply_trace ("got message request"); if (server->display_message_handler != NULL) server->display_message_handler(server->user_data, argument, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE) == 0) { ply_trigger_t *answer; ply_trace ("got keystroke request"); answer = ply_trigger_new (NULL); ply_trigger_add_handler (answer, (ply_trigger_handler_t) ply_boot_connection_on_keystroke_answer, connection); if (server->watch_for_keystroke_handler != NULL) server->watch_for_keystroke_handler (server->user_data, argument, answer, server); /* will reply later */ free(command); return; } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE_REMOVE) == 0) { ply_trace ("got keystroke remove request"); if (server->ignore_keystroke_handler != NULL) server->ignore_keystroke_handler (server->user_data, argument, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PROGRESS_PAUSE) == 0) { ply_trace ("got progress pause request"); if (server->progress_pause_handler != NULL) server->progress_pause_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PROGRESS_UNPAUSE) == 0) { ply_trace ("got progress unpause request"); if (server->progress_unpause_handler != NULL) server->progress_unpause_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_NEWROOT) == 0) { ply_trace ("got newroot request"); if (server->newroot_handler != NULL) server->newroot_handler(server->user_data, argument, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_HAS_ACTIVE_VT) == 0) { bool answer = false; ply_trace ("got has_active vt? request"); if (server->has_active_vt_handler != NULL) answer = server->has_active_vt_handler(server->user_data, server); if (!answer) { if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK))) ply_error ("could not write bytes: %m"); free(command); return; } } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PING) != 0) { ply_error ("received unknown command '%s' from client", command); if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK))) ply_error ("could not write bytes: %m"); free(command); return; } if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK))) { ply_error ("could not write bytes: %m"); } free(command); }
static void ply_boot_client_process_incoming_replies (ply_boot_client_t *client) { ply_list_node_t *request_node; ply_boot_client_request_t *request; bool processed_reply; uint8_t byte[2] = ""; uint32_t size; assert (client != NULL); processed_reply = false; if (ply_list_get_length (client->requests_waiting_for_replies) == 0) { ply_error ("received unexpected response from boot status daemon"); return; } if (!ply_read (client->socket_fd, byte, sizeof (uint8_t))) goto out; for (request_node = ply_list_get_first_node (client->requests_waiting_for_replies); request_node; request_node = ply_list_get_next_node (client->requests_waiting_for_replies, request_node)) { assert (request_node != NULL); request = (ply_boot_client_request_t *) ply_list_node_get_data (request_node); assert (request != NULL); if (! strcmp (request->command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD) || ! strcmp (request->command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUESTION) || ! strcmp (request->command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE)) { if (! memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER, sizeof (uint8_t)) || ! memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER, sizeof (uint8_t))) break; } else { if (memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER, sizeof (uint8_t)) && memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER, sizeof (uint8_t))) break; } } if (memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK, sizeof (uint8_t)) == 0) request->handler (request->user_data, client); else if (memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER, sizeof (uint8_t)) == 0) { char *answer; if (!ply_read_uint32 (client->socket_fd, &size)) goto out; answer = malloc ((size+1) * sizeof(char)); if (size > 0) { if (!ply_read (client->socket_fd, answer, size)) goto out; } answer[size] = '\0'; ((ply_boot_client_answer_handler_t) request->handler) (request->user_data, answer, client); free(answer); } else if (memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_MULTIPLE_ANSWERS, sizeof (uint8_t)) == 0) { ply_array_t *array; char **answers; char *answer; char *p; char *q; uint8_t i; array = NULL; answers = NULL; if (!ply_read_uint32 (client->socket_fd, &size)) goto out; assert (size > 0); answer = malloc (size); if (!ply_read (client->socket_fd, answer, size)) { free (answer); goto out; } array = ply_array_new (); p = answer; q = p; for (i = 0; i < size; i++, q++) { if (*q == '\0') { ply_array_add_element (array, strdup (p)); p = q + 1; } } free (answer); answers = (char **) ply_array_steal_elements (array); ply_array_free (array); ((ply_boot_client_multiple_answers_handler_t) request->handler) (request->user_data, (const char * const *) answers, client); ply_free_string_array (answers); } else if (memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER, sizeof (uint8_t)) == 0) { ((ply_boot_client_answer_handler_t) request->handler) (request->user_data, NULL, client); } else goto out; processed_reply = true; out: if (!processed_reply) { if (request->failed_handler != NULL) request->failed_handler (request->user_data, client); } ply_list_remove_node (client->requests_waiting_for_replies, request_node); if (ply_list_get_length (client->requests_waiting_for_replies) == 0) { if (client->daemon_has_reply_watch != NULL) { assert (client->loop != NULL); ply_event_loop_stop_watching_fd (client->loop, client->daemon_has_reply_watch); client->daemon_has_reply_watch = NULL; } } }
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; }
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; }