Add local implementation of asprintf() for Solaris 10
authorDavid Woodhouse <David.Woodhouse@intel.com>
Wed, 18 Apr 2012 12:35:42 +0000 (13:35 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Wed, 18 Apr 2012 12:35:42 +0000 (13:35 +0100)
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
configure.ac
http.c
openconnect-internal.h

index 6fc731f..c32ca78 100644 (file)
@@ -108,6 +108,34 @@ case $host_os in
     ;;
 esac
 
+AC_CHECK_FUNC(strcasestr, [AC_DEFINE(HAVE_STRCASESTR, 1)], [])
+need_vacopy=no
+AC_CHECK_FUNC(asprintf, [AC_DEFINE(HAVE_ASPRINTF, 1)], [need_vacopy=yes])
+if test "$need_vacopy" = "yes"; then
+  AC_MSG_CHECKING([for va_copy])
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([
+       #include <stdarg.h>
+       va_list a;],[
+       va_list b;
+       va_copy(b,a);
+       va_end(b);])],
+       [AC_DEFINE(HAVE_VA_COPY, 1)
+       AC_MSG_RESULT(va_copy)],
+       [AC_LINK_IFELSE([AC_LANG_PROGRAM([
+               #include <stdarg.h>
+               va_list a;],[
+               va_list b;
+               __va_copy(b,a);
+               va_end(b);])],
+               [AC_DEFINE(HAVE___VA_COPY, 1)
+               AC_MSG_RESULT(__va_copy)],
+               [AC_MSG_RESULT(no)
+               AC_MSG_ERROR([Your system lacks asprintf() and va_copy()])])
+       ])
+fi
+
+
+
 AS_COMPILER_FLAGS(CFLAGS,
         "-Wall
          -Wextra
diff --git a/http.c b/http.c
index e79a1c7..4c77f60 100644 (file)
--- a/http.c
+++ b/http.c
@@ -525,8 +525,8 @@ static int run_csd_script(struct openconnect_info *vpninfo, char *buf, int bufle
        return 0;
 }
 
-#ifdef __sun__
-static char *local_strcasestr(const char *haystack, const char *needle)
+#ifndef HAVE_STRCASESTR
+static char *openconnect__strcasestr(const char *haystack, const char *needle)
 {
        int hlen = strlen(haystack);
        int nlen = strlen(needle);
@@ -543,7 +543,81 @@ static char *local_strcasestr(const char *haystack, const char *needle)
        }
        return NULL;
 }
-#define strcasestr local_strcasestr
+#define strcasestr openconnect__strcasestr
+#endif
+
+#ifndef HAVE_ASPRINTF
+#include <stdarg.h>
+
+static int oc_vasprintf(char **strp, const char *fmt, va_list ap)
+{
+       va_list ap2;
+       char *res = NULL;
+       int len = 160, len2;
+       int ret = 0;
+       int errno_save = -ENOMEM;
+
+       res = malloc(160);
+       if (!res)
+               goto err;
+
+       /* Use a copy of 'ap', preserving it in case we need to retry into
+          a larger buffer. 160 characters should be sufficient for most
+          strings in openconnect. */
+#ifdef HAVE_VA_COPY
+       va_copy(ap2, ap);
+#elif defined (HAVE___VA_COPY)
+       __va_copy(ap2, ap);
+#else
+#error No va_copy()!
+       // You could try this.
+       ap2 = ap;
+       // Or this
+       *ap2 = *ap;
+#endif
+       len = vsnprintf(res, 160, fmt, ap2);
+       va_end(ap2);
+
+       if (len < 0) {
+       printf_err:
+               errno_save = errno;
+               free(res);
+               res = NULL;
+               goto err;
+       }
+       if (len >=0 && len < 160)
+               goto out;
+
+       free(res);
+       res = malloc(len+1);
+       if (!res)
+               goto err;
+
+       len2 = vsnprintf(res, len+1, fmt, ap);
+       if (len2 < 0 || len2 > len)
+               goto printf_err;
+
+       ret = 0;
+       goto out;
+
+ err:
+       errno = errno_save;
+       ret = -1;
+ out:
+       *strp = res;
+       return ret;
+}
+
+int openconnect__asprintf(char **strp, const char *fmt, ...)
+{
+       va_list ap;
+       int ret;
+
+       va_start(ap, fmt);
+       ret = oc_vasprintf(strp, fmt, ap);
+       va_end(ap);
+       return ret;
+}
 #endif
 
 int internal_parse_url(char *url, char **res_proto, char **res_host,
index a094e55..51bbabc 100644 (file)
@@ -239,6 +239,13 @@ struct openconnect_info {
 #define vpn_progress(vpninfo, ...) (vpninfo)->progress ((vpninfo)->cbdata, __VA_ARGS__)
 
 /****************************************************************************/
+/* Oh Solaris how we hate thee! */
+#ifndef HAVE_ASPRINTF
+#define asprintf openconnect__asprintf
+int openconnect__asprintf(char **strp, const char *fmt, ...);
+#endif
+
+/****************************************************************************/
 
 /* tun.c */
 int setup_tun(struct openconnect_info *vpninfo);