[PATCH] Add support for scrolling boot log messages
Ray Strode
halfline at gmail.com
Tue Mar 4 05:05:54 PST 2014
Hey Pali,
Sorry for the sluggish response. Would you mind putting the patch in
bugzilla? I do appreciate you working on this, and I don't want it to
get lost. I'm hoping to look at the patch soon, I just haven't had an
opportunity to read through it carefully yet.
--Ray
On Sat, Nov 23, 2013 at 1:13 PM, Pali Rohár <pali.rohar at gmail.com> wrote:
> On Wednesday 27 June 2012 21:51:51 Ray Strode wrote:
>> hi,
>>
>> > and current argument is status name (const char *). Command
>> > and argument are passing to function
>> > ply_boot_client_queue_request.
>> >
>> > How to add to this protocol/function operation-id argument?
>>
>> So the code does:
>>
>> request_string = NULL;
>> asprintf (&request_string, "%s\002%c%s", request->command,
>> (char) (strlen (request->argument) + 1),
>> request->argument); *request_size = strlen (request_string) +
>> 1;
>>
>> I guess I would change it to:
>>
>> request_string = NULL;
>> asprintf (&request_string, "%s\002%c%s\035%c%s",
>> request->command, (char) (strlen (request->argument_1) + 1),
>> request->argument_1, (char) (strlen (request->argument_2) +
>> 1), request->argument_2); *request_size = strlen
>> (request_string) + 1;
>>
>> (or so)
>>
>> \035 is just a random control character from "man ascii" that
>> seemed reasonable enough to use
>>
>> --Ray
>
> Hello Ray,
>
> after long time I finished my patch for boot log messages. I added
> register-operation and unregister-operation commands for it as
> you suggested. Here is patch generated by git format-patch:
>
> From a0a797d05208c8a134e5f6cfe185965b5f788755 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali.rohar at gmail.com>
> Date: Sat, 23 Nov 2013 17:39:53 +0100
> Subject: [PATCH] Add support for operation log messages
>
> This patch adding support for operation log messages and updating upstart
> bridge code to use it. This is usefull for verbose log output (e.g daemon
> starting, stopping).
>
> Example:
>
> Register operation ssh:
> $ plymouth register-operation --operation-id=ssh --name='Starting OpenSSH server ssh'
>
> Set state of operation ssh to wait:
> $ plymouth update --operation-id=ssh --status="wait"
> Details plugin will show: 'Starting OpenSSH server ssh... [wait]'
>
> Set state of operation ssh to done:
> $ plymouth update --operation-id=ssh --status="done"
> Details plugin will show: 'Starting OpenSSH server ssh... [done]'
>
> Unregister operation ssh:
> $ plymouth unregister-operation --operation-id=ssh
> ---
> src/client/ply-boot-client.c | 126 ++++++++++----
> src/client/ply-boot-client.h | 13 ++
> src/client/plymouth.c | 99 ++++++++++-
> src/libply-splash-core/ply-boot-splash-plugin.h | 9 +-
> src/libply-splash-core/ply-boot-splash.c | 32 +++-
> src/libply-splash-core/ply-boot-splash.h | 8 +-
> src/libply/ply-progress.c | 40 +++--
> src/libply/ply-progress.h | 2 +-
> src/main.c | 35 +++-
> src/plugins/splash/details/plugin.c | 146 +++++++++++++++-
> src/plugins/splash/fade-throbber/plugin.c | 3 +-
> src/plugins/splash/script/plugin.c | 28 +++-
> src/plugins/splash/script/script-lib-plymouth.c | 54 +++++-
> src/plugins/splash/script/script-lib-plymouth.h | 12 +-
> src/plugins/splash/space-flares/plugin.c | 3 +-
> src/plugins/splash/text/plugin.c | 3 +-
> src/plugins/splash/throbgress/plugin.c | 3 +-
> src/plugins/splash/two-step/plugin.c | 3 +-
> src/ply-boot-protocol.h | 2 +
> src/ply-boot-server.c | 144 ++++++++++++----
> src/ply-boot-server.h | 14 +-
> src/upstart-bridge/ply-upstart-monitor.c | 2 +-
> src/upstart-bridge/plymouth-upstart-bridge.c | 205 +++++++----------------
> 23 files changed, 739 insertions(+), 247 deletions(-)
>
> diff --git a/src/client/ply-boot-client.c b/src/client/ply-boot-client.c
> index 56458ce..a3425df 100644
> --- a/src/client/ply-boot-client.c
> +++ b/src/client/ply-boot-client.c
> @@ -1,6 +1,7 @@
> /* ply-boot-client.h - APIs for talking to the boot status daemon
> *
> * Copyright (C) 2007 Red Hat, Inc.
> + * Copyright (C) 2012 Pali Rohár <pali.rohar at gmail.com>
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> @@ -55,7 +56,8 @@ typedef struct
> {
> ply_boot_client_t *client;
> char *command;
> - char *argument;
> + char *argument_1;
> + char *argument_2;
> ply_boot_client_response_handler_t handler;
> ply_boot_client_response_handler_t failed_handler;
> void *user_data;
> @@ -208,7 +210,8 @@ ply_boot_client_connect (ply_boot_client_t *client,
> static ply_boot_client_request_t *
> ply_boot_client_request_new (ply_boot_client_t *client,
> const char *request_command,
> - const char *request_argument,
> + const char *request_argument_1,
> + const char *request_argument_2,
> ply_boot_client_response_handler_t handler,
> ply_boot_client_response_handler_t failed_handler,
> void *user_data)
> @@ -221,8 +224,10 @@ ply_boot_client_request_new (ply_boot_client_t *client,
> request = calloc (1, sizeof (ply_boot_client_request_t));
> request->client = client;
> request->command = strdup (request_command);
> - if (request_argument != NULL)
> - request->argument = strdup (request_argument);
> + if (request_argument_1 != NULL)
> + request->argument_1 = strdup (request_argument_1);
> + if (request_argument_2 != NULL)
> + request->argument_2 = strdup (request_argument_2);
> request->handler = handler;
> request->failed_handler = failed_handler;
> request->user_data = user_data;
> @@ -236,8 +241,8 @@ ply_boot_client_request_free (ply_boot_client_request_t *request)
> if (request == NULL)
> return;
> free (request->command);
> - if (request->argument != NULL)
> - free (request->argument);
> + free (request->argument_1);
> + free (request->argument_2);
> free (request);
> }
>
> @@ -389,6 +394,7 @@ ply_boot_client_get_request_string (ply_boot_client_t *client,
> size_t *request_size)
> {
> char *request_string;
> + int ret;
>
> assert (client != NULL);
> assert (request != NULL);
> @@ -396,19 +402,37 @@ ply_boot_client_get_request_string (ply_boot_client_t *client,
>
> assert (request->command != NULL);
>
> - if (request->argument == NULL)
> + if (request->argument_1 == NULL && request->argument_2 == NULL)
> {
> request_string = strdup (request->command);
> *request_size = strlen (request_string) + 1;
> return request_string;
> }
>
> - assert (strlen (request->argument) <= UCHAR_MAX);
> + assert (strlen (request->argument_1) <= UCHAR_MAX);
>
> request_string = NULL;
> - asprintf (&request_string, "%s\002%c%s", request->command,
> - (char) (strlen (request->argument) + 1), request->argument);
> - *request_size = strlen (request_string) + 1;
> +
> + if (request->argument_2 == NULL)
> + {
> + ret = asprintf (&request_string, "%s\002%c%s", request->command,
> + (char) (strlen (request->argument_1) + 1), request->argument_1);
> + }
> + else
> + {
> + assert (request->argument_1 != NULL);
> + assert (strlen (request->argument_2) <= UCHAR_MAX);
> + ret = asprintf (&request_string, "%s\003%c%s%c%c%s", request->command,
> + (char) (strlen (request->argument_1) + 1),
> + request->argument_1,
> + 0,
> + (char) (strlen (request->argument_2) + 1),
> + request->argument_2);
> + }
> +
> + assert (ret > 0);
> +
> + *request_size = (size_t)ret + 1;
>
> return request_string;
> }
> @@ -482,7 +506,8 @@ ply_boot_client_process_pending_requests (ply_boot_client_t *client)
> static void
> ply_boot_client_queue_request (ply_boot_client_t *client,
> const char *request_command,
> - const char *request_argument,
> + const char *request_argument_1,
> + const char *request_argument_2,
> ply_boot_client_response_handler_t handler,
> ply_boot_client_response_handler_t failed_handler,
> void *user_data)
> @@ -490,7 +515,8 @@ ply_boot_client_queue_request (ply_boot_client_t *client,
> assert (client != NULL);
> assert (client->loop != NULL);
> assert (request_command != NULL);
> - assert (request_argument == NULL || strlen (request_argument) <= UCHAR_MAX);
> + assert (request_argument_1 == NULL || strlen (request_argument_1) <= UCHAR_MAX);
> + assert (request_argument_2 == NULL || strlen (request_argument_2) <= UCHAR_MAX);
>
> if (client->daemon_can_take_request_watch == NULL &&
> client->socket_fd >= 0)
> @@ -516,7 +542,8 @@ ply_boot_client_queue_request (ply_boot_client_t *client,
> ply_boot_client_request_t *request;
>
> request = ply_boot_client_request_new (client, request_command,
> - request_argument,
> + request_argument_1,
> + request_argument_2,
> handler, failed_handler, user_data);
> ply_list_append_data (client->requests_to_send, request);
> }
> @@ -531,12 +558,39 @@ ply_boot_client_ping_daemon (ply_boot_client_t *client,
> assert (client != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PING,
> - NULL, handler, failed_handler, user_data);
> + NULL, NULL, handler, failed_handler, user_data);
> +}
> +
> +void ply_boot_client_register_operation (ply_boot_client_t *client,
> + const char *operation_id,
> + const char *name,
> + ply_boot_client_response_handler_t handler,
> + ply_boot_client_response_handler_t failed_handler,
> + void *user_data)
> +{
> + assert (client != NULL);
> +
> + ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_REGISTER,
> + operation_id, name, handler, failed_handler, user_data);
> +
> +
> +}
> +void ply_boot_client_unregister_operation (ply_boot_client_t *client,
> + const char *operation_id,
> + ply_boot_client_response_handler_t handler,
> + ply_boot_client_response_handler_t failed_handler,
> + void *user_data)
> +{
> + assert (client != NULL);
> +
> + ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_UNREGISTER,
> + operation_id, NULL, handler, failed_handler, user_data);
> }
>
> void
> ply_boot_client_update_daemon (ply_boot_client_t *client,
> const char *status,
> + const char *operation_id,
> ply_boot_client_response_handler_t handler,
> ply_boot_client_response_handler_t failed_handler,
> void *user_data)
> @@ -544,7 +598,7 @@ ply_boot_client_update_daemon (ply_boot_client_t *client,
> assert (client != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_UPDATE,
> - status, handler, failed_handler, user_data);
> + status, operation_id, handler, failed_handler, user_data);
> }
>
> void
> @@ -557,7 +611,7 @@ ply_boot_client_change_mode (ply_boot_client_t *client,
> assert (client != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_CHANGE_MODE,
> - new_mode, handler, failed_handler, user_data);
> + new_mode, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -570,7 +624,7 @@ ply_boot_client_system_update (ply_boot_client_t *client,
> assert (client != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_SYSTEM_UPDATE,
> - progress, handler, failed_handler, user_data);
> + progress, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -584,7 +638,7 @@ ply_boot_client_tell_daemon_to_change_root (ply_boot_client_t *
> assert (root_dir != NULL);
>
> ply_boot_client_queue_request(client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_NEWROOT,
> - root_dir, handler, failed_handler, user_data);
> + root_dir, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -598,7 +652,7 @@ ply_boot_client_tell_daemon_to_display_message (ply_boot_client_t
> assert (message != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_SHOW_MESSAGE,
> - message, handler, failed_handler, user_data);
> + message, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -612,7 +666,7 @@ ply_boot_client_tell_daemon_to_hide_message (ply_boot_client_t
> assert (message != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_HIDE_MESSAGE,
> - message, handler, failed_handler, user_data);
> + message, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -625,7 +679,7 @@ ply_boot_client_tell_daemon_system_is_initialized (ply_boot_client_t
>
> ply_boot_client_queue_request (client,
> PLY_BOOT_PROTOCOL_REQUEST_TYPE_SYSTEM_INITIALIZED,
> - NULL, handler, failed_handler, user_data);
> + NULL, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -639,7 +693,7 @@ ply_boot_client_ask_daemon_for_password (ply_boot_client_t *cli
> assert (client != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD,
> - prompt, (ply_boot_client_response_handler_t)
> + prompt, NULL, (ply_boot_client_response_handler_t)
> handler, failed_handler, user_data);
> }
>
> @@ -652,7 +706,7 @@ ply_boot_client_ask_daemon_for_cached_passwords (ply_boot_client_t
> assert (client != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_CACHED_PASSWORD,
> - NULL, (ply_boot_client_response_handler_t)
> + NULL, NULL, (ply_boot_client_response_handler_t)
> handler, failed_handler, user_data);
> }
>
> @@ -666,7 +720,7 @@ ply_boot_client_ask_daemon_question (ply_boot_client_t *c
> assert (client != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUESTION,
> - prompt, (ply_boot_client_response_handler_t)
> + prompt, NULL, (ply_boot_client_response_handler_t)
> handler, failed_handler, user_data);
> }
>
> @@ -680,7 +734,7 @@ ply_boot_client_ask_daemon_to_watch_for_keystroke (ply_boot_client_t *
> assert (client != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE,
> - keys, (ply_boot_client_response_handler_t)
> + keys, NULL, (ply_boot_client_response_handler_t)
> handler, failed_handler, user_data);
> }
>
> @@ -694,7 +748,7 @@ ply_boot_client_ask_daemon_to_ignore_keystroke (ply_boot_client_t
> assert (client != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE_REMOVE,
> - keys, (ply_boot_client_response_handler_t)
> + keys, NULL, (ply_boot_client_response_handler_t)
> handler, failed_handler, user_data);
> }
>
> @@ -707,7 +761,7 @@ ply_boot_client_tell_daemon_to_show_splash (ply_boot_client_t *
> assert (client != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_SHOW_SPLASH,
> - NULL, handler, failed_handler, user_data);
> + NULL, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -719,7 +773,7 @@ ply_boot_client_tell_daemon_to_hide_splash (ply_boot_client_t *
> assert (client != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_HIDE_SPLASH,
> - NULL, handler, failed_handler, user_data);
> + NULL, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -731,7 +785,7 @@ ply_boot_client_tell_daemon_to_deactivate (ply_boot_client_t *c
> assert (client != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_DEACTIVATE,
> - NULL, handler, failed_handler, user_data);
> + NULL, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -743,7 +797,7 @@ ply_boot_client_tell_daemon_to_reactivate (ply_boot_client_t *c
> assert (client != NULL);
>
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_REACTIVATE,
> - NULL, handler, failed_handler, user_data);
> + NULL, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -759,7 +813,7 @@ ply_boot_client_tell_daemon_to_quit (ply_boot_client_t *client,
>
> arg[0] = (char) (retain_splash != false);
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUIT,
> - arg, handler, failed_handler, user_data);
> + arg, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -769,7 +823,7 @@ ply_boot_client_tell_daemon_to_progress_pause (ply_boot_client_t
> void *user_data)
> {
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PROGRESS_PAUSE,
> - NULL, handler, failed_handler, user_data);
> + NULL, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -779,7 +833,7 @@ ply_boot_client_tell_daemon_to_progress_unpause (ply_boot_client_t
> void *user_data)
> {
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PROGRESS_UNPAUSE,
> - NULL, handler, failed_handler, user_data);
> + NULL, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -789,7 +843,7 @@ ply_boot_client_ask_daemon_has_active_vt (ply_boot_client_t *cl
> void *user_data)
> {
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_HAS_ACTIVE_VT,
> - NULL, handler, failed_handler, user_data);
> + NULL, NULL, handler, failed_handler, user_data);
> }
>
> void
> @@ -799,7 +853,7 @@ ply_boot_client_tell_daemon_about_error (ply_boot_client_t *cli
> void *user_data)
> {
> ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_ERROR,
> - NULL, handler, failed_handler, user_data);
> + NULL, NULL, handler, failed_handler, user_data);
> }
>
> void
> diff --git a/src/client/ply-boot-client.h b/src/client/ply-boot-client.h
> index 24939f7..8154a5c 100644
> --- a/src/client/ply-boot-client.h
> +++ b/src/client/ply-boot-client.h
> @@ -1,6 +1,7 @@
> /* ply-boot-client.h - APIs for talking to the boot status daemon
> *
> * Copyright (C) 2007 Red Hat, Inc.
> + * Copyright (C) 2012 Pali Rohár <pali.rohar at gmail.com>
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> @@ -53,8 +54,20 @@ void ply_boot_client_ping_daemon (ply_boot_client_t *client,
> ply_boot_client_response_handler_t handler,
> ply_boot_client_response_handler_t failed_handler,
> void *user_data);
> +void ply_boot_client_register_operation (ply_boot_client_t *client,
> + const char *operation_id,
> + const char *name,
> + ply_boot_client_response_handler_t handler,
> + ply_boot_client_response_handler_t failed_handler,
> + void *user_data);
> +void ply_boot_client_unregister_operation (ply_boot_client_t *client,
> + const char *operation_id,
> + ply_boot_client_response_handler_t handler,
> + ply_boot_client_response_handler_t failed_handler,
> + void *user_data);
> void ply_boot_client_update_daemon (ply_boot_client_t *client,
> const char *new_status,
> + const char *operation_id,
> ply_boot_client_response_handler_t handler,
> ply_boot_client_response_handler_t failed_handler,
> void *user_data);
> diff --git a/src/client/plymouth.c b/src/client/plymouth.c
> index e00208d..d103025 100644
> --- a/src/client/plymouth.c
> +++ b/src/client/plymouth.c
> @@ -1,6 +1,7 @@
> /* plymouth.c - updates boot status
> *
> * Copyright (C) 2007 Red Hat, Inc
> + * Copyright (C) 2012 Pali Rohár <pali.rohar at gmail.com>
> *
> * This file is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published
> @@ -841,10 +842,72 @@ on_hide_splash_request (state_t *state,
> }
>
> static void
> +on_register_operation_request (state_t *state,
> + const char *command)
> +{
> + char *operation_id;
> + char *name;
> +
> + operation_id = NULL;
> + ply_command_parser_get_command_options (state->command_parser,
> + command,
> + "operation-id", &operation_id,
> + NULL);
> +
> + name = NULL;
> + ply_command_parser_get_command_options (state->command_parser,
> + command,
> + "name", &name,
> + NULL);
> +
> + if (operation_id != NULL && name != NULL)
> + {
> + ply_boot_client_register_operation(state->client, operation_id, name,
> + (ply_boot_client_response_handler_t)
> + on_success,
> + (ply_boot_client_response_handler_t)
> + on_failure, state);
> + }
> + else
> + {
> + ply_error ("unknown operation id or name");
> + ply_event_loop_exit (state->loop, 1);
> + }
> +}
> +
> +static void
> +on_unregister_operation_request (state_t *state,
> + const char *command)
> +{
> + char *operation_id;
> +
> + operation_id = NULL;
> + ply_command_parser_get_command_options (state->command_parser,
> + command,
> + "operation-id", &operation_id,
> + NULL);
> +
> + if (operation_id != NULL)
> + {
> + ply_boot_client_unregister_operation(state->client, operation_id,
> + (ply_boot_client_response_handler_t)
> + on_success,
> + (ply_boot_client_response_handler_t)
> + on_failure, state);
> + }
> + else
> + {
> + ply_error ("unknown operation id");
> + ply_event_loop_exit (state->loop, 1);
> + }
> +}
> +
> +static void
> on_update_request (state_t *state,
> const char *command)
> {
> char *status;
> + const char *operation_id;
>
> status = NULL;
> ply_command_parser_get_command_options (state->command_parser,
> @@ -852,9 +915,19 @@ on_update_request (state_t *state,
> "status", &status,
> NULL);
>
> + operation_id = NULL;
> + ply_command_parser_get_command_options (state->command_parser,
> + command,
> + "operation-id", &operation_id,
> + NULL);
> +
> + if (operation_id == NULL)
> + operation_id = "";
> +
> if (status != NULL)
> {
> - ply_boot_client_update_daemon (state->client, status,
> +
> + ply_boot_client_update_daemon (state->client, status, operation_id,
> (ply_boot_client_response_handler_t)
> on_success,
> (ply_boot_client_response_handler_t)
> @@ -974,6 +1047,8 @@ main (int argc,
> "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,
> + "register-operation", "Tell boot daemon to register operation", PLY_COMMAND_OPTION_TYPE_STRING,
> + "unregister-operation", "Tell boot daemon to unregister operation", 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,
> @@ -1000,9 +1075,29 @@ main (int argc,
> NULL);
>
> ply_command_parser_add_command (state.command_parser,
> + "register-operation", "Tell boot daemon to register operation",
> + (ply_command_handler_t)
> + on_register_operation_request, &state,
> + "operation-id", "Operation id",
> + PLY_COMMAND_OPTION_TYPE_STRING,
> + "name", "Operation name",
> + PLY_COMMAND_OPTION_TYPE_STRING,
> + NULL);
> +
> + ply_command_parser_add_command (state.command_parser,
> + "unregister-operation", "Tell boot daemon to unregister operation",
> + (ply_command_handler_t)
> + on_unregister_operation_request, &state,
> + "operation-id", "Operation id",
> + PLY_COMMAND_OPTION_TYPE_STRING,
> + NULL);
> +
> + ply_command_parser_add_command (state.command_parser,
> "update", "Tell daemon about boot status changes",
> (ply_command_handler_t)
> on_update_request, &state,
> + "operation-id", "Tell daemon operation id",
> + PLY_COMMAND_OPTION_TYPE_STRING,
> "status", "Tell daemon the current boot status",
> PLY_COMMAND_OPTION_TYPE_STRING,
> NULL);
> @@ -1245,7 +1340,7 @@ main (int argc,
> (ply_boot_client_response_handler_t)
> on_failure, &state);
> else if (status != NULL)
> - ply_boot_client_update_daemon (state.client, status,
> + ply_boot_client_update_daemon (state.client, status, NULL,
> (ply_boot_client_response_handler_t)
> on_success,
> (ply_boot_client_response_handler_t)
> diff --git a/src/libply-splash-core/ply-boot-splash-plugin.h b/src/libply-splash-core/ply-boot-splash-plugin.h
> index 2d73d66..c44a9a2 100644
> --- a/src/libply-splash-core/ply-boot-splash-plugin.h
> +++ b/src/libply-splash-core/ply-boot-splash-plugin.h
> @@ -1,6 +1,7 @@
> /* ply-boot-splash-plugin.h - plugin interface for ply_boot_splash_t
> *
> * Copyright (C) 2007 Red Hat, Inc.
> + * Copyright (C) 2012 Pali Rohár <pali.rohar at gmail.com>
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> @@ -67,8 +68,14 @@ typedef struct
> ply_boot_splash_mode_t mode);
> void (* system_update) (ply_boot_splash_plugin_t *plugin,
> int progress);
> + void (* register_operation) (ply_boot_splash_plugin_t *plugin,
> + const char *operation_id,
> + const char *name);
> + void (* unregister_operation) (ply_boot_splash_plugin_t *plugin,
> + const char *operation_id);
> void (* update_status) (ply_boot_splash_plugin_t *plugin,
> - const char *status);
> + const char *status,
> + const char *operation_id);
> void (* on_boot_output) (ply_boot_splash_plugin_t *plugin,
> const char *output,
> size_t size);
> diff --git a/src/libply-splash-core/ply-boot-splash.c b/src/libply-splash-core/ply-boot-splash.c
> index 93d9345..7c1fb24 100644
> --- a/src/libply-splash-core/ply-boot-splash.c
> +++ b/src/libply-splash-core/ply-boot-splash.c
> @@ -1,6 +1,7 @@
> /* ply-boot-splash.h - APIs for putting up a splash screen
> *
> * Copyright (C) 2007 Red Hat, Inc.
> + * Copyright (C) 2012 Pali Rohár <pali.rohar at gmail.com>
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> @@ -623,9 +624,36 @@ ply_boot_splash_system_update (ply_boot_splash_t *splash,
> return true;
> }
>
> +void ply_boot_splash_register_operation (ply_boot_splash_t *splash,
> + const char *operation_id,
> + const char *name)
> +{
> + assert (splash != NULL);
> + assert (operation_id != NULL);
> + assert (name != NULL);
> + assert (splash->plugin_interface != NULL);
> + assert (splash->plugin != NULL);
> + assert (splash->plugin_interface->register_operation != NULL);
> +
> + splash->plugin_interface->register_operation (splash->plugin, operation_id, name);
> +}
> +
> +void ply_boot_splash_unregister_operation (ply_boot_splash_t *splash,
> + const char *operation_id)
> +{
> + assert (splash != NULL);
> + assert (operation_id != NULL);
> + assert (splash->plugin_interface != NULL);
> + assert (splash->plugin != NULL);
> + assert (splash->plugin_interface->register_operation != NULL);
> +
> + splash->plugin_interface->unregister_operation (splash->plugin, operation_id);
> +}
> +
> void
> ply_boot_splash_update_status (ply_boot_splash_t *splash,
> - const char *status)
> + const char *status,
> + const char *operation_id)
> {
> assert (splash != NULL);
> assert (status != NULL);
> @@ -634,7 +662,7 @@ ply_boot_splash_update_status (ply_boot_splash_t *splash,
> assert (splash->plugin_interface->update_status != NULL);
> assert (splash->mode != PLY_BOOT_SPLASH_MODE_INVALID);
>
> - splash->plugin_interface->update_status (splash->plugin, status);
> + splash->plugin_interface->update_status (splash->plugin, status, operation_id);
> }
>
> void
> diff --git a/src/libply-splash-core/ply-boot-splash.h b/src/libply-splash-core/ply-boot-splash.h
> index a79e939..af67a0e 100644
> --- a/src/libply-splash-core/ply-boot-splash.h
> +++ b/src/libply-splash-core/ply-boot-splash.h
> @@ -64,8 +64,14 @@ bool ply_boot_splash_show (ply_boot_splash_t *splash,
> ply_boot_splash_mode_t mode);
> bool ply_boot_splash_system_update (ply_boot_splash_t *splash,
> int progress);
> +void ply_boot_splash_register_operation (ply_boot_splash_t *splash,
> + const char *operation_id,
> + const char *name);
> +void ply_boot_splash_unregister_operation (ply_boot_splash_t *splash,
> + const char *operation_id);
> void ply_boot_splash_update_status (ply_boot_splash_t *splash,
> - const char *status);
> + const char *status,
> + const char *operation_id);
> void ply_boot_splash_update_output (ply_boot_splash_t *splash,
> const char *output,
> size_t size);
> diff --git a/src/libply/ply-progress.c b/src/libply/ply-progress.c
> index cf372cd..0fa5a52 100644
> --- a/src/libply/ply-progress.c
> +++ b/src/libply/ply-progress.c
> @@ -1,6 +1,7 @@
> /* ply-progress.c - calculats boot progress
> *
> * Copyright (C) 2007 Red Hat, Inc.
> + * Copyright (C) 2012 Pali Rohár <pali.rohar at gmail.com>
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> @@ -68,6 +69,7 @@ struct _ply_progress
> typedef struct
> {
> double time;
> + char* id;
> char* string;
> uint32_t disabled : 1;
> } ply_progress_message_t;
> @@ -103,6 +105,7 @@ ply_progress_free (ply_progress_t* progress)
> ply_progress_message_t *message = ply_list_node_get_data (node);
> next_node = ply_list_get_next_node (progress->current_message_list, node);
>
> + free (message->id);
> free (message->string);
> free (message);
> node = next_node;
> @@ -117,6 +120,7 @@ ply_progress_free (ply_progress_t* progress)
> ply_progress_message_t *message = ply_list_node_get_data (node);
> next_node = ply_list_get_next_node (progress->previous_message_list, node);
>
> + free (message->id);
> free (message->string);
> free (message);
> node = next_node;
> @@ -128,7 +132,7 @@ ply_progress_free (ply_progress_t* progress)
>
>
> static ply_progress_message_t*
> -ply_progress_message_search (ply_list_t *message_list, const char* string)
> +ply_progress_message_search (ply_list_t *message_list, const char* id, const char* string)
> {
> ply_list_node_t *node;
> node = ply_list_get_first_node (message_list);
> @@ -136,7 +140,7 @@ ply_progress_message_search (ply_list_t *message_list, const char* string)
> while (node)
> {
> ply_progress_message_t *message = ply_list_node_get_data (node);
> - if (strcmp(string, message->string)==0)
> + if (strcmp(id, message->id)==0 && strcmp(string, message->string)==0)
> return message;
> node = ply_list_get_next_node (message_list, node);
> }
> @@ -145,7 +149,7 @@ ply_progress_message_search (ply_list_t *message_list, const char* string)
>
>
> static ply_progress_message_t*
> -ply_progress_message_search_next (ply_list_t *message_list, double time)
> +ply_progress_message_search_next (ply_list_t *message_list, const char* id, double time)
> {
> ply_list_node_t *node;
> node = ply_list_get_first_node (message_list);
> @@ -153,7 +157,7 @@ ply_progress_message_search_next (ply_list_t *message_list, double time)
> while (node)
> {
> ply_progress_message_t *message = ply_list_node_get_data (node);
> - if (message->time > time && (!best || message->time < best->time))
> + if (strcmp(id, message->id)==0 && message->time > time && (!best || message->time < best->time))
> best = message;
> node = ply_list_get_next_node (message_list, node);
> }
> @@ -175,6 +179,8 @@ ply_progress_load_cache (ply_progress_t* progress,
> int items_matched;
> double time;
> int string_size=81;
> + char *ptr;
> + char *id;
> char *string;
> char colon;
> int i=0;
> @@ -200,8 +206,20 @@ ply_progress_load_cache (ply_progress_t* progress,
> }
> i++;
> }
> +
> + ptr = strchr(string, ':');
> + if (!ptr)
> + id = strdup("");
> + else
> + {
> + *ptr = 0;
> + id = string;
> + string = strdup(ptr+1);
> + }
> +
> ply_progress_message_t* message = malloc(sizeof(ply_progress_message_t));
> message->time = time;
> + message->id = id;
> message->string = string;
> ply_list_append_data(progress->previous_message_list, message);
> }
> @@ -227,7 +245,7 @@ ply_progress_save_cache (ply_progress_t* progress,
> ply_progress_message_t *message = ply_list_node_get_data (node);
> double percentage = message->time / cur_time;
> if (!message->disabled)
> - fprintf (fp, "%.3lf:%s\n", percentage, message->string);
> + fprintf (fp, "%.3lf:%s:%s\n", percentage, message->id, message->string);
> node = ply_list_get_next_node (progress->current_message_list, node);
> }
> fclose (fp);
> @@ -300,20 +318,21 @@ ply_progress_unpause (ply_progress_t* progress)
>
> void
> ply_progress_status_update (ply_progress_t* progress,
> - const char *status)
> + const char *status,
> + const char *operation_id)
> {
> ply_progress_message_t *message, *message_next;
> - message = ply_progress_message_search(progress->current_message_list, status);
> + message = ply_progress_message_search(progress->current_message_list, operation_id, status);
> if (message)
> {
> message->disabled = true;
> } /* Remove duplicates as they confuse things*/
> else
> {
> - message = ply_progress_message_search(progress->previous_message_list, status);
> + message = ply_progress_message_search(progress->previous_message_list, operation_id, status);
> if (message)
> {
> - message_next = ply_progress_message_search_next(progress->previous_message_list, message->time);
> + message_next = ply_progress_message_search_next(progress->previous_message_list, operation_id, message->time);
> if (message_next)
> progress->next_message_percentage = message_next->time;
> else
> @@ -324,6 +343,7 @@ ply_progress_status_update (ply_progress_t* progress,
> }
> message = malloc(sizeof(ply_progress_message_t));
> message->time = ply_progress_get_time (progress);
> + message->id = strdup(operation_id);
> message->string = strdup(status);
> message->disabled = false;
> ply_list_append_data(progress->current_message_list, message);
> @@ -366,7 +386,7 @@ main (int argc,
>
> for (i=0; i<10; i++)
> {
> - ply_progress_status_update (progress, strings[i]);
> + ply_progress_status_update (progress, strings[i], NULL);
> usleep ((rand () % slowness+slowness));
> percent = ply_progress_get_percentage (progress);
> time = ply_progress_get_time (progress);
> diff --git a/src/libply/ply-progress.h b/src/libply/ply-progress.h
> index 434636a..54bb7b9 100644
> --- a/src/libply/ply-progress.h
> +++ b/src/libply/ply-progress.h
> @@ -36,7 +36,7 @@ double ply_progress_get_time (ply_progress_t* progress);
> void ply_progress_pause (ply_progress_t* progress);
> void ply_progress_unpause (ply_progress_t* progress);
> void ply_progress_save_cache (ply_progress_t* progress, const char *filename);
> -void ply_progress_status_update (ply_progress_t* progress, const char *status);
> +void ply_progress_status_update (ply_progress_t* progress, const char *status, const char *operation_id);
>
> #endif /* PLY_PROGRESS_H */
> /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
> diff --git a/src/main.c b/src/main.c
> index 9c450c0..baef2db 100644
> --- a/src/main.c
> +++ b/src/main.c
> @@ -1,6 +1,7 @@
> /* main.c - boot messages monitor
> *
> * Copyright (C) 2007 Red Hat, Inc
> + * Copyright (C) 2012 Pali Rohár <pali.rohar at gmail.com>
> *
> * This file is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published
> @@ -174,15 +175,37 @@ on_session_hangup (state_t *state)
> }
>
> static void
> +on_register (state_t *state,
> + const char *operation_id,
> + const char *name)
> +{
> + ply_trace ("register operation '%s' with name '%s'", operation_id, name);
> + if (state->boot_splash != NULL)
> + ply_boot_splash_register_operation (state->boot_splash,
> + operation_id, name);
> +}
> +
> +static void
> +on_unregister (state_t *state,
> + const char *operation_id)
> +{
> + ply_trace ("register operation '%s'", operation_id);
> + if (state->boot_splash != NULL)
> + ply_boot_splash_unregister_operation (state->boot_splash,
> + operation_id);
> +}
> +
> +static void
> on_update (state_t *state,
> - const char *status)
> + const char *status,
> + const char *operation_id)
> {
> - ply_trace ("updating status to '%s'", status);
> + ply_trace ("updating status of operation '%s' to '%s'", operation_id, status);
> ply_progress_status_update (state->progress,
> - status);
> + status, operation_id);
> if (state->boot_splash != NULL)
> ply_boot_splash_update_status (state->boot_splash,
> - status);
> + status, operation_id);
> }
>
> static void
> @@ -1297,7 +1320,9 @@ start_boot_server (state_t *state)
> {
> ply_boot_server_t *server;
>
> - server = ply_boot_server_new ((ply_boot_server_update_handler_t) on_update,
> + server = ply_boot_server_new ((ply_boot_server_register_handler_t) on_register,
> + (ply_boot_server_unregister_handler_t) on_unregister,
> + (ply_boot_server_update_handler_t) on_update,
> (ply_boot_server_change_mode_handler_t) on_change_mode,
> (ply_boot_server_system_update_handler_t) on_system_update,
> (ply_boot_server_ask_for_password_handler_t) on_ask_for_password,
> diff --git a/src/plugins/splash/details/plugin.c b/src/plugins/splash/details/plugin.c
> index aff2f1c..ef62ffe 100644
> --- a/src/plugins/splash/details/plugin.c
> +++ b/src/plugins/splash/details/plugin.c
> @@ -1,6 +1,7 @@
> /* details.c - boot splash plugin
> *
> * Copyright (C) 2008 Red Hat, Inc.
> + * Copyright (C) 2012 Pali Rohár <pali.rohar at gmail.com>
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> @@ -66,6 +67,12 @@ typedef struct
> ply_text_display_t *display;
> } view_t;
>
> +typedef struct
> +{
> + char *operation_id;
> + char *name;
> +} operation_t;
> +
> ply_boot_splash_plugin_interface_t *ply_boot_splash_plugin_get_interface (void);
> static void detach_from_event_loop (ply_boot_splash_plugin_t *plugin);
>
> @@ -76,7 +83,7 @@ struct _ply_boot_splash_plugin
> ply_list_t *views;
> ply_boot_splash_display_type_t state;
> ply_list_t *messages;
> -
> + ply_list_t *operations;
> };
>
> static view_t *
> @@ -148,6 +155,75 @@ free_messages (ply_boot_splash_plugin_t *plugin)
> plugin->messages = NULL;
> }
>
> +static operation_t *
> +operation_new (ply_boot_splash_plugin_t *plugin,
> + const char *operation_id,
> + const char *name)
> +{
> + operation_t *operation;
> + operation = malloc (sizeof(operation_t));
> + operation->operation_id = strdup (operation_id);
> + operation->name = strdup (name);
> + return operation;
> +}
> +
> +static void
> +operation_free (operation_t *operation)
> +{
> + free (operation->operation_id);
> + free (operation->name);
> + free (operation);
> +}
> +
> +static void
> +free_operations (ply_boot_splash_plugin_t *plugin)
> +{
> + ply_list_node_t *node;
> +
> + node = ply_list_get_first_node (plugin->operations);
> +
> + while (node != NULL)
> + {
> + ply_list_node_t *next_node;
> + operation_t *operation;
> +
> + operation = ply_list_node_get_data (node);
> + next_node = ply_list_get_next_node (plugin->operations, node);
> +
> + operation_free (operation);
> + ply_list_remove_node (plugin->operations, node);
> +
> + node = next_node;
> + }
> +
> + ply_list_free (plugin->operations);
> + plugin->operations = NULL;
> +}
> +
> +static const char *
> +get_operation_name (ply_boot_splash_plugin_t *plugin, const char *id)
> +{
> + ply_list_node_t *node;
> +
> + node = ply_list_get_first_node (plugin->operations);
> +
> + while (node != NULL)
> + {
> + operation_t *operation;
> +
> + operation = ply_list_node_get_data (node);
> + if (strcmp(operation->operation_id, id) == 0)
> + {
> + return operation->name;
> + }
> +
> + node = ply_list_get_next_node (plugin->operations, node);
> +
> + }
> +
> + return NULL;
> +}
> +
> static ply_boot_splash_plugin_t *
> create_plugin (ply_key_file_t *key_file)
> {
> @@ -158,6 +234,7 @@ create_plugin (ply_key_file_t *key_file)
> plugin = calloc (1, sizeof (ply_boot_splash_plugin_t));
> plugin->views = ply_list_new ();
> plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL;
> + plugin->operations = ply_list_new ();
> plugin->messages = ply_list_new ();
> return plugin;
> }
> @@ -178,6 +255,7 @@ destroy_plugin (ply_boot_splash_plugin_t *plugin)
> detach_from_event_loop (plugin);
> }
>
> + free_operations (plugin);
> free_messages (plugin);
> free_views (plugin);
>
> @@ -299,12 +377,74 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
> }
>
> static void
> +register_operation (ply_boot_splash_plugin_t *plugin,
> + const char *operation_id,
> + const char *name)
> +{
> + operation_t *operation;
> + assert (plugin != NULL);
> + assert (operation_id != NULL);
> + assert (name != NULL);
> +
> + ply_trace ("register operation");
> +
> + operation = operation_new (plugin, operation_id, name);
> + ply_list_append_data (plugin->operations, operation);
> +}
> +
> +static void
> +unregister_operation (ply_boot_splash_plugin_t *plugin,
> + const char *operation_id)
> +{
> + assert (plugin != NULL);
> + assert (operation_id != NULL);
> +
> + ply_trace ("unregister operation");
> +
> + ply_list_node_t *node;
> +
> + node = ply_list_get_first_node (plugin->operations);
> +
> + while (node != NULL)
> + {
> + operation_t *operation;
> +
> + operation = ply_list_node_get_data (node);
> + if (strcmp(operation->operation_id, operation_id) == 0)
> + {
> + ply_list_remove_node(plugin->operations, node);
> + return;
> + }
> +
> + node = ply_list_get_next_node (plugin->operations, node);
> +
> + }
> +}
> +
> +static void
> update_status (ply_boot_splash_plugin_t *plugin,
> - const char *status)
> + const char *status,
> + const char *operation_id)
> {
> assert (plugin != NULL);
> + assert (status != NULL);
>
> ply_trace ("status update");
> +
> + if (operation_id != NULL)
> + {
> + const char *operation_name = get_operation_name (plugin, operation_id);
> + if (operation_name != NULL)
> + {
> + char *message;
> + asprintf (&message, "%s... [%s]\r\n", operation_name, status);
> + if (message != NULL)
> + {
> + write_on_views (plugin, message, strlen (message));
> + free(message);
> + }
> + }
> + }
> }
>
> static void
> @@ -431,6 +571,8 @@ ply_boot_splash_plugin_get_interface (void)
> .add_text_display = add_text_display,
> .remove_text_display = remove_text_display,
> .show_splash_screen = show_splash_screen,
> + .register_operation = register_operation,
> + .unregister_operation = unregister_operation,
> .update_status = update_status,
> .on_boot_output = on_boot_output,
> .hide_splash_screen = hide_splash_screen,
> diff --git a/src/plugins/splash/fade-throbber/plugin.c b/src/plugins/splash/fade-throbber/plugin.c
> index 4af6cae..8ed79bf 100644
> --- a/src/plugins/splash/fade-throbber/plugin.c
> +++ b/src/plugins/splash/fade-throbber/plugin.c
> @@ -927,7 +927,8 @@ add_stars (ply_boot_splash_plugin_t *plugin)
>
> static void
> update_status (ply_boot_splash_plugin_t *plugin,
> - const char *status)
> + const char *status,
> + const char *operation_id)
> {
> assert (plugin != NULL);
>
> diff --git a/src/plugins/splash/script/plugin.c b/src/plugins/splash/script/plugin.c
> index c5c1e16..6eccedf 100644
> --- a/src/plugins/splash/script/plugin.c
> +++ b/src/plugins/splash/script/plugin.c
> @@ -430,12 +430,34 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
> }
>
> static void
> +register_operation (ply_boot_splash_plugin_t *plugin,
> + const char *operation_id,
> + const char *name)
> +{
> + script_lib_plymouth_on_register_operation (plugin->script_state,
> + plugin->script_plymouth_lib,
> + operation_id,
> + name);
> +}
> +
> +static void
> +unregister_operation (ply_boot_splash_plugin_t *plugin,
> + const char *operation_id)
> +{
> + script_lib_plymouth_on_unregister_operation (plugin->script_state,
> + plugin->script_plymouth_lib,
> + operation_id);
> +}
> +
> +static void
> update_status (ply_boot_splash_plugin_t *plugin,
> - const char *status)
> + const char *status,
> + const char *operation_id)
> {
> script_lib_plymouth_on_update_status (plugin->script_state,
> plugin->script_plymouth_lib,
> - status);
> + status,
> + operation_id);
> }
>
> static void
> @@ -539,6 +561,8 @@ ply_boot_splash_plugin_get_interface (void)
> .add_pixel_display = add_pixel_display,
> .remove_pixel_display = remove_pixel_display,
> .show_splash_screen = show_splash_screen,
> + .register_operation = register_operation,
> + .unregister_operation = unregister_operation,
> .update_status = update_status,
> .on_boot_progress = on_boot_progress,
> .hide_splash_screen = hide_splash_screen,
> diff --git a/src/plugins/splash/script/script-lib-plymouth.c b/src/plugins/splash/script/script-lib-plymouth.c
> index ab2ec44..6cb1a25 100644
> --- a/src/plugins/splash/script/script-lib-plymouth.c
> +++ b/src/plugins/splash/script/script-lib-plymouth.c
> @@ -81,6 +81,8 @@ script_lib_plymouth_data_t *script_lib_plymouth_setup (script_state_t *s
> data->script_boot_progress_func = script_obj_new_null ();
> data->script_root_mounted_func = script_obj_new_null ();
> data->script_keyboard_input_func = script_obj_new_null ();
> + data->script_register_operation_func = script_obj_new_null ();
> + data->script_unregister_operation_func = script_obj_new_null ();
> data->script_update_status_func = script_obj_new_null ();
> data->script_display_normal_func = script_obj_new_null ();
> data->script_display_password_func = script_obj_new_null ();
> @@ -116,6 +118,18 @@ script_lib_plymouth_data_t *script_lib_plymouth_setup (script_state_t *s
> "function",
> NULL);
> script_add_native_function (plymouth_hash,
> + "SetRegisterOperationFunction",
> + plymouth_set_function,
> + &data->script_register_operation_func,
> + "function",
> + NULL);
> + script_add_native_function (plymouth_hash,
> + "SetUnregisterOperationFunction",
> + plymouth_set_function,
> + &data->script_unregister_operation_func,
> + "function",
> + NULL);
> + script_add_native_function (plymouth_hash,
> "SetUpdateStatusFunction",
> plymouth_set_function,
> &data->script_update_status_func,
> @@ -178,6 +192,8 @@ void script_lib_plymouth_destroy (script_lib_plymouth_data_t *data)
> script_obj_unref (data->script_boot_progress_func);
> script_obj_unref (data->script_root_mounted_func);
> script_obj_unref (data->script_keyboard_input_func);
> + script_obj_unref (data->script_register_operation_func);
> + script_obj_unref (data->script_unregister_operation_func);
> script_obj_unref (data->script_update_status_func);
> script_obj_unref (data->script_display_normal_func);
> script_obj_unref (data->script_display_password_func);
> @@ -240,17 +256,53 @@ void script_lib_plymouth_on_keyboard_input (script_state_t *state,
> script_obj_unref (ret.object);
> }
>
> +void script_lib_plymouth_on_register_operation (script_state_t *state,
> + script_lib_plymouth_data_t *data,
> + const char *operation_id,
> + const char *name)
> +{
> + script_obj_t *new_name_obj = script_obj_new_string (name);
> + script_obj_t *new_operation_id_obj = script_obj_new_string (operation_id);
> + script_return_t ret = script_execute_object (state,
> + data->script_register_operation_func,
> + NULL,
> + new_operation_id_obj,
> + new_name_obj,
> + NULL);
> + script_obj_unref (new_name_obj);
> + script_obj_unref (new_operation_id_obj);
> + script_obj_unref (ret.object);
> +}
> +
> +void script_lib_plymouth_on_unregister_operation (script_state_t *state,
> + script_lib_plymouth_data_t *data,
> + const char *operation_id)
> +{
> + script_obj_t *new_operation_id_obj = script_obj_new_string (operation_id);
> + script_return_t ret = script_execute_object (state,
> + data->script_unregister_operation_func,
> + NULL,
> + new_operation_id_obj,
> + NULL);
> + script_obj_unref (new_operation_id_obj);
> + script_obj_unref (ret.object);
> +}
> +
> void script_lib_plymouth_on_update_status (script_state_t *state,
> script_lib_plymouth_data_t *data,
> - const char *new_status)
> + const char *new_status,
> + const char *operation_id)
> {
> script_obj_t *new_status_obj = script_obj_new_string (new_status);
> + script_obj_t *new_operation_id_obj = script_obj_new_string (operation_id);
> script_return_t ret = script_execute_object (state,
> data->script_update_status_func,
> NULL,
> new_status_obj,
> + new_operation_id_obj,
> NULL);
> script_obj_unref (new_status_obj);
> + script_obj_unref (new_operation_id_obj);
> script_obj_unref (ret.object);
> }
>
> diff --git a/src/plugins/splash/script/script-lib-plymouth.h b/src/plugins/splash/script/script-lib-plymouth.h
> index c4ec5a6..fef5a0f 100644
> --- a/src/plugins/splash/script/script-lib-plymouth.h
> +++ b/src/plugins/splash/script/script-lib-plymouth.h
> @@ -32,6 +32,8 @@ typedef struct
> script_obj_t *script_boot_progress_func;
> script_obj_t *script_root_mounted_func;
> script_obj_t *script_keyboard_input_func;
> + script_obj_t *script_register_operation_func;
> + script_obj_t *script_unregister_operation_func;
> script_obj_t *script_update_status_func;
> script_obj_t *script_display_normal_func;
> script_obj_t *script_display_password_func;
> @@ -57,9 +59,17 @@ void script_lib_plymouth_on_root_mounted (script_state_t *state,
> void script_lib_plymouth_on_keyboard_input (script_state_t *state,
> script_lib_plymouth_data_t *data,
> const char *keyboard_input);
> +void script_lib_plymouth_on_register_operation (script_state_t *state,
> + script_lib_plymouth_data_t *data,
> + const char *operation_id,
> + const char *name);
> +void script_lib_plymouth_on_unregister_operation (script_state_t *state,
> + script_lib_plymouth_data_t *data,
> + const char *operation_id);
> void script_lib_plymouth_on_update_status (script_state_t *state,
> script_lib_plymouth_data_t *data,
> - const char *new_status);
> + const char *new_status,
> + const char *operation_id);
> void script_lib_plymouth_on_display_normal (script_state_t *state,
> script_lib_plymouth_data_t *data);
> void script_lib_plymouth_on_display_password (script_state_t *state,
> diff --git a/src/plugins/splash/space-flares/plugin.c b/src/plugins/splash/space-flares/plugin.c
> index e31dce8..05754e6 100644
> --- a/src/plugins/splash/space-flares/plugin.c
> +++ b/src/plugins/splash/space-flares/plugin.c
> @@ -1708,7 +1708,8 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
>
> static void
> update_status (ply_boot_splash_plugin_t *plugin,
> - const char *status)
> + const char *status,
> + const char *operation_id)
> {
> assert (plugin != NULL);
> }
> diff --git a/src/plugins/splash/text/plugin.c b/src/plugins/splash/text/plugin.c
> index fb97c14..078cd02 100644
> --- a/src/plugins/splash/text/plugin.c
> +++ b/src/plugins/splash/text/plugin.c
> @@ -537,7 +537,8 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
>
> static void
> update_status (ply_boot_splash_plugin_t *plugin,
> - const char *status)
> + const char *status,
> + const char *operation_id)
> {
> assert (plugin != NULL);
>
> diff --git a/src/plugins/splash/throbgress/plugin.c b/src/plugins/splash/throbgress/plugin.c
> index fba809b..a10c5b3 100644
> --- a/src/plugins/splash/throbgress/plugin.c
> +++ b/src/plugins/splash/throbgress/plugin.c
> @@ -713,7 +713,8 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
>
> static void
> update_status (ply_boot_splash_plugin_t *plugin,
> - const char *status)
> + const char *status,
> + const char *operation_id)
> {
> assert (plugin != NULL);
> }
> diff --git a/src/plugins/splash/two-step/plugin.c b/src/plugins/splash/two-step/plugin.c
> index 773e9bf..4d74a52 100644
> --- a/src/plugins/splash/two-step/plugin.c
> +++ b/src/plugins/splash/two-step/plugin.c
> @@ -1157,7 +1157,8 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
>
> static void
> update_status (ply_boot_splash_plugin_t *plugin,
> - const char *status)
> + const char *status,
> + const char *operation_id)
> {
> assert (plugin != NULL);
> }
> diff --git a/src/ply-boot-protocol.h b/src/ply-boot-protocol.h
> index 23dfc8d..31cff34 100644
> --- a/src/ply-boot-protocol.h
> +++ b/src/ply-boot-protocol.h
> @@ -25,6 +25,8 @@
> #define PLY_BOOT_PROTOCOL_TRIMMED_ABSTRACT_SOCKET_PATH "/org/freedesktop/plymouthd"
> #define PLY_BOOT_PROTOCOL_OLD_ABSTRACT_SOCKET_PATH "/ply-boot-protocol"
> #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_PING "P"
> +#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_REGISTER "O"
> +#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_UNREGISTER "o"
> #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_UPDATE "U"
> #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_CHANGE_MODE "C"
> #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_SYSTEM_UPDATE "u"
> diff --git a/src/ply-boot-server.c b/src/ply-boot-server.c
> index 2d2a5b8..409534f 100644
> --- a/src/ply-boot-server.c
> +++ b/src/ply-boot-server.c
> @@ -1,6 +1,7 @@
> /* ply-boot-server.c - listens for and processes boot-status events
> *
> * Copyright (C) 2007 Red Hat, Inc.
> + * Copyright (C) 2012 Pali Rohár <pali.rohar at gmail.com>
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> @@ -57,6 +58,8 @@ struct _ply_boot_server
> ply_list_t *cached_passwords;
> int socket_fd;
>
> + ply_boot_server_register_handler_t register_handler;
> + ply_boot_server_unregister_handler_t unregister_handler;
> ply_boot_server_update_handler_t update_handler;
> ply_boot_server_change_mode_handler_t change_mode_handler;
> ply_boot_server_system_update_handler_t system_update_handler;
> @@ -83,7 +86,9 @@ struct _ply_boot_server
> };
>
> ply_boot_server_t *
> -ply_boot_server_new (ply_boot_server_update_handler_t update_handler,
> +ply_boot_server_new (ply_boot_server_register_handler_t register_handler,
> + ply_boot_server_unregister_handler_t unregister_handler,
> + ply_boot_server_update_handler_t update_handler,
> ply_boot_server_change_mode_handler_t change_mode_handler,
> ply_boot_server_system_update_handler_t system_update_handler,
> ply_boot_server_ask_for_password_handler_t ask_for_password_handler,
> @@ -112,6 +117,8 @@ ply_boot_server_new (ply_boot_server_update_handler_t update_handler,
> server->cached_passwords = ply_list_new ();
> server->loop = NULL;
> server->is_listening = false;
> + server->register_handler = register_handler;
> + server->unregister_handler = unregister_handler;
> server->update_handler = update_handler;
> server->change_mode_handler = change_mode_handler;
> server->system_update_handler = system_update_handler;
> @@ -203,9 +210,12 @@ ply_boot_server_stop_listening (ply_boot_server_t *server)
> static bool
> ply_boot_connection_read_request (ply_boot_connection_t *connection,
> char **command,
> - char **argument)
> + char **argument_1,
> + char **argument_2)
> {
> uint8_t header[2];
> + uint8_t argument_1_size = 0;
> + uint8_t argument_2_size = 0;
>
> assert (connection != NULL);
> assert (connection->fd >= 0);
> @@ -218,22 +228,41 @@ ply_boot_connection_read_request (ply_boot_connection_t *connection,
> *command = calloc (2, sizeof (char));
> *command[0] = header[0];
>
> - *argument = NULL;
> - if (header[1] == '\002')
> + *argument_1 = NULL;
> + *argument_2 = NULL;
> + if (header[1] == '\002' || header[1] == '\003')
> {
> - uint8_t argument_size;
> + if (!ply_read (connection->fd, &argument_1_size, sizeof (uint8_t)))
> + {
> + free (*command);
> + return false;
> + }
> +
> + *argument_1 = calloc (argument_1_size, sizeof (char));
>
> - if (!ply_read (connection->fd, &argument_size, sizeof (uint8_t)))
> + if (!ply_read (connection->fd, *argument_1, argument_1_size))
> {
> + free (*argument_1);
> free (*command);
> return false;
> }
> + }
>
> - *argument = calloc (argument_size, sizeof (char));
> + if (header[1] == '\003')
> + {
> + if (!ply_read (connection->fd, &argument_2_size, sizeof (uint8_t)))
> + {
> + free (*argument_1);
> + free (*command);
> + return false;
> + }
> +
> + *argument_2 = calloc (argument_2_size, sizeof (char));
>
> - if (!ply_read (connection->fd, *argument, argument_size))
> + if (!ply_read (connection->fd, *argument_2, argument_2_size))
> {
> - free (*argument);
> + free (*argument_1);
> + free (*argument_2);
> free (*command);
> return false;
> }
> @@ -242,7 +271,8 @@ ply_boot_connection_read_request (ply_boot_connection_t *connection,
> if (!ply_get_credentials_from_fd (connection->fd, &connection->pid, &connection->uid, NULL))
> {
> ply_trace ("couldn't read credentials from connection: %m");
> - free (*argument);
> + free (*argument_1);
> + free (*argument_2);
> free (*command);
> return false;
> }
> @@ -379,7 +409,7 @@ static void
> ply_boot_connection_on_request (ply_boot_connection_t *connection)
> {
> ply_boot_server_t *server;
> - char *command, *argument;
> + char *command, *argument_1, *argument_2;
>
> assert (connection != NULL);
> assert (connection->fd >= 0);
> @@ -388,7 +418,7 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
> assert (server != NULL);
>
> if (!ply_boot_connection_read_request (connection,
> - &command, &argument))
> + &command, &argument_1, &argument_2))
> {
> ply_trace ("could not read connection request");
> return;
> @@ -420,8 +450,36 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
>
> ply_trace ("got update request");
> if (server->update_handler != NULL)
> - server->update_handler (server->user_data, argument, server);
> - free (argument);
> + server->update_handler (server->user_data, argument_1, argument_2, server);
> + free (argument_1);
> + free (argument_2);
> + free (command);
> + return;
> + }
> + else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_REGISTER) == 0)
> + {
> + if (!ply_write (connection->fd,
> + PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK,
> + strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK)))
> + ply_trace ("could not finish writing update reply: %m");
> +
> + if (server->register_handler != NULL)
> + server->register_handler (server->user_data, argument_1, argument_2, server);
> + free (argument_1);
> + free (argument_2);
> + free (command);
> + return;
> + }
> + else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_UNREGISTER) == 0)
> + {
> + if (!ply_write (connection->fd,
> + PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK,
> + strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK)))
> + ply_trace ("could not finish writing update reply: %m");
> +
> + if (server->unregister_handler != NULL)
> + server->unregister_handler (server->user_data, argument_1, server);
> + free (argument_1);
> free (command);
> return;
> }
> @@ -434,8 +492,9 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
>
> ply_trace ("got change mode notification");
> if (server->change_mode_handler != NULL)
> - server->change_mode_handler (server->user_data, argument, server);
> - free (argument);
> + server->change_mode_handler (server->user_data, argument_1, server);
> + free (argument_1);
> + free (argument_2);
> free (command);
> return;
> }
> @@ -444,10 +503,10 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
> long int value;
> char *endptr = NULL;
>
> - value = strtol (argument, &endptr, 10);
> + value = strtol (argument_1, &endptr, 10);
> if (endptr == NULL || *endptr != '\0' || value < 0 || value > 100)
> {
> - ply_error ("failed to parse percentage %s", argument);
> + ply_error ("failed to parse percentage %s", argument_1);
> value = 0;
> }
>
> @@ -459,7 +518,8 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
>
> if (server->system_update_handler != NULL)
> server->system_update_handler (server->user_data, value, server);
> - free (argument);
> + free (argument_1);
> + free (argument_2);
> free (command);
> return;
> }
> @@ -503,7 +563,8 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
> if (server->deactivate_handler != NULL)
> server->deactivate_handler (server->user_data, deactivate_trigger, server);
>
> - free (argument);
> + free (argument_1);
> + free (argument_2);
> free (command);
> return;
> }
> @@ -518,7 +579,7 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
> bool retain_splash;
> ply_trigger_t *quit_trigger;
>
> - retain_splash = (bool) argument[0];
> + retain_splash = (bool) argument_1[0];
>
> ply_trace ("got quit %srequest", retain_splash? "--retain-splash " : "");
>
> @@ -532,7 +593,8 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
> if (server->quit_handler != NULL)
> server->quit_handler (server->user_data, retain_splash, quit_trigger, server);
>
> - free(argument);
> + free(argument_1);
> + free(argument_2);
> free(command);
> return;
> }
> @@ -550,7 +612,7 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
>
> if (server->ask_for_password_handler != NULL)
> server->ask_for_password_handler (server->user_data,
> - argument,
> + argument_1,
> answer,
> server);
> /* will reply later
> @@ -638,7 +700,7 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
>
> if (server->ask_question_handler != NULL)
> server->ask_question_handler (server->user_data,
> - argument,
> + argument_1,
> answer,
> server);
> /* will reply later
> @@ -650,13 +712,13 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
> {
> ply_trace ("got show message request");
> if (server->display_message_handler != NULL)
> - server->display_message_handler(server->user_data, argument, server);
> + server->display_message_handler(server->user_data, argument_1, server);
> }
> else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_HIDE_MESSAGE) == 0)
> {
> ply_trace ("got hide message request");
> if (server->hide_message_handler != NULL)
> - server->hide_message_handler(server->user_data, argument, server);
> + server->hide_message_handler(server->user_data, argument_1, server);
> }
> else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE) == 0)
> {
> @@ -672,7 +734,7 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
>
> if (server->watch_for_keystroke_handler != NULL)
> server->watch_for_keystroke_handler (server->user_data,
> - argument,
> + argument_1,
> answer,
> server);
> /* will reply later
> @@ -685,7 +747,7 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
> ply_trace ("got keystroke remove request");
> if (server->ignore_keystroke_handler != NULL)
> server->ignore_keystroke_handler (server->user_data,
> - argument,
> + argument_1,
> server);
> }
> else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PROGRESS_PAUSE) == 0)
> @@ -706,7 +768,7 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
> {
> ply_trace ("got newroot request");
> if (server->newroot_handler != NULL)
> - server->newroot_handler(server->user_data, argument, server);
> + server->newroot_handler(server->user_data, argument_1, server);
> }
> else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_HAS_ACTIVE_VT) == 0)
> {
> @@ -838,11 +900,27 @@ ply_boot_server_attach_to_event_loop (ply_boot_server_t *server,
> #include "ply-event-loop.h"
> #include "ply-boot-server.h"
>
> +static void
> +on_register (ply_event_loop_t *loop,
> + const char *operation_id,
> + const char *name)
> +{
> + printf ("register operation id '%s' name '%s'\n", operation_id, name);
> +}
> +
> +static void
> +on_unregister (ply_event_loop_t *loop,
> + const char *operation_id)
> +{
> + printf ("unregister operation id '%s'\n", operation_id);
> +}
> +
> static void
> on_update (ply_event_loop_t *loop,
> - const char *status)
> + const char *status,
> + const char *operation_id)
> {
> - printf ("new status is '%s'\n", status);
> + printf ("new status for operation '%s' is '%s'\n", operation_id, status);
> }
>
> static void
> @@ -974,7 +1052,9 @@ main (int argc,
>
> loop = ply_event_loop_new ();
>
> - server = ply_boot_server_new ((ply_boot_server_update_handler_t) on_update,
> + server = ply_boot_server_new ((ply_boot_server_register_handler_t) on_register,
> + (ply_boot_server_unregister_handler_t) on_unregister,
> + (ply_boot_server_update_handler_t) on_update,
> (ply_boot_server_change_mode_handler_t) on_change_mode,
> (ply_boot_server_system_update_handler_t) on_system_update,
> (ply_boot_server_ask_for_password_handler_t) on_ask_for_password,
> diff --git a/src/ply-boot-server.h b/src/ply-boot-server.h
> index b885a81..56e50bb 100644
> --- a/src/ply-boot-server.h
> +++ b/src/ply-boot-server.h
> @@ -32,8 +32,18 @@
>
> typedef struct _ply_boot_server ply_boot_server_t;
>
> +typedef void (* ply_boot_server_register_handler_t) (void *user_data,
> + const char *operation_id,
> + const char *name,
> + ply_boot_server_t *server);
> +
> +typedef void (* ply_boot_server_unregister_handler_t) (void *user_data,
> + const char *operation_id,
> + ply_boot_server_t *server);
> +
> typedef void (* ply_boot_server_update_handler_t) (void *user_data,
> const char *status,
> + const char *operation_id,
> ply_boot_server_t *server);
>
> typedef void (* ply_boot_server_change_mode_handler_t) (void *user_data,
> @@ -104,7 +114,9 @@ typedef bool (* ply_boot_server_has_active_vt_handler_t) (void *use
> ply_boot_server_t *server);
>
> #ifndef PLY_HIDE_FUNCTION_DECLARATIONS
> -ply_boot_server_t *ply_boot_server_new (ply_boot_server_update_handler_t update_handler,
> +ply_boot_server_t *ply_boot_server_new (ply_boot_server_register_handler_t register_handler,
> + ply_boot_server_unregister_handler_t unregister_handler,
> + ply_boot_server_update_handler_t update_handler,
> ply_boot_server_change_mode_handler_t change_mode_handler,
> ply_boot_server_system_update_handler_t system_update_handler,
> ply_boot_server_ask_for_password_handler_t ask_for_password_handler,
> diff --git a/src/upstart-bridge/ply-upstart-monitor.c b/src/upstart-bridge/ply-upstart-monitor.c
> index b19d95a..5c49d8a 100644
> --- a/src/upstart-bridge/ply-upstart-monitor.c
> +++ b/src/upstart-bridge/ply-upstart-monitor.c
> @@ -110,7 +110,7 @@ instance_is_initialized (ply_upstart_monitor_instance_t *instance)
> {
> /* Note that the job may not have a description. */
> if (instance->job->properties.name &&
> - instance->properties.name && instance->properties.goal &&
> + instance->properties.goal &&
> instance->properties.state)
> return true;
> else
> diff --git a/src/upstart-bridge/plymouth-upstart-bridge.c b/src/upstart-bridge/plymouth-upstart-bridge.c
> index 7fe1f42..f9e0b6e 100644
> --- a/src/upstart-bridge/plymouth-upstart-bridge.c
> +++ b/src/upstart-bridge/plymouth-upstart-bridge.c
> @@ -1,6 +1,7 @@
> /* plymouth-upstart-bridge.c - bridge Upstart job state changes to Plymouth
> *
> * Copyright (C) 2010, 2011 Canonical Ltd.
> + * Copyright (C) 2012 Pali Rohár <pali.rohar at gmail.com>
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> @@ -28,14 +29,6 @@
> #include <string.h>
> #include <unistd.h>
>
> -#if defined(HAVE_NCURSESW_TERM_H)
> -#include <ncursesw/term.h>
> -#elif defined(HAVE_NCURSES_TERM_H)
> -#include <ncurses/term.h>
> -#else
> -#include <term.h>
> -#endif
> -
> #include "ply-boot-client.h"
> #include "ply-command-parser.h"
> #include "ply-event-loop.h"
> @@ -50,152 +43,70 @@ typedef struct
> ply_command_parser_t *command_parser;
> } state_t;
>
> -#ifndef TERMINAL_COLOR_RED
> -#define TERMINAL_COLOR_RED 1
> -#endif
> -
> -/* We don't care about the difference between "not a string capability" and
> - * "cancelled or absent".
> - */
> -static const char *
> -get_string_capability (const char *name)
> -{
> - const char *value;
> -
> - value = tigetstr ((char *) name);
> - if (value == (const char *) -1)
> - value = NULL;
> -
> - return value;
> -}
> -
> -static bool
> -terminal_ignores_new_line_after_80_chars (void)
> -{
> - return tigetflag ((char *) "xenl") != 0;
> -}
> -
> -static int
> -get_number_of_columns (void)
> -{
> - int number_of_columns;
> -
> - number_of_columns = tigetnum ((char *) "cols");
> -
> - return number_of_columns;
> -}
> -
> -static bool
> -can_set_cursor_column (void)
> -{
> - const char *capability;
> -
> - capability = get_string_capability ("hpa");
> -
> - return capability != NULL;
> -}
> -
> -static void
> -set_cursor_column (int column)
> -{
> - const char *capability;
> - const char *terminal_string;
> -
> - capability = get_string_capability ("hpa");
> - terminal_string = tiparm (capability, column);
> - fputs (terminal_string, stdout);
> -}
> -
> -static bool
> -can_set_fg_color (void)
> -{
> - const char *capability;
> -
> - capability = get_string_capability ("setaf");
> -
> - return capability != NULL;
> -}
> -
> -static void
> -set_fg_color (int color)
> -{
> - const char *capability;
> - const char *terminal_string;
> -
> - capability = get_string_capability ("setaf");
> - terminal_string = tiparm (capability, color);
> - fputs (terminal_string, stdout);
> -}
> -
> -static void
> -unset_fg_color (void)
> -{
> - const char *terminal_string;
> -
> - terminal_string = get_string_capability ("op");
> -
> - if (terminal_string == NULL)
> - return;
> -
> - fputs (terminal_string, stdout);
> -}
> -
> static void
> update_status (state_t *state,
> ply_upstart_monitor_job_properties_t *job,
> ply_upstart_monitor_instance_properties_t *instance,
> const char *action,
> - bool is_okay)
> + const char *status,
> + bool init,
> + bool finished)
> {
> - ply_boot_client_update_daemon (state->client, job->name, NULL, NULL, state);
> + size_t size = 0;
> + char *description = NULL;
> + char *ptr;
>
> - if (job->description == NULL)
> + if (job->name == NULL || status == NULL)
> return;
>
> - printf (" * %s%s%s",
> - action ? action : "", action ? " " : "", job->description);
> + if (finished && strcmp(status, "failed") != 0)
> + {
> + status = "done";
> + }
>
> - if (terminal_ignores_new_line_after_80_chars () && can_set_cursor_column ())
> + if (init)
> {
> - int number_of_columns, column;
>
> - number_of_columns = get_number_of_columns ();
> + if (action != NULL)
> + size += strlen(action) + 1;
>
> - if (number_of_columns < (int) strlen("[fail]"))
> - number_of_columns = 80;
> + if (job->description != NULL)
> + size += strlen(job->description) + 1;
>
> - column = number_of_columns - strlen ("[fail]") - 1;
> + size += strlen(job->name) + 1;
>
> - set_cursor_column (column);
> + ptr = description = malloc(size);
>
> - if (is_okay)
> - puts ("[ OK ]");
> - else
> + if (description != NULL)
> {
> - bool supports_color;
>
> - supports_color = can_set_fg_color ();
> + if (action != NULL)
> + {
> + ptr += sprintf (ptr, "%s ", action);
> + }
>
> - fputs ("[", stdout);
> + if (job->description != NULL)
> + {
> + ptr += sprintf (ptr, "%s ", job->description);
> + }
>
> - if (supports_color)
> - set_fg_color (TERMINAL_COLOR_RED);
> + ptr += sprintf (ptr, "%s", job->name);
>
> - fputs ("fail", stdout);
> + ply_boot_client_register_operation (state->client, job->name, description, NULL, NULL, state);
>
> - if (supports_color)
> - unset_fg_color ();
> + free(description);
>
> - puts ("]");
> }
> +
> }
> - else
> +
> + ply_boot_client_update_daemon (state->client, status, job->name, NULL, NULL, state);
> +
> + if (finished)
> {
> - if (is_okay)
> - puts (" ...done.");
> - else
> - puts (" ...fail!");
> + ply_boot_client_unregister_operation (state->client, job->name, NULL, NULL, state);
> }
> +
> }
>
> static void
> @@ -206,15 +117,9 @@ on_failed (void *data,
> {
> state_t *state = data;
>
> - if (job->is_task)
> - update_status (state, job, instance, NULL, false);
> - else
> - {
> - if (strcmp (instance->goal, "start") == 0)
> - update_status (state, job, instance, "Starting", false);
> - else if (strcmp (instance->goal, "stop") == 0)
> - update_status (state, job, instance, "Stopping", false);
> - }
> + ply_trace ("state: %s goal: %s is_task: %d", instance->state, instance->goal, job->is_task);
> +
> + update_status (state, job, instance, NULL, "failed", false, true);
> }
>
> static void
> @@ -223,25 +128,39 @@ on_state_changed (state_t *state,
> ply_upstart_monitor_job_properties_t *job,
> ply_upstart_monitor_instance_properties_t *instance)
> {
> + bool init = false;
> + bool finish = false;
> +
> + ply_trace ("state: %s goal: %s is_task: %d", instance->state, instance->goal, job->is_task);
> +
> if (instance->failed)
> return;
>
> if (job->is_task)
> {
> - if (strcmp (instance->state, "waiting") == 0)
> - update_status (state, job, instance, NULL, true);
> + if (strcmp (instance->state, "starting") == 0)
> + init = true;
> + else if (strcmp (instance->state, "waiting") == 0)
> + finish = true;
> + update_status (state, job, instance, NULL, instance->state, init, finish);
> }
> else
> {
> if (strcmp (instance->goal, "start") == 0)
> {
> - if (strcmp (instance->state, "running") == 0)
> - update_status (state, job, instance, "Starting", true);
> + if (strcmp (instance->state, "starting") == 0)
> + init = true;
> + else if (strcmp (instance->state, "running") == 0)
> + finish = true;
> + update_status (state, job, instance, "Starting", instance->state, init, finish);
> }
> else if (strcmp (instance->goal, "stop") == 0)
> {
> - if (strcmp (instance->state, "waiting") == 0)
> - update_status (state, job, instance, "Stopping", true);
> + if (strcmp (instance->state, "pre-stop") == 0)
> + init = true;
> + else if (strcmp (instance->state, "waiting") == 0)
> + finish = true;
> + update_status (state, job, instance, "Stopping", instance->state, init, finish);
> }
> }
> }
> @@ -307,8 +226,6 @@ main (int argc,
> 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);
> --
> 1.7.9.5
>
> --
> Pali Rohár
> pali.rohar at gmail.com
More information about the plymouth
mailing list