diff --git a/.gitignore b/.gitignore index a2de16f61e..89a3fec76b 100644 --- a/.gitignore +++ b/.gitignore @@ -182,6 +182,7 @@ test-*.trs /libnm/nm-settings-docs.xml /libnm/nm-settings-docs-overrides.xml /libnm/nm-settings-keyfile-docs.xml +/libnm/tests/test-general /libnm/tests/test-nm-client /libnm/tests/test-remote-settings-client /libnm/tests/test-secret-agent diff --git a/Makefile.am b/Makefile.am index 32b6ba65f8..1bf3e96d26 100644 --- a/Makefile.am +++ b/Makefile.am @@ -737,6 +737,7 @@ libnm_lib_h_pub_nointrospect = \ libnm_lib_h_pub_mkenums = \ libnm/nm-enum-types.h libnm_lib_h_priv = \ + libnm/nm-libnm-utils.h \ libnm/nm-dbus-helpers.h \ libnm/nm-device-private.h \ libnm/nm-dhcp4-config.h \ @@ -793,6 +794,14 @@ libnm_lib_c_real = \ libnm_lib_c_mkenums = \ libnm/nm-enum-types.c +libnm_lib_cppflags = \ + $(dflt_cppflags_libnm_core) \ + -I$(srcdir)/libnm \ + -I$(builddir)/libnm \ + -DG_LOG_DOMAIN=\""libnm"\" \ + -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB \ + -DNMRUNDIR=\"$(nmrundir)\" + libnminclude_HEADERS += \ $(libnm_lib_h_pub_real) \ $(libnm_lib_h_pub_nointrospect) @@ -802,6 +811,23 @@ nodist_libnminclude_HEADERS += \ ############################################################################### +lib_LTLIBRARIES += libnm/libnm-utils.la + +libnm_libnm_utils_la_CPPFLAGS = \ + $(libnm_lib_cppflags) + +libnm_libnm_utils_la_SOURCES = \ + libnm/nm-libnm-utils.c + +libnm_libnm_utils_la_LIBADD = \ + libnm-core/libnm-core.la \ + introspection/libnmdbus.la \ + $(GLIB_LIBS) + +$(libnm_libnm_utils_la_OBJECTS) : $(libnm_lib_h_pub_mkenums) + +############################################################################### + lib_LTLIBRARIES += libnm/libnm.la GLIB_GENERATED += \ @@ -820,13 +846,8 @@ $(libnm_libnm_la_OBJECTS): $(libnm_lib_h_pub_mkenum $(libnm_tests_libnm_vpn_plugin_utils_test_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) libnm_libnm_la_CPPFLAGS = \ - $(dflt_cppflags_libnm_core) \ - -I$(srcdir)/libnm \ - -I$(builddir)/libnm \ - $(LIBUDEV_CFLAGS) \ - -DG_LOG_DOMAIN=\""libnm"\" \ - -DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB \ - -DNMRUNDIR=\"$(nmrundir)\" + $(libnm_lib_cppflags) \ + $(LIBUDEV_CFLAGS) libnm_libnm_la_SOURCES = \ $(libnm_lib_h_pub_real) \ @@ -844,6 +865,7 @@ EXTRA_libnm_libnm_la_DEPENDENCIES = \ libnm_libnm_la_LIBADD = \ libnm-core/libnm-core.la \ introspection/libnmdbus.la \ + libnm/libnm-utils.la \ $(DL_LIBS) \ $(GLIB_LIBS) \ $(UUID_LIBS) \ @@ -950,6 +972,7 @@ EXTRA_DIST += \ ############################################################################### libnm_tests_programs = \ + libnm/tests/test-general \ libnm/tests/test-nm-client \ libnm/tests/test-remote-settings-client \ libnm/tests/test-secret-agent @@ -967,10 +990,14 @@ libnm_tests_ldadd = \ libnm/libnm.la \ $(GLIB_LIBS) +libnm_tests_test_general_CPPFLAGS = $(libnm_tests_cppflags) libnm_tests_test_nm_client_CPPFLAGS = $(libnm_tests_cppflags) libnm_tests_test_remote_settings_client_CPPFLAGS = $(libnm_tests_cppflags) libnm_tests_test_secret_agent_CPPFLAGS = $(libnm_tests_cppflags) +libnm_tests_test_general_SOURCES = \ + libnm/tests/test-general.c + libnm_tests_test_nm_client_SOURCES = \ shared/nm-test-utils-impl.c \ shared/nm-test-libnm-utils.h \ @@ -986,10 +1013,14 @@ libnm_tests_test_secret_agent_SOURCES = \ shared/nm-test-libnm-utils.h \ libnm/tests/test-secret-agent.c +libnm_tests_test_general_LDADD = \ + libnm/libnm-utils.la \ + $(libnm_tests_ldadd) libnm_tests_test_nm_client_LDADD = $(libnm_tests_ldadd) libnm_tests_test_remote_settings_client_LDADD = $(libnm_tests_ldadd) libnm_tests_test_secret_agent_LDADD = $(libnm_tests_ldadd) +$(libnm_tests_test_general_OBJECTS): $(libnm_core_lib_h_pub_mkenums) $(libnm_tests_test_nm_client_OBJECTS): $(libnm_core_lib_h_pub_mkenums) $(libnm_tests_test_remote_settings_client_OBJECTS): $(libnm_core_lib_h_pub_mkenums) $(libnm_tests_test_secret_agent_OBJECTS): $(libnm_core_lib_h_pub_mkenums) diff --git a/libnm/nm-device.c b/libnm/nm-device.c index 7e8feb1cd5..969d08a620 100644 --- a/libnm/nm-device.c +++ b/libnm/nm-device.c @@ -26,6 +26,7 @@ #include #include +#include "nm-libnm-utils.h" #include "nm-dbus-interface.h" #include "nm-active-connection.h" #include "nm-device-bt.h" @@ -1431,138 +1432,6 @@ nm_device_get_vendor (NMDevice *device) return priv->vendor; } -static char * -fixup_desc_string (const char *desc) -{ - static const char *const IGNORED_PHRASES[] = { - "Multiprotocol MAC/baseband processor", - "Wireless LAN Controller", - "Wireless LAN Adapter", - "Wireless Adapter", - "Network Connection", - "Wireless Cardbus Adapter", - "Wireless CardBus Adapter", - "54 Mbps Wireless PC Card", - "Wireless PC Card", - "Wireless PC", - "PC Card with XJACK(r) Antenna", - "Wireless cardbus", - "Wireless LAN PC Card", - "Technology Group Ltd.", - "Communication S.p.A.", - "Business Mobile Networks BV", - "Mobile Broadband Minicard Composite Device", - "Mobile Communications AB", - "(PC-Suite Mode)", - }; - static const char *const IGNORED_WORDS[] = { - "Semiconductor", - "Components", - "Corporation", - "Communications", - "Company", - "Corp.", - "Corp", - "Co.", - "Inc.", - "Inc", - "Incorporated", - "Ltd.", - "Limited.", - "Intel?", - "chipset", - "adapter", - "[hex]", - "NDIS", - "Module", - }; - char *desc_full; - char *p, *q; - int i; - - if (!desc || !desc[0]) - return NULL; - - /* restore original non-UTF-8-safe text. */ - desc_full = nm_utils_str_utf8safe_unescape_cp (desc); - - /* replace all invalid UTF-8 bytes with space. */ - p = desc_full; - while (!g_utf8_validate (p, -1, (const char **) &q)) { - /* the byte is invalid UTF-8. Replace it with space and proceed. */ - *q = ' '; - p = q + 1; - } - - /* replace '_', ',', and ASCII controll characters with space. */ - for (p = desc_full; p[0]; p++) { - if ( NM_IN_SET (*p, '_', ',') - || *p < ' ') - *p = ' '; - } - - /* Attempt to shorten ID by ignoring certain phrases */ - for (i = 0; i < G_N_ELEMENTS (IGNORED_PHRASES); i++) { - p = strstr (desc_full, IGNORED_PHRASES[i]); - if (p) { - const char *eow = &p[strlen (IGNORED_PHRASES[i])]; - - memmove (p, eow, strlen (eow) + 1); /* +1 for the \0 */ - } - } - - /* Attempt to shorten ID by ignoring certain individual words. - * - word-split the description at spaces - * - coalesce multiple spaces - * - skip over IGNORED_WORDS */ - p = desc_full; - q = desc_full; - for (;;) { - char *eow; - gsize l; - - /* skip leading spaces. */ - while (p[0] == ' ') - p++; - - if (!p[0]) - break; - - /* split leading word on first space */ - eow = strchr (p, ' '); - if (eow) - *eow = '\0'; - - if (nm_utils_strv_find_first ((char **) IGNORED_WORDS, - G_N_ELEMENTS (IGNORED_WORDS), - p) < 0) - goto next; - - l = strlen (p); - if (q != p) { - if (q != desc_full) - *q++ = ' '; - memmove (q, p, l); - } - q += l; - -next: - if (!eow) - break; - p = eow + 1; - } - - *q++ = '\0'; - - if (!desc_full[0]) { - g_free (desc_full); - return NULL; - } - - nm_assert (g_utf8_validate (desc_full, -1, NULL)); - return desc_full; -} - static void ensure_description (NMDevice *device) { @@ -1570,7 +1439,7 @@ ensure_description (NMDevice *device) GParamSpec *name_prop; gs_free char *short_product = NULL; - priv->short_vendor = nm_str_realloc (fixup_desc_string (nm_device_get_vendor (device))); + priv->short_vendor = nm_str_realloc (nm_utils_fixup_desc_string (nm_device_get_vendor (device))); /* Grab device's preferred name, if any */ name_prop = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (device)), "name"); @@ -1582,7 +1451,7 @@ ensure_description (NMDevice *device) } if ( !priv->short_vendor - || !(short_product = fixup_desc_string (nm_device_get_product (device)))) { + || !(short_product = nm_utils_fixup_desc_string (nm_device_get_product (device)))) { priv->description = g_strdup (nm_device_get_iface (device) ?: ""); return; } diff --git a/libnm/nm-libnm-utils.c b/libnm/nm-libnm-utils.c new file mode 100644 index 0000000000..fbbfe2c552 --- /dev/null +++ b/libnm/nm-libnm-utils.c @@ -0,0 +1,162 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2017 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-libnm-utils.h" + +/*****************************************************************************/ + +char * +nm_utils_fixup_desc_string (const char *desc) +{ + static const char *const IGNORED_PHRASES[] = { + "Multiprotocol MAC/baseband processor", + "Wireless LAN Controller", + "Wireless LAN Adapter", + "Wireless Adapter", + "Network Connection", + "Wireless Cardbus Adapter", + "Wireless CardBus Adapter", + "54 Mbps Wireless PC Card", + "Wireless PC Card", + "Wireless PC", + "PC Card with XJACK(r) Antenna", + "Wireless cardbus", + "Wireless LAN PC Card", + "Technology Group Ltd.", + "Communication S.p.A.", + "Business Mobile Networks BV", + "Mobile Broadband Minicard Composite Device", + "Mobile Communications AB", + "(PC-Suite Mode)", + }; + static const char *const IGNORED_WORDS[] = { + "Semiconductor", + "Components", + "Corporation", + "Communications", + "Company", + "Corp.", + "Corp", + "Co.", + "Inc.", + "Inc", + "Incorporated", + "Ltd.", + "Limited.", + "Intel?", + "chipset", + "adapter", + "[hex]", + "NDIS", + "Module", + }; + char *desc_full; + char *p, *q; + int i; + + if (!desc || !desc[0]) + return NULL; + + /* restore original non-UTF-8-safe text. */ + desc_full = nm_utils_str_utf8safe_unescape_cp (desc); + + /* replace all invalid UTF-8 bytes with space. */ + p = desc_full; + while (!g_utf8_validate (p, -1, (const char **) &q)) { + /* the byte is invalid UTF-8. Replace it with space and proceed. */ + *q = ' '; + p = q + 1; + } + + /* replace '_', ',', and ASCII controll characters with space. */ + for (p = desc_full; p[0]; p++) { + if ( NM_IN_SET (*p, '_', ',') + || *p < ' ') + *p = ' '; + } + + /* Attempt to shorten ID by ignoring certain phrases */ + for (i = 0; i < G_N_ELEMENTS (IGNORED_PHRASES); i++) { + p = strstr (desc_full, IGNORED_PHRASES[i]); + if (p) { + const char *eow = &p[strlen (IGNORED_PHRASES[i])]; + + /* require that the phrase is delimited by space, or + * at the beginning or end of the description. */ + if ( (p == desc_full || p[-1] == ' ') + && NM_IN_SET (eow[0], '\0', ' ')) + memmove (p, eow, strlen (eow) + 1); /* +1 for the \0 */ + } + } + + /* Attempt to shorten ID by ignoring certain individual words. + * - word-split the description at spaces + * - coalesce multiple spaces + * - skip over IGNORED_WORDS */ + p = desc_full; + q = desc_full; + for (;;) { + char *eow; + gsize l; + + /* skip leading spaces. */ + while (p[0] == ' ') + p++; + + if (!p[0]) + break; + + /* split leading word on first space */ + eow = strchr (p, ' '); + if (eow) + *eow = '\0'; + + if (nm_utils_strv_find_first ((char **) IGNORED_WORDS, + G_N_ELEMENTS (IGNORED_WORDS), + p) >= 0) + goto next; + + l = strlen (p); + if (q != p) { + if (q != desc_full) + *q++ = ' '; + memmove (q, p, l); + } + q += l; + +next: + if (!eow) + break; + p = eow + 1; + } + + *q++ = '\0'; + + if (!desc_full[0]) { + g_free (desc_full); + return NULL; + } + + nm_assert (g_utf8_validate (desc_full, -1, NULL)); + return desc_full; +} diff --git a/libnm/nm-libnm-utils.h b/libnm/nm-libnm-utils.h new file mode 100644 index 0000000000..4a5a361c51 --- /dev/null +++ b/libnm/nm-libnm-utils.h @@ -0,0 +1,26 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2017 Red Hat, Inc. + */ + +#ifndef __NM_LIBNM_UTILS_H__ +#define __NM_LIBNM_UTILS_H__ + +char *nm_utils_fixup_desc_string (const char *desc); + +#endif /* __NM_LIBNM_UTILS_H__ */ diff --git a/libnm/tests/test-general.c b/libnm/tests/test-general.c new file mode 100644 index 0000000000..7e0b7bb740 --- /dev/null +++ b/libnm/tests/test-general.c @@ -0,0 +1,69 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT SC 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2017 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-libnm-utils.h" + +#include "nm-utils/nm-test-utils.h" + +/*****************************************************************************/ + +static void +do_test_fixup_desc_string (const char *desc, const char *expected) +{ + gs_free char *result = NULL; + + result = nm_utils_fixup_desc_string (desc); + g_assert_cmpstr (result, ==, expected); +} + +#define do_test_fixup_desc_string_same(desc) (do_test_fixup_desc_string (""desc"", ""desc"")) + +static void +test_fixup_desc_string (void) +{ + do_test_fixup_desc_string (NULL, NULL); + do_test_fixup_desc_string ("", NULL); + do_test_fixup_desc_string_same ("a"); + do_test_fixup_desc_string_same ("a b"); + do_test_fixup_desc_string ("a b ", "a b"); + do_test_fixup_desc_string (" a bbc ", "a bbc"); + do_test_fixup_desc_string (" a \xcc bbc ", "a bbc"); + do_test_fixup_desc_string (" a\xcc bbc ", "a bbc"); + do_test_fixup_desc_string (" a\xcc""bbc Wireless PC", "a bbc"); + do_test_fixup_desc_string (" a\xcc""bbc Wireless PC ", "a bbc"); + do_test_fixup_desc_string (" a\xcc""bbcWireless PC ", "a bbcWireless PC"); + do_test_fixup_desc_string (" a\xcc""bbc Wireless PCx", "a bbc Wireless PCx"); + do_test_fixup_desc_string (" a\xcc""bbc Inc Wireless PC ", "a bbc"); +} + +/*****************************************************************************/ + +NMTST_DEFINE (); + +int main (int argc, char **argv) +{ + nmtst_init (&argc, &argv, TRUE); + + g_test_add_func ("/libnm/general/fixup_desc_string", test_fixup_desc_string); + + return g_test_run (); +}