Merge branch 'th/bgo726287_cleanup_read_sysctl'

https://bugzilla.gnome.org/show_bug.cgi?id=726287

Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
Thomas Haller 2014-04-10 16:36:42 +02:00
commit 7ef622b447
9 changed files with 258 additions and 92 deletions

View file

@ -864,12 +864,13 @@ nm_utils_match_connection (GSList *connections,
*
* A wrapper for g_ascii_strtoll, that checks whether the whole string
* can be successfully converted to a number and is within a given
* range. On any error, @fallback will be returned and @errno will be set
* to a non-zero value. Check @errno for errors. Any trailing or leading
* (ascii) white space is ignored and the functions is locale independent.
* range. On any error, @fallback will be returned and %errno will be set
* to a non-zero value. On success, %errno will be set to zero, check %errno
* for errors. Any trailing or leading (ascii) white space is ignored and the
* functions is locale independent.
*
* The function is guaranteed to return a value between @min and @max
* (included) or @fallback. Also, the parsing is rather strict, it does
* (inclusive) or @fallback. Also, the parsing is rather strict, it does
* not allow for any unrecognized characters, except leading and trailing
* white space.
**/
@ -877,11 +878,11 @@ gint64
nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback)
{
gint64 v;
char *end;
char *str_free = NULL;
size_t len;
char buf[64], *s, *str_free = NULL;
if (str) {
while (str[0] && g_ascii_isspace (str[0]))
while (g_ascii_isspace (str[0]))
str++;
}
if (!str || !str[0]) {
@ -889,32 +890,48 @@ nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max
return fallback;
}
if (g_ascii_isspace (str[strlen (str) - 1])) {
str_free = g_strdup (str);
g_strstrip (str_free);
str = str_free;
len = strlen (str);
if (g_ascii_isspace (str[--len])) {
/* backward search the first non-ws character.
* We already know that str[0] is non-ws. */
while (g_ascii_isspace (str[--len]))
;
/* str[len] is now the last non-ws character... */
len++;
if (len >= sizeof (buf))
s = str_free = g_malloc (len + 1);
else
s = buf;
memcpy (s, str, len);
s[len] = 0;
/*
g_assert (len > 0 && len < strlen (str) && len == strlen (s));
g_assert (!g_ascii_isspace (str[len-1]) && g_ascii_isspace (str[len]));
g_assert (strncmp (str, s, len) == 0);
*/
str = s;
}
errno = 0;
v = g_ascii_strtoll (str, &end, base);
v = g_ascii_strtoll (str, &s, base);
if (errno != 0) {
g_free (str_free);
return fallback;
}
if (end[0] != 0) {
g_free (str_free);
if (errno != 0)
v = fallback;
else if (s[0] != 0) {
errno = EINVAL;
return fallback;
}
g_free (str_free);
if (v > max || v < min) {
v = fallback;
} else if (v > max || v < min) {
errno = ERANGE;
return fallback;
v = fallback;
}
if (G_UNLIKELY (str_free))
g_free (str_free);
return v;
}
@ -1045,9 +1062,44 @@ nm_utils_ip6_property_path (const char *ifname, const char *property)
static char path[sizeof (IPV6_PROPERTY_DIR) + IFNAMSIZ + 32];
int len;
ifname = ASSERT_VALID_PATH_COMPONENT (ifname);
property = ASSERT_VALID_PATH_COMPONENT (property);
len = g_snprintf (path, sizeof (path), IPV6_PROPERTY_DIR "%s/%s",
ifname, property);
g_assert (len < sizeof (path) - 1);
return path;
}
const char *
ASSERT_VALID_PATH_COMPONENT (const char *name)
{
const char *n;
if (name == NULL || name[0] == '\0')
goto fail;
if (name[0] == '.') {
if (name[1] == '\0')
goto fail;
if (name[1] == '.' && name[2] == '\0')
goto fail;
}
n = name;
do {
if (*n == '/')
goto fail;
} while (*(++n) != '\0');
return name;
fail:
if (name)
nm_log_err (LOGD_CORE, "Failed asserting path component: NULL");
else
nm_log_err (LOGD_CORE, "Failed asserting path component: \"%s\"", name);
g_assert_not_reached ();
g_return_val_if_reached ("XXXXX");
return "XXXXX";
}

View file

@ -108,6 +108,7 @@ gint64 nm_utils_get_monotonic_timestamp_us (void);
gint64 nm_utils_get_monotonic_timestamp_ms (void);
gint32 nm_utils_get_monotonic_timestamp_s (void);
const char *ASSERT_VALID_PATH_COMPONENT (const char *name) G_GNUC_WARN_UNUSED_RESULT;
const char *nm_utils_ip6_property_path (const char *ifname, const char *property);
#endif /* NETWORK_MANAGER_UTILS_H */

View file

@ -530,30 +530,19 @@ static gboolean
carrier_update_cb (gpointer user_data)
{
NMDeviceAdsl *self = NM_DEVICE_ADSL (user_data);
GError *error = NULL;
gboolean carrier = FALSE;
char *path, *contents;
int carrier;
char *path;
const char *iface;
gboolean success;
iface = nm_device_get_iface (NM_DEVICE (self));
path = g_strdup_printf ("/sys/class/atm/%s/carrier", iface);
success = g_file_get_contents (path, &contents, NULL, &error);
path = g_strdup_printf ("/sys/class/atm/%s/carrier",
ASSERT_VALID_PATH_COMPONENT (iface));
carrier = (int) nm_platform_sysctl_get_int_checked (path, 10, 0, 1, -1);
g_free (path);
if (!success) {
nm_log_dbg (LOGD_ADSL, "error reading %s: (%d) %s",
path,
error ? error->code : -1,
error && error->message ? error->message : "(unknown)");
g_clear_error (&error);
return TRUE;
}
carrier = (gboolean) atoi (contents);
g_free (contents);
nm_device_set_carrier (NM_DEVICE (self), carrier);
if (carrier != -1)
nm_device_set_carrier (NM_DEVICE (self), carrier);
return TRUE;
}
@ -576,16 +565,16 @@ nm_device_adsl_new (const char *udi,
}
static int
get_atm_index (const char *iface, GError **error)
get_atm_index (const char *iface)
{
char *path, *contents;
int idx = -1;
char *path;
int idx;
path = g_strdup_printf ("/sys/class/atm/%s/atmindex", iface);
if (g_file_get_contents (path, &contents, NULL, error))
idx = atoi (contents);
path = g_strdup_printf ("/sys/class/atm/%s/atmindex",
ASSERT_VALID_PATH_COMPONENT (iface));
idx = (int) nm_platform_sysctl_get_int_checked (path, 10, 0, G_MAXINT, -1);
g_free (path);
g_free (contents);
return idx;
}
@ -596,7 +585,6 @@ constructor (GType type,
{
GObject *object;
NMDeviceAdslPrivate *priv;
GError *error = NULL;
object = G_OBJECT_CLASS (nm_device_adsl_parent_class)->constructor (type,
n_construct_params,
@ -606,12 +594,10 @@ constructor (GType type,
priv = NM_DEVICE_ADSL_GET_PRIVATE (object);
priv->atm_index = get_atm_index (nm_device_get_iface (NM_DEVICE (object)), &error);
priv->atm_index = get_atm_index (nm_device_get_iface (NM_DEVICE (object)));
if (priv->atm_index < 0) {
nm_log_dbg (LOGD_ADSL, "error reading ATM device index: (%d) %s",
error ? error->code : -1,
error && error->message ? error->message : "(unknown)");
g_clear_error (&error);
nm_log_err (LOGD_ADSL, "(%s): error reading ATM device index",
nm_device_get_iface (NM_DEVICE (object)));
g_object_unref (object);
return NULL;
} else {

View file

@ -168,7 +168,8 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
transport_mode = nm_setting_infiniband_get_transport_mode (s_infiniband);
mode_path = g_strdup_printf ("/sys/class/net/%s/mode", nm_device_get_iface (dev));
mode_path = g_strdup_printf ("/sys/class/net/%s/mode",
ASSERT_VALID_PATH_COMPONENT (nm_device_get_iface (dev)));
if (!g_file_test (mode_path, G_FILE_TEST_EXISTS)) {
g_free (mode_path);
@ -312,7 +313,7 @@ update_connection (NMDevice *device, NMConnection *connection)
gconstpointer mac = nm_device_get_hw_address (device, &maclen);
static const guint8 null_mac[INFINIBAND_ALEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
GByteArray *array;
char *mode_path, *contents;
char *mode_path, *contents = NULL;
const char *transport_mode = "datagram";
if (!s_infiniband) {
@ -327,16 +328,18 @@ update_connection (NMDevice *device, NMConnection *connection)
g_byte_array_unref (array);
}
mode_path = g_strdup_printf ("/sys/class/net/%s/mode", nm_device_get_iface (device));
if (g_file_get_contents (mode_path, &contents, NULL, NULL)) {
mode_path = g_strdup_printf ("/sys/class/net/%s/mode",
ASSERT_VALID_PATH_COMPONENT (nm_device_get_iface (device)));
contents = nm_platform_sysctl_get (mode_path);
g_free (mode_path);
if (contents) {
if (strstr (contents, "datagram"))
transport_mode = "datagram";
else if (strstr (contents, "connected"))
transport_mode = "connected";
g_free (contents);
}
g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_TRANSPORT_MODE, transport_mode, NULL);
g_free (mode_path);
g_free (contents);
}
static gboolean

View file

@ -230,8 +230,10 @@ nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self)
const char *str_state = NULL;
if ( priv->ipw_rfkill_path
&& g_file_get_contents (priv->ipw_rfkill_path, &contents, NULL, NULL)) {
contents = g_strstrip (contents);
&& (contents = nm_platform_sysctl_get (priv->ipw_rfkill_path))) {
if (strlen (contents) != 1)
contents[0] = 0;
/* 0 - RF kill not enabled
* 1 - SW based RF kill active (sysfs)
@ -331,7 +333,7 @@ constructor (GType type,
* don't have to poll.
*/
priv->ipw_rfkill_path = g_strdup_printf ("/sys/class/net/%s/device/rf_kill",
nm_device_get_iface (NM_DEVICE (self)));
ASSERT_VALID_PATH_COMPONENT (nm_device_get_iface (NM_DEVICE (self))));
if (!g_file_test (priv->ipw_rfkill_path, G_FILE_TEST_IS_REGULAR)) {
g_free (priv->ipw_rfkill_path);
priv->ipw_rfkill_path = NULL;

View file

@ -1602,7 +1602,7 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value)
g_assert (g_str_has_prefix (path, "/proc/sys/")
|| g_str_has_prefix (path, "/sys/"));
/* Don't write to suspicious locations */
g_assert (!strstr (path, "/.."));
g_assert (!strstr (path, "/../"));
fd = open (path, O_WRONLY | O_TRUNC);
if (fd == -1) {
@ -1701,7 +1701,7 @@ sysctl_get (NMPlatform *platform, const char *path)
g_assert (g_str_has_prefix (path, "/proc/sys/")
|| g_str_has_prefix (path, "/sys/"));
/* Don't write to suspicious locations */
g_assert (!strstr (path, "/.."));
g_assert (!strstr (path, "/../"));
if (!g_file_get_contents (path, &contents, NULL, &error)) {
/* We assume FAILED means EOPNOTSUP */
@ -2153,6 +2153,8 @@ link_get_physical_port_id (NMPlatform *platform, int ifindex)
if (!ifname)
return NULL;
ifname = ASSERT_VALID_PATH_COMPONENT (ifname);
path = g_strdup_printf ("/sys/class/net/%s/phys_port_id", ifname);
id = sysctl_get (platform, path);
g_free (path);
@ -2266,7 +2268,10 @@ link_option_path (int master, const char *category, const char *option)
if (!name || !category || !option)
return NULL;
return g_strdup_printf ("/sys/class/net/%s/%s/%s", name, category, option);
return g_strdup_printf ("/sys/class/net/%s/%s/%s",
ASSERT_VALID_PATH_COMPONENT (name),
ASSERT_VALID_PATH_COMPONENT (category),
ASSERT_VALID_PATH_COMPONENT (option));
}
static gboolean
@ -2352,7 +2357,7 @@ infiniband_partition_add (NMPlatform *platform, int parent, int p_key)
parent_name = nm_platform_link_get_name (parent);
g_return_val_if_fail (parent_name != NULL, FALSE);
path = g_strdup_printf ("/sys/class/net/%s/create_child", parent_name);
path = g_strdup_printf ("/sys/class/net/%s/create_child", ASSERT_VALID_PATH_COMPONENT (parent_name));
id = g_strdup_printf ("0x%04x", p_key);
success = nm_platform_sysctl_set (path, id);
g_free (id);
@ -2412,6 +2417,7 @@ tun_get_properties (NMPlatform *platform, int ifindex, NMPlatformTunProperties *
ifname = nm_platform_link_get_name (ifindex);
if (!ifname || !nm_utils_iface_valid_name (ifname))
return FALSE;
ifname = ASSERT_VALID_PATH_COMPONENT (ifname);
path = g_strdup_printf ("/sys/class/net/%s/owner", ifname);
val = nm_platform_sysctl_get (path);

View file

@ -274,11 +274,32 @@ nm_platform_sysctl_get (const char *path)
* as decimal integer.
*
* Returns: contents of the sysctl file parsed as s32 integer, or
* @fallback on error. Also, on error, @errno will be set to a non-zero
* value.
* @fallback on error. On error, %errno will be set to a non-zero
* value, on success %errno will be set to zero.
*/
gint32
nm_platform_sysctl_get_int32 (const char *path, gint32 fallback)
{
return nm_platform_sysctl_get_int_checked (path, 10, G_MININT32, G_MAXINT32, fallback);
}
/**
* nm_platform_sysctl_get_int_checked:
* @path: Absolute path to sysctl
* @base: base of numeric conversion
* @min: minimal value that is still valid
* @max: maximal value that is still valid
* @fallback: default value, if the content of path could not be read
* as valid integer.
*
* Returns: contents of the sysctl file parsed as s64 integer, or
* @fallback on error. On error, %errno will be set to a non-zero
* value. On success, %errno will be set to zero. The returned value
* will always be in the range between @min and @max
* (inclusive) or @fallback.
*/
gint64
nm_platform_sysctl_get_int_checked (const char *path, guint base, gint64 min, gint64 max, gint64 fallback)
{
char *value = NULL;
gint32 ret;
@ -293,7 +314,7 @@ nm_platform_sysctl_get_int32 (const char *path, gint32 fallback)
return fallback;
}
ret = nm_utils_ascii_str_to_int64 (value, 10, G_MININT32, G_MAXINT32, fallback);
ret = nm_utils_ascii_str_to_int64 (value, base, min, max, fallback);
g_free (value);
return ret;
}

View file

@ -417,6 +417,7 @@ void nm_platform_query_devices (void);
gboolean nm_platform_sysctl_set (const char *path, const char *value);
char *nm_platform_sysctl_get (const char *path);
gint32 nm_platform_sysctl_get_int32 (const char *path, gint32 fallback);
gint64 nm_platform_sysctl_get_int_checked (const char *path, guint base, gint64 min, gint64 max, gint64 fallback);
GArray *nm_platform_link_get_all (void);
gboolean nm_platform_dummy_add (const char *name);

View file

@ -27,38 +27,132 @@
static void
test_nm_utils_ascii_str_to_int64_do (const char *str, guint base, gint64 min,
gint64 max, gint64 fallback, int exp_errno,
gint64 exp_val)
test_nm_utils_ascii_str_to_int64_check (const char *str, guint base, gint64 min,
gint64 max, gint64 fallback, int exp_errno,
gint64 exp_val)
{
gint64 v;
errno = 0;
errno = 1;
v = nm_utils_ascii_str_to_int64 (str, base, min, max, fallback);
g_assert_cmpint (errno, ==, exp_errno);
g_assert_cmpint (v, ==, exp_val);
}
static void
test_nm_utils_ascii_str_to_int64_do (const char *str, guint base, gint64 min,
gint64 max, gint64 fallback, int exp_errno,
gint64 exp_val)
{
const char *sign = "";
const char *val;
static const char *whitespaces[] = {
"",
" ",
"\r\n\t",
" \r\n\t ",
" \r\n\t \t\r\n\t",
NULL,
};
static const char *nulls[] = {
"",
"0",
"00",
"0000",
"0000000000000000",
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
NULL,
};
const char **ws_pre, **ws_post, **null;
int i;
if (str == NULL || exp_errno != 0) {
test_nm_utils_ascii_str_to_int64_check (str, base, min, max, fallback, exp_errno, exp_val);
return;
}
if (strncmp (str, "-", 1) == 0)
sign = "-";
val = str + strlen (sign);
for (ws_pre = whitespaces; *ws_pre; ws_pre++) {
for (ws_post = whitespaces; *ws_post; ws_post++) {
for (null = nulls; *null; null++) {
for (i = 0; ; i++) {
char *s;
const char *str_base = "";
if (base == 16) {
if (i == 1)
str_base = "0x";
else if (i > 1)
break;
} else if (base == 8) {
if (i == 1)
str_base = "0";
else if (i > 1)
break;
} else if (base == 0) {
if (i > 0)
break;
/* with base==0, a leading zero would be interpreted as octal. Only test without *null */
if ((*null)[0])
break;
} else {
if (i > 0)
break;
}
s = g_strdup_printf ("%s%s%s%s%s%s", *ws_pre, sign, str_base, *null, val, *ws_post);
test_nm_utils_ascii_str_to_int64_check (s, base, min, max, fallback, exp_errno, exp_val);
g_free (s);
}
}
}
}
}
static void
test_nm_utils_ascii_str_to_int64 (void)
{
test_nm_utils_ascii_str_to_int64_do ("4711", 10, 0, 10000, -1, 0, 4711);
test_nm_utils_ascii_str_to_int64_do ("", 10, 0, 10000, -1, EINVAL, -1);
test_nm_utils_ascii_str_to_int64_do (NULL, 10, 0, 10000, -1, EINVAL, -1);
test_nm_utils_ascii_str_to_int64_do (" 1x ", 10, 0, 10000, -1, EINVAL, -1);
test_nm_utils_ascii_str_to_int64_do (" 10000 ", 10, 0, 10000, -1, 0, 10000);
test_nm_utils_ascii_str_to_int64_do (" 10001 ", 10, 0, 10000, -1, ERANGE, -1);
test_nm_utils_ascii_str_to_int64_do (" 0xFF ", 16, 0, 10000, -1, 0, 255);
test_nm_utils_ascii_str_to_int64_do (" FF ", 16, 0, 10000, -1, 0, 255);
test_nm_utils_ascii_str_to_int64_do (" FF ", 10, 0, 10000, -2, EINVAL, -2);
test_nm_utils_ascii_str_to_int64_do (" 9223372036854775807 ", 10, 0, G_MAXINT64, -2, 0, G_MAXINT64);
test_nm_utils_ascii_str_to_int64_do (" 0x7FFFFFFFFFFFFFFF ", 16, 0, G_MAXINT64, -2, 0, G_MAXINT64);
test_nm_utils_ascii_str_to_int64_do (" 7FFFFFFFFFFFFFFF ", 16, 0, G_MAXINT64, -2, 0, G_MAXINT64);
test_nm_utils_ascii_str_to_int64_do (" 9223372036854775808 ", 10, 0, G_MAXINT64, -2, ERANGE, -2);
test_nm_utils_ascii_str_to_int64_do (" -9223372036854775808 ", 10, G_MININT64, 0, -2, 0, G_MININT64);
test_nm_utils_ascii_str_to_int64_do (" -9223372036854775808 ", 10, G_MININT64+1, 0, -2, ERANGE, -2);
test_nm_utils_ascii_str_to_int64_do (" -9223372036854775809 ", 10, G_MININT64, 0, -2, ERANGE, -2);
test_nm_utils_ascii_str_to_int64_do ("\r\n\t10000\t\n\t\n", 10, 0, 10000, -1, 0, 10000);
test_nm_utils_ascii_str_to_int64_do ("", 10, 0, 10000, -1, EINVAL, -1);
test_nm_utils_ascii_str_to_int64_do ("1x", 10, 0, 10000, -1, EINVAL, -1);
test_nm_utils_ascii_str_to_int64_do ("4711", 10, 0, 10000, -1, 0, 4711);
test_nm_utils_ascii_str_to_int64_do ("10000", 10, 0, 10000, -1, 0, 10000);
test_nm_utils_ascii_str_to_int64_do ("10001", 10, 0, 10000, -1, ERANGE, -1);
test_nm_utils_ascii_str_to_int64_do ("FF", 16, 0, 10000, -1, 0, 255);
test_nm_utils_ascii_str_to_int64_do ("FF", 10, 0, 10000, -2, EINVAL, -2);
test_nm_utils_ascii_str_to_int64_do ("9223372036854775807", 10, 0, G_MAXINT64, -2, 0, G_MAXINT64);
test_nm_utils_ascii_str_to_int64_do ("7FFFFFFFFFFFFFFF", 16, 0, G_MAXINT64, -2, 0, G_MAXINT64);
test_nm_utils_ascii_str_to_int64_do ("9223372036854775808", 10, 0, G_MAXINT64, -2, ERANGE, -2);
test_nm_utils_ascii_str_to_int64_do ("-9223372036854775808", 10, G_MININT64, 0, -2, 0, G_MININT64);
test_nm_utils_ascii_str_to_int64_do ("-9223372036854775808", 10, G_MININT64+1, 0, -2, ERANGE, -2);
test_nm_utils_ascii_str_to_int64_do ("-9223372036854775809", 10, G_MININT64, 0, -2, ERANGE, -2);
test_nm_utils_ascii_str_to_int64_do ("1.0", 10, 1, 1, -1, EINVAL, -1);
test_nm_utils_ascii_str_to_int64_do ("1x0", 16, -10, 10, -100, EINVAL, -100);
test_nm_utils_ascii_str_to_int64_do ("0", 16, -10, 10, -100, 0, 0);
test_nm_utils_ascii_str_to_int64_do ("10001111", 2, -1000, 1000, -100000, 0, 0x8F);
test_nm_utils_ascii_str_to_int64_do ("-10001111", 2, -1000, 1000, -100000, 0, -0x8F);
test_nm_utils_ascii_str_to_int64_do ("1111111", 2, G_MININT64, G_MAXINT64, -1, 0, 0x7F);
test_nm_utils_ascii_str_to_int64_do ("111111111111111", 2, G_MININT64, G_MAXINT64, -1, 0, 0x7FFF);
test_nm_utils_ascii_str_to_int64_do ("11111111111111111111111111111111111111111111111", 2, G_MININT64, G_MAXINT64, -1, 0, 0x7FFFFFFFFFFF);
test_nm_utils_ascii_str_to_int64_do ("111111111111111111111111111111111111111111111111111111111111111", 2, G_MININT64, G_MAXINT64, -1, 0, 0x7FFFFFFFFFFFFFFF);
test_nm_utils_ascii_str_to_int64_do ("100000000000000000000000000000000000000000000000000000000000000", 2, G_MININT64, G_MAXINT64, -1, 0, 0x4000000000000000);
test_nm_utils_ascii_str_to_int64_do ("1000000000000000000000000000000000000000000000000000000000000000", 2, G_MININT64, G_MAXINT64, -1, ERANGE, -1);
test_nm_utils_ascii_str_to_int64_do ("-100000000000000000000000000000000000000000000000000000000000000", 2, G_MININT64, G_MAXINT64, -1, 0, -0x4000000000000000);
test_nm_utils_ascii_str_to_int64_do ("111111111111111111111111111111111111111111111111111111111111111", 2, G_MININT64, G_MAXINT64, -1, 0, 0x7FFFFFFFFFFFFFFF);
test_nm_utils_ascii_str_to_int64_do ("-100000000000000000000000000000000000000000000000000000000000000", 2, G_MININT64, G_MAXINT64, -1, 0, -0x4000000000000000);
test_nm_utils_ascii_str_to_int64_do ("0x70", 10, G_MININT64, G_MAXINT64, -1, EINVAL, -1);
test_nm_utils_ascii_str_to_int64_do ("4711", 0, G_MININT64, G_MAXINT64, -1, 0, 4711);
test_nm_utils_ascii_str_to_int64_do ("04711", 0, G_MININT64, G_MAXINT64, -1, 0, 04711);
test_nm_utils_ascii_str_to_int64_do ("0x4711", 0, G_MININT64, G_MAXINT64, -1, 0, 0x4711);
test_nm_utils_ascii_str_to_int64_do ("080", 0, G_MININT64, G_MAXINT64, -1, EINVAL, -1);
test_nm_utils_ascii_str_to_int64_do ("070", 0, G_MININT64, G_MAXINT64, -1, 0, 7*8);
test_nm_utils_ascii_str_to_int64_do ("0x70", 0, G_MININT64, G_MAXINT64, -1, 0, 0x70);
}
/* Reference implementation for nm_utils_ip6_address_clear_host_address.