7
#include <glib/gstdio.h>
8
#include <libnotify/notify.h>
10
#include <sys/sysinfo.h>
12
#include "update-notifier.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
show_notification (const char *summary, const char *body, const char *icon)
34
NotifyNotification *n = notify_notification_new (summary, body, icon);
35
notify_notification_set_timeout (n, 60000);
36
notify_notification_show (n, NULL);
41
get_event_from_file (const char* filename, char **event, char **description)
43
g_autofree gchar *content = NULL;
45
g_return_if_fail (filename != NULL);
46
g_return_if_fail (event != NULL);
47
g_return_if_fail (description != NULL);
49
*event = *description = NULL;
51
g_file_get_contents (filename, &content, NULL, NULL);
54
gchar **strings = g_strsplit (content, " ", 2);
56
if (g_strv_length (strings) > 0)
57
*event = g_strdup (g_strstrip (strings[0]));
58
if (g_strv_length (strings) > 1)
59
*description = g_strdup (g_strstrip (strings[1]));
70
if (sysinfo (&info) == -1) {
71
g_critical ("Failed to get uptime: %m");
79
file_modified_after_boot (const char* filename)
83
time_t boot_timestamp;
85
/* In case of error it's safer to assume that the status file has been
86
modified after boot in order to not miss the notification. */
87
if (g_stat (STATUS_PATH, &status_stat) == -1)
90
if ((uptime = get_uptime ()) == -1)
93
boot_timestamp = time (NULL) - (time_t) uptime;
94
return difftime (status_stat.st_mtim.tv_sec, boot_timestamp) >= 0;
98
show_status_notification ()
100
g_autofree gchar *event = NULL;
101
g_autofree gchar *description = NULL;
103
if (!g_file_test (STATUS_PATH, G_FILE_TEST_EXISTS))
106
if (!file_modified_after_boot (STATUS_PATH))
109
get_event_from_file (STATUS_PATH, &event, &description);
111
if (g_strcmp0 (event, "applied") == 0) {
112
g_autofree gchar *body = NULL;
114
gboolean is_overflow, conversion_failed;
117
guint64 num_updates = g_ascii_strtoull (description, &endptr, 10);
118
is_overflow = (num_updates == G_MAXUINT64 && errno == ERANGE);
119
conversion_failed = (num_updates == 0 && description == endptr);
121
if (is_overflow || conversion_failed) {
122
g_warning ("Failed to parse the status file");
123
} else if (num_updates != 0) {
124
body = g_strdup_printf (
125
ngettext ("%" G_GUINT64_FORMAT " Livepatch update has been successfully applied.",
126
"%" G_GUINT64_FORMAT " Livepatch updates have been successfully applied.",
130
show_notification (_("Canonical Livepatch"), body, NULL);
136
main (int argc, char **argv)
138
init_notification ();
141
show_status_notification ();