summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rwxr-xr-xscripts/plymouth-update-initrd2
-rw-r--r--src/main.c31
-rw-r--r--src/ply-boot-server.c53
-rw-r--r--src/ply-boot-server.h7
-rw-r--r--src/ply-boot-splash-plugin.h6
-rw-r--r--src/ply-boot-splash.c9
-rw-r--r--src/ply-boot-splash.h5
-rw-r--r--src/splash-plugins/text/text.c72
9 files changed, 131 insertions, 57 deletions
diff --git a/TODO b/TODO
index b100d37..309c7b6 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,6 @@
- fix the tests so that they work better with "make check"
- Allow plymouth to be started from nash instead of the other way around
- Drop all the make ram disk and copy code. That was just to make bolting things on easier. We can integrate now.
+- allow longer than 255 byte replies from server to client
+- make server send immediate ACK for password request and then ANSWER later with a link back to original request in ANSWER
+- add ask-for-password support to fedora-fade-in and details plugins
diff --git a/scripts/plymouth-update-initrd b/scripts/plymouth-update-initrd
index 99032ae..2615f54 100755
--- a/scripts/plymouth-update-initrd
+++ b/scripts/plymouth-update-initrd
@@ -31,7 +31,7 @@ TMPDIR="$(mktemp -d $PWD/initrd.XXXXXXXXXX)"
(cd $TMPDIR
zcat $INITRD | cpio --quiet -Hnewc -i --make-directories
sed -i -e 's@^#!\(.*\)@#!/bin/plymouthd \1\n@' init
- sed -i -e 's@setquiet@&\n/bin/plymouth --show-splash@' init
+ sed -i -e 's@setquiet@&\n/bin/plymouth --show-splash\n/bin/plymouth --ask-for-password@' init
(cd $LIBDIR
DEPS=$(get_lib_deps ${LIBEXECDIR}/plymouth/plymouth ${LIBDIR}/plymouth/fedora-fade-in.so ${LIBDIR}/plymouth/text.so ${LIBDIR}/plymouth/details.so)
for dep in $DEPS; do
diff --git a/src/main.c b/src/main.c
index 6bfd839..eb5c724 100644
--- a/src/main.c
+++ b/src/main.c
@@ -99,10 +99,35 @@ on_update (state_t *state,
status);
}
-static char *
-on_ask_for_password (state_t *state)
+typedef struct
+{
+ ply_boot_server_password_answer_handler_t handler;
+ void *data;
+ state_t *state;
+} password_answer_closure_t;
+
+static void
+on_password_answer (password_answer_closure_t *closure,
+ const char *password)
+{
+ closure->handler (closure->data, password, closure->state->boot_server);
+}
+
+static void
+on_ask_for_password (state_t *state,
+ ply_boot_server_password_answer_handler_t answer_handler,
+ void *answer_data)
{
- return ply_boot_splash_ask_for_password (state->boot_splash);
+ password_answer_closure_t *closure;
+
+ closure = malloc (sizeof (password_answer_closure_t));
+ closure->handler = answer_handler;
+ closure->data = answer_data;
+ closure->state = state;
+
+ ply_boot_splash_ask_for_password (state->boot_splash,
+ (ply_boot_splash_password_answer_handler_t)
+ on_password_answer, closure);
}
static void
diff --git a/src/ply-boot-server.c b/src/ply-boot-server.c
index 5752c25..84e4ad2 100644
--- a/src/ply-boot-server.c
+++ b/src/ply-boot-server.c
@@ -181,6 +181,31 @@ ply_boot_connection_is_from_root (ply_boot_connection_t *connection)
}
static void
+ply_boot_connection_on_password_answer (ply_boot_connection_t *connection,
+ const char *password,
+ ply_boot_server_t *server)
+{
+
+ size_t size;
+
+ /* FIXME: support up to 4 billion
+ */
+ if (strlen (password) > 255)
+ ply_error ("password to long to fit in buffer");
+
+ size = (uint8_t) strlen (password);
+
+ if (!ply_write (connection->fd,
+ PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER,
+ strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER)) ||
+ !ply_write (connection->fd,
+ &size, sizeof (uint8_t)) ||
+ !ply_write (connection->fd,
+ password, size))
+ ply_error ("could not write bytes: %m");
+}
+
+static void
ply_boot_connection_on_request (ply_boot_connection_t *connection)
{
ply_boot_server_t *server;
@@ -231,31 +256,13 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
}
else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD) == 0)
{
- char *password;
- uint8_t size;
-
- password = NULL;
-
if (server->ask_for_password_handler != NULL)
- password = server->ask_for_password_handler (server->user_data, server);
-
- /* FIXME: support up to 4 billion
+ server->ask_for_password_handler (server->user_data,
+ ply_boot_connection_on_password_answer,
+ connection,
+ server);
+ /* will reply later
*/
- if (strlen (password) > 255)
- ply_error ("password to long to fit in buffer");
-
- size = (uint8_t) strlen (password);
-
- if (!ply_write (connection->fd,
- PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER,
- strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER)) ||
- !ply_write (connection->fd,
- &size, sizeof (uint8_t)) ||
- !ply_write (connection->fd,
- password, size))
- ply_error ("could not write bytes: %m");
-
- free (password);
return;
}
else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PING) != 0)
diff --git a/src/ply-boot-server.h b/src/ply-boot-server.h
index 7ddab15..dd9f386 100644
--- a/src/ply-boot-server.h
+++ b/src/ply-boot-server.h
@@ -38,7 +38,12 @@ typedef void (* ply_boot_server_update_handler_t) (void *user_data,
typedef void (* ply_boot_server_show_splash_handler_t) (void *user_data,
ply_boot_server_t *server);
-typedef char * (* ply_boot_server_ask_for_password_handler_t) (void *user_data,
+typedef void (* ply_boot_server_password_answer_handler_t) (void *answer_data,
+ const char *password,
+ ply_boot_server_t *server);
+typedef void (* ply_boot_server_ask_for_password_handler_t) (void *user_data,
+ ply_boot_server_password_answer_handler_t on_answer_handler,
+ void *answer_data,
ply_boot_server_t *server);
typedef void (* ply_boot_server_system_initialized_handler_t) (void *user_data,
diff --git a/src/ply-boot-splash-plugin.h b/src/ply-boot-splash-plugin.h
index a93d07f..7f18bb1 100644
--- a/src/ply-boot-splash-plugin.h
+++ b/src/ply-boot-splash-plugin.h
@@ -32,6 +32,8 @@
typedef struct _ply_boot_splash_plugin ply_boot_splash_plugin_t;
+typedef void (* ply_boot_splash_password_answer_handler_t) (void *answer_data, const char *password);
+
typedef struct
{
ply_boot_splash_plugin_t * (* create_plugin) (void);
@@ -50,7 +52,9 @@ typedef struct
ply_event_loop_t *loop,
ply_window_t *window);
- char * (* ask_for_password) (ply_boot_splash_plugin_t *plugin);
+ void (* ask_for_password) (ply_boot_splash_plugin_t *plugin,
+ ply_boot_splash_password_answer_handler_t answer_handler,
+ void *answer_data);
void (* on_keyboard_input) (ply_boot_splash_plugin_t *plugin,
const char *keyboard_input);
diff --git a/src/ply-boot-splash.c b/src/ply-boot-splash.c
index c24ca64..3f51755 100644
--- a/src/ply-boot-splash.c
+++ b/src/ply-boot-splash.c
@@ -226,8 +226,10 @@ ply_boot_splash_update_output (ply_boot_splash_t *splash,
splash->plugin_interface->on_boot_output (splash->plugin, output, size);
}
-char *
-ply_boot_splash_ask_for_password (ply_boot_splash_t *splash)
+void
+ply_boot_splash_ask_for_password (ply_boot_splash_t *splash,
+ ply_boot_splash_password_answer_handler_t *answer_handler,
+ void *answer_data)
{
assert (splash != NULL);
@@ -236,7 +238,8 @@ ply_boot_splash_ask_for_password (ply_boot_splash_t *splash)
assert (splash->plugin_interface->ask_for_password != NULL);
assert (splash->is_shown);
- return splash->plugin_interface->ask_for_password (splash->plugin);
+ splash->plugin_interface->ask_for_password (splash->plugin,
+ answer_handler, answer_data);
}
static void
diff --git a/src/ply-boot-splash.h b/src/ply-boot-splash.h
index fefb359..5c26caf 100644
--- a/src/ply-boot-splash.h
+++ b/src/ply-boot-splash.h
@@ -29,6 +29,7 @@
#include "ply-event-loop.h"
#include "ply-window.h"
#include "ply-buffer.h"
+#include "ply-boot-splash-plugin.h"
typedef struct _ply_boot_splash ply_boot_splash_t;
@@ -44,7 +45,9 @@ void ply_boot_splash_update_output (ply_boot_splash_t *splash,
const char *output,
size_t size);
-char *ply_boot_splash_ask_for_password (ply_boot_splash_t *splash);
+void ply_boot_splash_ask_for_password (ply_boot_splash_t *splash,
+ ply_boot_splash_password_answer_handler_t *answer_handler,
+ void *answer_data);
void ply_boot_splash_hide (ply_boot_splash_t *splash);
void ply_boot_splash_attach_to_event_loop (ply_boot_splash_t *splash,
ply_event_loop_t *loop);
diff --git a/src/splash-plugins/text/text.c b/src/splash-plugins/text/text.c
index d65c0be..a40e945 100644
--- a/src/splash-plugins/text/text.c
+++ b/src/splash-plugins/text/text.c
@@ -38,8 +38,10 @@
#include <termios.h>
#include <unistd.h>
#include <values.h>
+#include <wchar.h>
#include "ply-boot-splash-plugin.h"
+#include "ply-buffer.h"
#include "ply-event-loop.h"
#include "ply-list.h"
#include "ply-logger.h"
@@ -50,11 +52,18 @@
#include <linux/kd.h>
+#define CLEAR_LINE_SEQUENCE "\033[2K"
+
struct _ply_boot_splash_plugin
{
ply_event_loop_t *loop;
int console_fd;
+ ply_boot_splash_password_answer_handler_t password_answer_handler;
+ void *password_answer_data;
+
+ ply_buffer_t *keyboard_input_buffer;
+ uint32_t keyboard_input_is_hidden : 1;
};
ply_boot_splash_plugin_t *
@@ -65,6 +74,7 @@ create_plugin (void)
ply_trace ("creating plugin");
plugin = calloc (1, sizeof (ply_boot_splash_plugin_t));
+ plugin->keyboard_input_buffer = ply_buffer_new ();
plugin->console_fd = -1;
return plugin;
@@ -78,6 +88,8 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin)
if (plugin == NULL)
return;
+ ply_buffer_free (plugin->keyboard_input_buffer);
+
free (plugin);
}
@@ -151,38 +163,50 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin,
}
}
-char *
-ask_for_password (ply_boot_splash_plugin_t *plugin)
+void
+ask_for_password (ply_boot_splash_plugin_t *plugin,
+ ply_boot_splash_password_answer_handler_t answer_handler,
+ void *answer_data)
{
- char answer[1024];
- struct termios initial_term_attributes;
- struct termios noecho_term_attributes;
-
- tcgetattr (STDIN_FILENO, &initial_term_attributes);
- noecho_term_attributes = initial_term_attributes;
- noecho_term_attributes.c_lflag &= ~ECHO;
-
- printf ("Password: ");
-
- if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &noecho_term_attributes) != 0) {
- fprintf (stderr, "Could not set terminal attributes\n");
- return NULL;
- }
-
- fgets (answer, sizeof (answer), stdin);
- answer[strlen (answer) - 1] = '\0';
-
- tcsetattr (STDIN_FILENO, TCSANOW, &initial_term_attributes);
+ plugin->password_answer_handler = answer_handler;
+ plugin->password_answer_data = answer_data;
- printf ("\n");
-
- return strdup (answer);
+ write (STDOUT_FILENO, "\nPassword: ", strlen ("\nPassword: "));
+ plugin->keyboard_input_is_hidden = true;
}
void
on_keyboard_input (ply_boot_splash_plugin_t *plugin,
const char *keyboard_input)
{
+ ssize_t character_size;
+
+ character_size = (ssize_t) mbrlen (keyboard_input, MB_CUR_MAX, NULL);
+
+ if (character_size < 0)
+ return;
+
+ if (plugin->password_answer_handler != NULL)
+ {
+ if (character_size == 1 && keyboard_input[0] == '\r')
+ {
+ plugin->password_answer_handler (plugin->password_answer_data,
+ ply_buffer_get_bytes (plugin->keyboard_input_buffer));
+ plugin->keyboard_input_is_hidden = false;
+ ply_buffer_clear (plugin->keyboard_input_buffer);
+ plugin->password_answer_handler = NULL;
+ write (STDOUT_FILENO, CLEAR_LINE_SEQUENCE, strlen (CLEAR_LINE_SEQUENCE));
+ return;
+ }
+ }
+
+ ply_buffer_append_bytes (plugin->keyboard_input_buffer,
+ keyboard_input, character_size);
+
+ if (plugin->keyboard_input_is_hidden)
+ write (STDOUT_FILENO, "•", strlen ("•"));
+ else
+ write (STDOUT_FILENO, keyboard_input, character_size);
}
ply_boot_splash_plugin_interface_t *