From 1a1e7e54248c5c896b9e57e779d520846ca5a590 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 15 Jul 2014 16:35:11 -0500 Subject: add a passable parser for /etc/os-release --- src/service.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/src/service.c b/src/service.c index 7484134..1852cbc 100644 --- a/src/service.c +++ b/src/service.c @@ -329,14 +329,95 @@ get_current_real_name (IndicatorSessionService * self) **** ***/ +static GHashTable* +get_os_release (void) +{ + GHashTable * hash; + GIOChannel * io; + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + if ((io = g_io_channel_new_file ("/etc/os-release", "r", NULL))) + { + GString * gstr = g_string_new (NULL); + + for (;;) + { + char *p, *q; + const char *val; + GIOStatus status; + + /* read a line */ + status = g_io_channel_read_line_string (io, gstr, NULL, NULL); + if (status == G_IO_STATUS_EOF) + break; + + /* ignore blank lines & comments */ + if (!gstr->len || gstr->str[0]=='#') + continue; + + /* split into name=value */ + p = strchr(gstr->str, '='); + if (!p) + continue; + *p++ = '\0'; + + /* remove quotes and newline; un-escape */ + val = p; + q = p; + while (*p) + { + if ((*p == '\'') || (*p == '"') || (*p == '\n')) + { + ++p; + } + else + { + if ((*p=='\\') && !*++p) + break; + *q++ = *p++; + } + + *q = '\0'; /* zero terminate */ + } + + g_hash_table_insert (hash, g_strdup(gstr->str), g_strdup(val)); + } + + g_string_free(gstr, TRUE); + g_io_channel_unref(io); + } + + return hash; +} + +static const char* +get_distro_name (void) +{ + static char * distro_name = NULL; + + if (distro_name == NULL) + { + GHashTable * os_release = get_os_release(); + gpointer value = g_hash_table_lookup(os_release, "NAME"); + if (value == NULL) + value = _("Ubuntu"); /* fallback value */ + distro_name = g_strdup(value); + g_hash_table_destroy(os_release); + } + + return distro_name; +} + static GMenuModel * create_admin_section (void) { GMenu * menu; - + gchar * help_label = g_strjoin(" ", get_distro_name(), _("Help"), NULL); menu = g_menu_new (); g_menu_append (menu, _("About This Computer"), "indicator.about"); - g_menu_append (menu, _("Ubuntu Help"), "indicator.help"); + g_menu_append (menu, help_label, "indicator.help"); + g_free (help_label); return G_MENU_MODEL (menu); } -- cgit v1.2.3 From cbe3fbea8ad9d75210885fc7437709b735515470 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 16 Jul 2014 01:16:42 -0500 Subject: don't mark 'Ubuntu' for translation. --- src/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service.c b/src/service.c index 1852cbc..0b94998 100644 --- a/src/service.c +++ b/src/service.c @@ -401,7 +401,7 @@ get_distro_name (void) GHashTable * os_release = get_os_release(); gpointer value = g_hash_table_lookup(os_release, "NAME"); if (value == NULL) - value = _("Ubuntu"); /* fallback value */ + value = "Ubuntu"; /* fallback value */ distro_name = g_strdup(value); g_hash_table_destroy(os_release); } -- cgit v1.2.3 From a034869430082a3b10179b13071e3cc3eb6ffb97 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 16 Jul 2014 01:18:35 -0500 Subject: better i18n markup of the help string --- src/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service.c b/src/service.c index 0b94998..f8c375d 100644 --- a/src/service.c +++ b/src/service.c @@ -413,7 +413,7 @@ static GMenuModel * create_admin_section (void) { GMenu * menu; - gchar * help_label = g_strjoin(" ", get_distro_name(), _("Help"), NULL); + gchar * help_label = g_strdup_printf(_("%s Help"), get_distro_name()); menu = g_menu_new (); g_menu_append (menu, _("About This Computer"), "indicator.about"); g_menu_append (menu, help_label, "indicator.help"); -- cgit v1.2.3 From b2fe95c6d86114b2681763df845a2817ee0fe234 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 16 Jul 2014 01:26:56 -0500 Subject: make the os-release parser slightly less unreadable. --- src/service.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/service.c b/src/service.c index f8c375d..faff4d4 100644 --- a/src/service.c +++ b/src/service.c @@ -343,7 +343,7 @@ get_os_release (void) for (;;) { - char *p, *q; + char *in, *out; const char *val; GIOStatus status; @@ -357,29 +357,28 @@ get_os_release (void) continue; /* split into name=value */ - p = strchr(gstr->str, '='); - if (!p) + in = strchr(gstr->str, '='); + if (!in) continue; - *p++ = '\0'; + *in++ = '\0'; /* remove quotes and newline; un-escape */ - val = p; - q = p; - while (*p) + val = out = in; + while (*in) { - if ((*p == '\'') || (*p == '"') || (*p == '\n')) + if ((*in=='\'') || (*in=='"') || (*in=='\n')) /* skip chars */ { - ++p; + ++in; } else { - if ((*p=='\\') && !*++p) + if ((*in=='\\') && !*++in) /* handle an escaped char */ break; - *q++ = *p++; - } - *q = '\0'; /* zero terminate */ + *out++ = *in++; + } } + *out = '\0'; /* zero terminate */ g_hash_table_insert (hash, g_strdup(gstr->str), g_strdup(val)); } -- cgit v1.2.3 From 53bf4a35a2fb23a97756fd758ad7de84a1565688 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 16 Jul 2014 01:42:54 -0500 Subject: make the os-release parser slightly more readable. --- src/service.c | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/service.c b/src/service.c index faff4d4..4c32f8b 100644 --- a/src/service.c +++ b/src/service.c @@ -339,51 +339,48 @@ get_os_release (void) if ((io = g_io_channel_new_file ("/etc/os-release", "r", NULL))) { - GString * gstr = g_string_new (NULL); + GString * key = g_string_new (NULL); for (;;) { - char *in, *out; - const char *val; GIOStatus status; + char *in; + GString * val; + gsize i; /* read a line */ - status = g_io_channel_read_line_string (io, gstr, NULL, NULL); + status = g_io_channel_read_line_string (io, key, NULL, NULL); if (status == G_IO_STATUS_EOF) break; /* ignore blank lines & comments */ - if (!gstr->len || gstr->str[0]=='#') + if (!key->len || key->str[0]=='#') continue; - /* split into name=value */ - in = strchr(gstr->str, '='); + /* split into key=value */ + in = strchr(key->str, '='); if (!in) continue; *in++ = '\0'; - /* remove quotes and newline; un-escape */ - val = out = in; - while (*in) + /* remove quotes and newlines; unescape escape sequences */ + val = g_string_new(in); + for (i=0; ilen; ) { - if ((*in=='\'') || (*in=='"') || (*in=='\n')) /* skip chars */ - { - ++in; - } - else - { - if ((*in=='\\') && !*++in) /* handle an escaped char */ - break; - - *out++ = *in++; - } + if (val->str[i]=='\\' && ((i+1)len)) /* unescape */ + g_string_erase (val, i++, 1); + + else if ((val->str[i]=='\'') || (val->str[i]=='"') || (val->str[i]=='\n')) /* skip */ + g_string_erase (val, i, 1); + + else /* keep */ + i++; } - *out = '\0'; /* zero terminate */ - - g_hash_table_insert (hash, g_strdup(gstr->str), g_strdup(val)); + + g_hash_table_insert (hash, g_strdup(key->str), g_string_free(val,FALSE)); } - g_string_free(gstr, TRUE); + g_string_free(key, TRUE); g_io_channel_unref(io); } -- cgit v1.2.3 From a66b3889574a355fe900cbb8d8e5d39c82043de9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 16 Jul 2014 09:00:50 -0500 Subject: tweak unescape comment for readability --- src/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service.c b/src/service.c index 4c32f8b..c9d1b13 100644 --- a/src/service.c +++ b/src/service.c @@ -367,7 +367,7 @@ get_os_release (void) val = g_string_new(in); for (i=0; ilen; ) { - if (val->str[i]=='\\' && ((i+1)len)) /* unescape */ + if (val->str[i]=='\\' && ((i+1)len)) /* unescape: skip 1, keep 1 */ g_string_erase (val, i++, 1); else if ((val->str[i]=='\'') || (val->str[i]=='"') || (val->str[i]=='\n')) /* skip */ -- cgit v1.2.3 From bf07982baca283c98624d4e64efbf0e641d019d0 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 16 Jul 2014 11:32:07 -0500 Subject: use g_shell_unquote() to unmunge the values in /etc/os-release --- src/service.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/service.c b/src/service.c index c9d1b13..034e67c 100644 --- a/src/service.c +++ b/src/service.c @@ -332,21 +332,22 @@ get_current_real_name (IndicatorSessionService * self) static GHashTable* get_os_release (void) { + static const char * const os_release = "/etc/os-release"; GHashTable * hash; GIOChannel * io; hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - if ((io = g_io_channel_new_file ("/etc/os-release", "r", NULL))) + if ((io = g_io_channel_new_file (os_release, "r", NULL))) { GString * key = g_string_new (NULL); for (;;) { GIOStatus status; - char *in; - GString * val; - gsize i; + char * in; + GError * error; + gchar * val; /* read a line */ status = g_io_channel_read_line_string (io, key, NULL, NULL); @@ -363,21 +364,19 @@ get_os_release (void) continue; *in++ = '\0'; - /* remove quotes and newlines; unescape escape sequences */ - val = g_string_new(in); - for (i=0; ilen; ) + /* unmunge the value component */ + g_strstrip(in); /* eat linefeed */ + error = NULL; + val = g_shell_unquote (in, &error); + if (error != NULL) { - if (val->str[i]=='\\' && ((i+1)len)) /* unescape: skip 1, keep 1 */ - g_string_erase (val, i++, 1); - - else if ((val->str[i]=='\'') || (val->str[i]=='"') || (val->str[i]=='\n')) /* skip */ - g_string_erase (val, i, 1); - - else /* keep */ - i++; + g_warning("Unable to unquote \"%s\": %s", in, error->message); + val = g_strdup(in); + g_clear_error(&error); } - - g_hash_table_insert (hash, g_strdup(key->str), g_string_free(val,FALSE)); + + g_debug("from \"%s\": key [%s] val [%s]", os_release, key->str, val); + g_hash_table_insert (hash, g_strdup(key->str), val); /* hash owns val now */ } g_string_free(key, TRUE); -- cgit v1.2.3