[network-manager-openvpn/th/ovpn-import-bgo761285: 5/10] utils: add _nm_utils_ascii_str_to_int64() from NetworkManager sources



commit a9993db9a4a9ca084e7bfc7fccf40bc271898cea
Author: Thomas Haller <thaller redhat com>
Date:   Fri Jan 29 10:28:11 2016 +0100

    utils: add _nm_utils_ascii_str_to_int64() from NetworkManager sources
    
    Copied from NetworkManager's "libnm-core/nm-utils.c".

 shared/utils.c |   79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 shared/utils.h |    2 +
 2 files changed, 81 insertions(+), 0 deletions(-)
---
diff --git a/shared/utils.c b/shared/utils.c
index 4f5a558..b777d9f 100644
--- a/shared/utils.c
+++ b/shared/utils.c
@@ -22,9 +22,11 @@
 #include "config.h"
 
 #include <string.h>
+#include <errno.h>
 
 #include "nm-default.h"
 #include "utils.h"
+#include "nm-macros-internal.h"
 
 gboolean
 is_pkcs12 (const char *filepath)
@@ -91,3 +93,80 @@ is_encrypted (const char *filename)
        return encrypted;
 }
 
+/*****************************************************************************/
+
+/* _nm_utils_ascii_str_to_int64:
+ *
+ * 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. 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
+ * (inclusive) or @fallback. Also, the parsing is rather strict, it does
+ * not allow for any unrecognized characters, except leading and trailing
+ * white space.
+ **/
+gint64
+_nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback)
+{
+       gint64 v;
+       size_t len;
+       char buf[64], *s, *str_free = NULL;
+
+       if (str) {
+               while (g_ascii_isspace (str[0]))
+                       str++;
+       }
+       if (!str || !str[0]) {
+               errno = EINVAL;
+               return fallback;
+       }
+
+       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;
+
+               nm_assert (len > 0 && len < strlen (str) && len == strlen (s));
+               nm_assert (!g_ascii_isspace (str[len-1]) && g_ascii_isspace (str[len]));
+               nm_assert (strncmp (str, s, len) == 0);
+
+               str = s;
+       }
+
+       errno = 0;
+       v = g_ascii_strtoll (str, &s, base);
+
+       if (errno != 0)
+               v = fallback;
+       else if (s[0] != 0) {
+               errno = EINVAL;
+               v = fallback;
+       } else if (v > max || v < min) {
+               errno = ERANGE;
+               v = fallback;
+       }
+
+       if (G_UNLIKELY (str_free))
+               g_free (str_free);
+       return v;
+}
+
+/*****************************************************************************/
+
diff --git a/shared/utils.h b/shared/utils.h
index fcdda44..4571a77 100644
--- a/shared/utils.h
+++ b/shared/utils.h
@@ -28,5 +28,7 @@ gboolean is_pkcs12 (const char *filepath);
 
 gboolean is_encrypted (const char *filename);
 
+gint64 _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback);
+
 #endif  /* UTILS_H */
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]