From a2885a56d41f5f190bc3d5ad1dab8e43088457a9 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 13 May 2011 15:48:45 +0100 Subject: [PATCH] info: Add helper for pretty hostname to hostname So that we can set the static hostname depending on the value of the pretty hostname. --- panels/info/Makefile.am | 16 +++- panels/info/hostname-helper.c | 173 ++++++++++++++++++++++++++++++++++ panels/info/hostname-helper.h | 21 +++++ panels/info/test-hostname.c | 59 ++++++++++++ 4 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 panels/info/hostname-helper.c create mode 100644 panels/info/hostname-helper.h create mode 100644 panels/info/test-hostname.c diff --git a/panels/info/Makefile.am b/panels/info/Makefile.am index 1a9e81c67..7ffee41ef 100644 --- a/panels/info/Makefile.am +++ b/panels/info/Makefile.am @@ -11,13 +11,25 @@ INCLUDES = \ -I$(top_srcdir)/libgnome-control-center/ \ $(NULL) +noinst_PROGRAMS = test-hostname +test_hostname_SOURCES = hostname-helper.c hostname-helper.h test-hostname.c +test_hostname_LDADD = $(PANEL_LIBS) $(INFO_PANEL_LIBS) +test_hostname_CFLAGS = $(INCLUDES) + +all-local: check-local + +check-local: test-hostname + $(builddir)/test-hostname > /dev/null + ccpanelsdir = $(PANELS_DIR) ccpanels_LTLIBRARIES = libinfo.la libinfo_la_SOURCES = \ info-module.c \ - cc-info-panel.c \ - cc-info-panel.h + cc-info-panel.c \ + cc-info-panel.h \ + hostname-helper.c \ + hostname-helper.h libinfo_la_LIBADD = $(PANEL_LIBS) $(INFO_PANEL_LIBS) libinfo_la_LDFLAGS = $(PANEL_LDFLAGS) diff --git a/panels/info/hostname-helper.c b/panels/info/hostname-helper.c new file mode 100644 index 000000000..3225a8fd1 --- /dev/null +++ b/panels/info/hostname-helper.c @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2011 Red Hat, Inc + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "hostname-helper.h" + +static char * +allowed_chars (void) +{ + GString *s; + char i; + + s = g_string_new (NULL); + for (i = 'a'; i <= 'z'; i++) + g_string_append_c (s, i); + for (i = 'A'; i <= 'Z'; i++) + g_string_append_c (s, i); + for (i = '0'; i <= '9'; i++) + g_string_append_c (s, i); + g_string_append_c (s, '-'); + + return g_string_free (s, FALSE); +} + +static char * +remove_leading_dashes (char *input) +{ + char *start; + + for (start = input; *start && (*start == '-'); start++) + ; + + g_memmove (input, start, strlen (start) + 1); + + return input; +} + +static gboolean +is_empty (const char *input) +{ + if (input == NULL || + *input == '\0') + return TRUE; + return FALSE; +} + +static char * +remove_trailing_dashes (char *input) +{ + int len; + + len = strlen (input); + while (len--) { + if (input[len] == '-') + input[len] = '\0'; + else + break; + } + return input; +} + +static char * +remove_apostrophes (char *input) +{ + char *apo; + + while ((apo = strchr (input, '\'')) != NULL) + g_memmove (apo, apo + 1, strlen (apo)); + return input; +} + +static char * +remove_duplicate_dashes (char *input) +{ + char *dashes; + + while ((dashes = strstr (input, "--")) != NULL) + g_memmove (dashes, dashes + 1, strlen (dashes)); + return input; +} + +#define CHECK if (is_empty (result)) goto bail + +char * +pretty_hostname_to_static (const char *pretty, + gboolean for_display) +{ + char *result; + char *valid_chars; + + g_return_val_if_fail (pretty != NULL, NULL); + g_return_val_if_fail (g_utf8_validate (pretty, -1, NULL), NULL); + + g_debug ("Input: '%s'", pretty); + + /* Transform the pretty hostname to ASCII */ + result = g_convert (pretty, + -1, + "ASCII//TRANSLIT//IGNORE", + "UTF-8", + NULL, + NULL, + NULL); + g_debug ("\ttranslit: '%s'", result); + + CHECK; + + /* Remove apostrophes */ + result = remove_apostrophes (result); + g_debug ("\tapostrophes: '%s'", result); + + CHECK; + + /* Remove all the not-allowed chars */ + valid_chars = allowed_chars (); + result = g_strcanon (result, valid_chars, '-'); + g_free (valid_chars); + g_debug ("\tcanon: '%s'", result); + + CHECK; + + /* Remove the leading dashes */ + result = remove_leading_dashes (result); + g_debug ("\tleading: '%s'", result); + + CHECK; + + /* Remove trailing dashes */ + result = remove_trailing_dashes (result); + g_debug ("\ttrailing: '%s'", result); + + CHECK; + + /* Remove duplicate dashes */ + result = remove_duplicate_dashes (result); + g_debug ("\tduplicate: '%s'", result); + + CHECK; + + /* Lower case */ + if (!for_display) { + char *tmp; + + tmp = g_ascii_strdown (result, -1); + g_free (result); + result = tmp; + } + + return result; + +bail: + g_free (result); + return g_strdup ("localhost"); +} +#undef CHECK diff --git a/panels/info/hostname-helper.h b/panels/info/hostname-helper.h new file mode 100644 index 000000000..737bf5784 --- /dev/null +++ b/panels/info/hostname-helper.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2011 Red Hat, Inc + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +char *pretty_hostname_to_static (const char *pretty, + gboolean for_display); diff --git a/panels/info/test-hostname.c b/panels/info/test-hostname.c new file mode 100644 index 000000000..fc8afce89 --- /dev/null +++ b/panels/info/test-hostname.c @@ -0,0 +1,59 @@ +#include "config.h" + +#include +#include +#include + +#include "hostname-helper.h" + +struct { + char *input; + char *output_display; + char *output_real; +} tests[] = { + { "Lennart's PC", "Lennarts-PC", "lennarts-pc" }, + { "Müllers Computer", "Mullers-Computer", "mullers-computer" }, + { "Voran!", "Voran", "voran" }, + { "Es war einmal ein Männlein", "Es-war-einmal-ein-Mannlein", "es-war-einmal-ein-mannlein" }, + { "Jawoll. Ist doch wahr!", "Jawoll-Ist-doch-wahr", "jawoll-ist-doch-wahr" }, + { "レナート", "localhost", "localhost" }, + { "!!!", "localhost", "localhost" }, + { "...zack!!! zack!...", "zack-zack", "zack-zack" }, + { "Bãstien's computer... Foo-bar", "Bastiens-computer-Foo-bar", "bastiens-computer-foo-bar" }, + { "", "localhost", "localhost" }, +}; + +int main (int argc, char **argv) +{ + char *result; + guint i; + + setlocale (LC_ALL, ""); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + + /* FIXME: + * - Tests don't work in non-UTF-8 locales + * - They also fail in de_DE.UTF-8 because of "ü" -> "ue" conversions */ + + for (i = 0; i < G_N_ELEMENTS (tests); i++) { + result = pretty_hostname_to_static (tests[i].input, FALSE); + if (g_strcmp0 (result, tests[i].output_real) != 0) + g_error ("Result for '%s' doesn't match '%s' (got: '%s')", + tests[i].input, tests[i].output_real, result); + else + g_debug ("Result for '%s' matches '%s'", + tests[i].input, result); + g_free (result); + + result = pretty_hostname_to_static (tests[i].input, TRUE); + if (g_strcmp0 (result, tests[i].output_display) != 0) + g_error ("Result for '%s' doesn't match '%s' (got: '%s')", + tests[i].input, tests[i].output_display, result); + else + g_debug ("Result for '%s' matches '%s'", + tests[i].input, result); + g_free (result); + } + + return 0; +}