5
#include <gio/gdesktopappinfo.h>
7
#include <glib/gstdio.h>
8
#include <libnotify/notify.h>
9
#include <sys/sysinfo.h>
11
#include "update-notifier.h"
12
#include "livepatch-utils.h"
14
#define STATUS_PATH "/var/snap/canonical-livepatch/current/status"
19
notify_init ("update-notifier");
25
setlocale (LC_ALL, "");
26
bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
27
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
28
textdomain (GETTEXT_PACKAGE);
32
notify_action_cb (NotifyNotification *notification,
36
g_autoptr(GDesktopAppInfo) info = NULL;
37
g_autoptr(GdkAppLaunchContext) context = NULL;
38
g_autoptr(GError) error = NULL;
40
info = g_desktop_app_info_new (LIVEPATCH_DESKTOP_FILE);
42
g_warning ("Could not find application '%s'", LIVEPATCH_DESKTOP_FILE);
46
context = gdk_display_get_app_launch_context (gdk_display_get_default ());
47
if (!g_app_info_launch (G_APP_INFO (info), NULL, G_APP_LAUNCH_CONTEXT (context), &error)) {
48
g_warning ("Could not launch application '%s'", LIVEPATCH_DESKTOP_FILE);
53
show_notification (const char *summary, const char *body, const char *icon)
55
NotifyNotification *n;
56
g_autoptr(GError) error = NULL;
58
n = notify_notification_new (summary, body, icon);
59
notify_notification_set_timeout (n, 60000);
61
if (livepatch_has_settings_ui()) {
62
notify_notification_add_action (n, "settings", _("Show Settings…"),
63
notify_action_cb, NULL, NULL);
64
notify_notification_add_action (n, "default", _("Show Settings…"),
65
notify_action_cb, NULL, NULL);
67
g_warning ("There is no graphical application installed to manage "
68
"Livepatch. The notification will not have a "
69
"'Show Settings…' button.");
72
g_signal_connect (n, "closed", G_CALLBACK (gtk_main_quit), NULL);
74
if (!notify_notification_show (n, &error)) {
75
g_warning ("Could not show notification: '%s", error->message);
87
if (sysinfo (&info) == -1) {
88
g_critical ("Failed to get uptime: %m");
96
file_modified_after_boot (const char* filename)
100
time_t boot_timestamp;
102
/* In case of error it's safer to assume that the status file has been
103
modified after boot in order to not miss the notification. */
104
if (g_stat (STATUS_PATH, &status_stat) == -1)
107
if ((uptime = get_uptime ()) == -1)
110
boot_timestamp = time (NULL) - (time_t) uptime;
111
return difftime (status_stat.st_mtim.tv_sec, boot_timestamp) >= 0;
115
show_status_notification ()
117
g_autofree gchar *state = NULL;
118
g_autoptr(GError) error = NULL;
120
if (!g_file_test (STATUS_PATH, G_FILE_TEST_EXISTS))
123
if (!file_modified_after_boot (STATUS_PATH))
126
state = livepatch_get_state (&error);
128
g_warning ("Failed to get Livepatch state: %s", error->message);
132
if (g_strcmp0(state, "applied") != 0)
135
return show_notification ("Livepatch", _("An update has just been applied."), NULL);
139
main (int argc, char **argv)
141
gtk_init (&argc, &argv);
142
init_notification ();
145
if (show_status_notification ())