Skip to content

Commit

Permalink
Add local implementation of asprintf() for Solaris 10
Browse files Browse the repository at this point in the history
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Apr 18, 2012
1 parent 8b5c180 commit 4874af0
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 3 deletions.
28 changes: 28 additions & 0 deletions configure.ac
Expand Up @@ -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
Expand Down
80 changes: 77 additions & 3 deletions http.c
Expand Up @@ -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);
Expand All @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions openconnect-internal.h
Expand Up @@ -238,6 +238,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 */
Expand Down

0 comments on commit 4874af0

Please sign in to comment.