[svn] dirmngr - r248 - in trunk: . m4 src
svn author marcus
cvs at cvs.gnupg.org
Thu Jul 26 01:20:53 CEST 2007
Author: marcus
Date: 2007-07-26 01:20:23 +0200 (Thu, 26 Jul 2007)
New Revision: 248
Added:
trunk/src/ldap-url.c
trunk/src/vasprintf.c
Modified:
trunk/ChangeLog
trunk/README
trunk/acinclude.m4
trunk/configure.ac
trunk/m4/ChangeLog
trunk/m4/Makefile.am
trunk/m4/gnupg-pth.m4
trunk/src/ChangeLog
trunk/src/Makefile.am
trunk/src/dirmngr.c
trunk/src/dirmngr_ldap.c
trunk/src/ldap.c
trunk/src/no-libgcrypt.h
trunk/src/util.h
Log:
2007-07-26 Marcus Brinkmann <marcus at g10code.de>
* acinclude.m4 (GNUPG_PTH_VERSION_CHECK): Remove macro.
(GNUPG_CHECK_VA_COPY): Add macro.
* configure.ac: Call AM_ICONV and add vasprintf as a replacement
function (checking GNUPG_CHECK_VA_COPY if necessary).
m4/
2007-07-26 Marcus Brinkmann <marcus at g10code.de>
* Makefile.am (EXTRA_DIST): Add estream.m4.
* estream.m4: New file.
* gnupg-pth.m4: Remove exception for W32 systems. The canonical
check works and is necessary.
src/
2007-07-26 Marcus Brinkmann <marcus at g10code.de>
* Makefile.am (ldap_url): New variable.
(dirmngr_ldap_SOURCES): Add $(ldap_url).
(dirmngr_ldap_LDADD): Add $(LIBOBJS).
* ldap-url.c: New file, excerpted from OpenLDAP.
* dirmngr.c (main) [HAVE_W32_SYSTEM]: Avoid the daemonization.
* dirmngr_ldap.c: Include "util.h".
(main) [HAVE_W32_SYSTEM]: Don't set up alarm.
(set_timeout) [HAVE_W32_SYSTEM]: Likewise.
* ldap.c [HAVE_W32_SYSTEM]: Add macros for setenv and pth_yield.
* no-libgcrypt.h (NO_LIBGCRYPT): Define.
* util.h [NO_LIBGCRYPT]: Don't include <gcrypt.h>.
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/ChangeLog 2007-07-25 23:20:23 UTC (rev 248)
@@ -1,3 +1,10 @@
+2007-07-26 Marcus Brinkmann <marcus at g10code.de>
+
+ * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): Remove macro.
+ (GNUPG_CHECK_VA_COPY): Add macro.
+ * configure.ac: Call AM_ICONV and add vasprintf as a replacement
+ function (checking GNUPG_CHECK_VA_COPY if necessary).
+
2007-07-20 Marcus Brinkmann <marcus at g10code.de>
* acinclude.m4 (GNUPG_FUNC_MKDIR_TAKES_ONE_ARG): New.
Modified: trunk/README
===================================================================
--- trunk/README 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/README 2007-07-25 23:20:23 UTC (rev 248)
@@ -17,7 +17,12 @@
See the file COPYING for copyright and warranty information. See
the file AUTHORS for contact addresses and code history.
+ On W32 targets, the URL extension of OpenLDAP is included which is
+ provided in src/ldap-url.c. This file has a different copyright
+ from the rest of the package. Please see that file for more
+ details.
+
Installation
------------
Please read the file INSTALL. Here is a quick summary:
Modified: trunk/acinclude.m4
===================================================================
--- trunk/acinclude.m4 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/acinclude.m4 2007-07-25 23:20:23 UTC (rev 248)
@@ -35,48 +35,6 @@
fi
])
-# GNUPG_PTH_VERSION_CHECK(REQUIRED)
-#
-# If the version is sufficient, HAVE_PTH will be set to yes.
-#
-# Taken form the m4 macros which come with Pth
-AC_DEFUN([GNUPG_PTH_VERSION_CHECK],
- [
- _pth_version=`$PTH_CONFIG --version | awk 'NR==1 {print [$]3}'`
- _req_version="ifelse([$1],,1.2.0,$1)"
- for _var in _pth_version _req_version; do
- eval "_val=\"\$${_var}\""
- _major=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\1/'`
- _minor=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\2/'`
- _rtype=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\3/'`
- _micro=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\4/'`
- case $_rtype in
- "a" ) _rtype=0 ;;
- "b" ) _rtype=1 ;;
- "." ) _rtype=2 ;;
- esac
- _hex=`echo dummy | awk '{ printf("%d%02d%1d%02d", major, minor, rtype, micro); }' \
- "major=$_major" "minor=$_minor" "rtype=$_rtype" "micro=$_micro"`
- eval "${_var}_hex=\"\$_hex\""
- done
- have_pth=no
- if test ".$_pth_version_hex" != .; then
- if test ".$_req_version_hex" != .; then
- if test $_pth_version_hex -ge $_req_version_hex; then
- have_pth=yes
- fi
- fi
- fi
- if test $have_pth = no; then
- AC_MSG_WARN([[
-***
-*** Found Pth version $_pth_version, but require at least
-*** version $_req_version. Please upgrade Pth first.
-***]])
- fi
- ])
-
-
dnl Stolen from gcc
dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead
dnl of the usual 2.
@@ -100,3 +58,46 @@
[Defined if mkdir() does not take permission flags])
fi
])
+
+
+dnl GNUPG_CHECK_VA_COPY()
+dnl Do some check on how to implement va_copy.
+dnl May define MUST_COPY_VA_BY_VAL.
+dnl Actual test code taken from glib-1.1.
+AC_DEFUN([GNUPG_CHECK_VA_COPY],
+[ AC_MSG_CHECKING(whether va_lists must be copied by value)
+ AC_CACHE_VAL(gnupg_cv_must_copy_va_byval,[
+ if test "$cross_compiling" = yes; then
+ gnupg_cv_must_copy_va_byval=no
+ else
+ gnupg_cv_must_copy_va_byval=no
+ AC_TRY_RUN([
+ #include <stdarg.h>
+ void f (int i, ...)
+ {
+ va_list args1, args2;
+ va_start (args1, i);
+ args2 = args1;
+ if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
+ exit (1);
+ va_end (args1);
+ va_end (args2);
+ }
+
+ int main()
+ {
+ f (0, 42);
+ return 0;
+ }
+ ],gnupg_cv_must_copy_va_byval=yes)
+ fi
+ ])
+ if test "$gnupg_cv_must_copy_va_byval" = yes; then
+ AC_DEFINE(MUST_COPY_VA_BYVAL,1,[used to implement the va_copy macro])
+ fi
+ if test "$cross_compiling" = yes; then
+ AC_MSG_RESULT(assuming $gnupg_cv_must_copy_va_byval)
+ else
+ AC_MSG_RESULT($gnupg_cv_must_copy_va_byval)
+ fi
+])
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/configure.ac 2007-07-25 23:20:23 UTC (rev 248)
@@ -99,7 +99,6 @@
#AC_ARG_PROGRAM
AC_SYS_LARGEFILE
-
AC_ARG_ENABLE(gcc-warnings,
AC_HELP_STRING([--enable-gcc-warnings],
[enable more verbose gcc warnings]),
@@ -180,7 +179,13 @@
#
# Checks for libraries.
#
+AM_ICONV
+AC_REPLACE_FUNCS(vasprintf)
+if test "$ac_cv_func_vasprintf" != yes; then
+ GNUPG_CHECK_VA_COPY
+fi
+
#
# We need the GNU Pth library
#
Modified: trunk/m4/ChangeLog
===================================================================
--- trunk/m4/ChangeLog 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/m4/ChangeLog 2007-07-25 23:20:23 UTC (rev 248)
@@ -1,6 +1,9 @@
-2007-06-22 Marcus Brinkmann <marcus at g10code.de>
+2007-07-26 Marcus Brinkmann <marcus at g10code.de>
+ * Makefile.am (EXTRA_DIST): Add estream.m4.
* estream.m4: New file.
+ * gnupg-pth.m4: Remove exception for W32 systems. The canonical
+ check works and is necessary.
2006-11-17 Werner Koch <wk at g10code.com>
@@ -90,4 +93,4 @@
-
\ No newline at end of file
+
Modified: trunk/m4/Makefile.am
===================================================================
--- trunk/m4/Makefile.am 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/m4/Makefile.am 2007-07-25 23:20:23 UTC (rev 248)
@@ -4,7 +4,7 @@
lcmessage.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 longdouble.m4 \
longlong.m4 nls.m4 po.m4 printf-posix.m4 progtest.m4 signed.m4 \
size_max.m4 stdint_h.m4 uintmax_t.m4 ulonglong.m4 \
- wchar_t.m4 wint_t.m4 xsize.m4
+ wchar_t.m4 wint_t.m4 xsize.m4 estream.m4
EXTRA_DIST += autobuild.m4
EXTRA_DIST += gpg-error.m4 ksba.m4 libassuan.m4 libgcrypt.m4
Modified: trunk/m4/gnupg-pth.m4
===================================================================
--- trunk/m4/gnupg-pth.m4 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/m4/gnupg-pth.m4 2007-07-25 23:20:23 UTC (rev 248)
@@ -91,9 +91,7 @@
fi
AC_PATH_PROG(PTH_CONFIG, pth-config, no)
tmp=ifelse([$1], ,1.3.7,$1)
- test -z "$have_w32_system" && have_w32_system="no"
- if test "$have_w32_system" = no; then
- if test "$PTH_CONFIG" != "no"; then
+ if test "$PTH_CONFIG" != "no"; then
GNUPG_PTH_VERSION_CHECK($tmp)
if test $have_pth = yes; then
PTH_CFLAGS=`$PTH_CONFIG --cflags`
@@ -102,12 +100,6 @@
AC_DEFINE(HAVE_PTH, 1,
[Defined if the GNU Pth is available])
fi
- fi
- else
- have_pth=yes
- PTH_CFLAGS=""
- PTH_LIBS=""
- AC_DEFINE(HAVE_PTH, 1)
fi
AC_SUBST(PTH_CFLAGS)
AC_SUBST(PTH_LIBS)
Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/src/ChangeLog 2007-07-25 23:20:23 UTC (rev 248)
@@ -1,3 +1,17 @@
+2007-07-26 Marcus Brinkmann <marcus at g10code.de>
+
+ * Makefile.am (ldap_url): New variable.
+ (dirmngr_ldap_SOURCES): Add $(ldap_url).
+ (dirmngr_ldap_LDADD): Add $(LIBOBJS).
+ * ldap-url.c: New file, excerpted from OpenLDAP.
+ * dirmngr.c (main) [HAVE_W32_SYSTEM]: Avoid the daemonization.
+ * dirmngr_ldap.c: Include "util.h".
+ (main) [HAVE_W32_SYSTEM]: Don't set up alarm.
+ (set_timeout) [HAVE_W32_SYSTEM]: Likewise.
+ * ldap.c [HAVE_W32_SYSTEM]: Add macros for setenv and pth_yield.
+ * no-libgcrypt.h (NO_LIBGCRYPT): Define.
+ * util.h [NO_LIBGCRYPT]: Don't include <gcrypt.h>.
+
2007-07-23 Marcus Brinkmann <marcus at g10code.de>
* Makefile.am (dirmngr_SOURCES): Add exechelp.h and exechelp.c.
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/src/Makefile.am 2007-07-25 23:20:23 UTC (rev 248)
@@ -25,6 +25,7 @@
EXTRA_DIST = Manifest
bin_PROGRAMS = dirmngr dirmngr-client
+
libexec_PROGRAMS = dirmngr_ldap
AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\"
@@ -48,14 +49,19 @@
dirmngr_LDADD = ../jnlib/libjnlib.a $(LIBOBJS) $(LIBASSUAN_PTH_LIBS) \
$(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(PTH_LIBS) $(LIBINTL)
+if HAVE_W32_SYSTEM
+ldap_url = ldap-url.c
+else
+ldap_url =
+endif
+
dirmngr_ldap_SOURCES = dirmngr_ldap.c i18n.h util.h \
- no-libgcrypt.c no-libgcrypt.h
+ no-libgcrypt.c no-libgcrypt.h $(ldap_url)
dirmngr_ldap_CFLAGS = $(GPG_ERROR_CFLAGS)
dirmngr_ldap_LDFLAGS =
-dirmngr_ldap_LDADD = ../jnlib/libjnlib.a $(LIBOBJS) $(GPG_ERROR_LIBS) \
- $(LDAPLIBS) $(LIBINTL)
+dirmngr_ldap_LDADD = $(ldap_ldadd) ../jnlib/libjnlib.a $(LIBOBJS) \
+ $(GPG_ERROR_LIBS) $(LDAPLIBS) $(LIBINTL)
-
dirmngr_client_SOURCES = dirmngr-client.c i18n.h util.h b64enc.c \
no-libgcrypt.c no-libgcrypt.h
dirmngr_client_LDADD = ../jnlib/libjnlib.a $(LIBOBJS) $(LIBASSUAN_LIBS) \
Modified: trunk/src/dirmngr.c
===================================================================
--- trunk/src/dirmngr.c 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/src/dirmngr.c 2007-07-25 23:20:23 UTC (rev 248)
@@ -875,6 +875,11 @@
log_info (_("listening on socket `%s'\n"), socket_name );
fflush (NULL);
+
+#ifdef HAVE_W32_SYSTEM
+ pid = getpid ();
+ printf ("set DIRMNGR_INFO=%s;%lu;1\n", socket_name, (ulong) pid);
+#else
pid = pth_fork ();
if (pid == (pid_t)-1)
{
@@ -949,6 +954,7 @@
dirmngr_exit (1);
}
}
+#endif
launch_reaper_thread ();
cert_cache_init ();
Modified: trunk/src/dirmngr_ldap.c
===================================================================
--- trunk/src/dirmngr_ldap.c 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/src/dirmngr_ldap.c 2007-07-25 23:20:23 UTC (rev 248)
@@ -42,8 +42,8 @@
#include "../jnlib/strlist.h"
#include "i18n.h"
+#include "no-libgcrypt.h"
#include "util.h"
-#include "no-libgcrypt.h"
#define DEFAULT_LDAP_TIMEOUT 100 /* Arbitrary long timeout. */
@@ -255,17 +255,19 @@
if (opt.alarm_timeout)
{
-#if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION)
+#ifndef HAVE_W32_SYSTEM
+# if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION)
struct sigaction act;
act.sa_handler = catch_alarm;
sigemptyset (&act.sa_mask);
act.sa_flags = 0;
if (sigaction (SIGALRM,&act,NULL))
-#else
+# else
if (signal (SIGALRM, catch_alarm) == SIG_ERR)
+# endif
+ log_fatal ("unable to register timeout handler\n");
#endif
- log_fatal ("unable to register timeout handler\n");
}
for (; argc; argc--, argv++)
@@ -286,12 +288,14 @@
static void
set_timeout (void)
{
+#ifndef HAVE_W32_SYSTEM
+ /* FIXME for W32. */
if (opt.alarm_timeout)
alarm (opt.alarm_timeout);
+#endif
}
-
/* Helper for fetch_ldap(). */
static int
print_ldap_entries (LDAP *ld, LDAPMessage *msg, char *want_attr)
Added: trunk/src/ldap-url.c
===================================================================
--- trunk/src/ldap-url.c 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/src/ldap-url.c 2007-07-25 23:20:23 UTC (rev 248)
@@ -0,0 +1,928 @@
+/* The following code comes from the OpenLDAP project. The references
+ to the COPYRIGHT file below refer to the corresponding file in the
+ OpenLDAP distribution, which is reproduced here in full:
+
+Copyright 1998-2004 The OpenLDAP Foundation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted only as authorized by the OpenLDAP
+Public License.
+
+A copy of this license is available in the file LICENSE in the
+top-level directory of the distribution or, alternatively, at
+<http://www.OpenLDAP.org/license.html>.
+
+OpenLDAP is a registered trademark of the OpenLDAP Foundation.
+
+Individual files and/or contributed packages may be copyright by
+other parties and subject to additional restrictions.
+
+This work is derived from the University of Michigan LDAP v3.3
+distribution. Information concerning this software is available
+at <http://www.umich.edu/~dirsvcs/ldap/>.
+
+This work also contains materials derived from public sources.
+
+Additional information about OpenLDAP can be obtained at
+<http://www.openldap.org/>.
+
+---
+
+Portions Copyright 1998-2004 Kurt D. Zeilenga.
+Portions Copyright 1998-2004 Net Boolean Incorporated.
+Portions Copyright 2001-2004 IBM Corporation.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted only as authorized by the OpenLDAP
+Public License.
+
+---
+
+Portions Copyright 1999-2003 Howard Y.H. Chu.
+Portions Copyright 1999-2003 Symas Corporation.
+Portions Copyright 1998-2003 Hallvard B. Furuseth.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that this notice is preserved.
+The names of the copyright holders may not be used to endorse or
+promote products derived from this software without their specific
+prior written permission. This software is provided ``as is''
+without express or implied warranty.
+
+---
+
+Portions Copyright (c) 1992-1996 Regents of the University of Michigan.
+All rights reserved.
+
+Redistribution and use in source and binary forms are permitted
+provided that this notice is preserved and that due credit is given
+to the University of Michigan at Ann Arbor. The name of the
+University may not be used to endorse or promote products derived
+from this software without specific prior written permission. This
+software is provided ``as is'' without express or implied warranty. */
+
+
+#include <config.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <ldap.h>
+
+#define LDAP_URL_URLCOLON "URL:"
+#define LDAP_URL_URLCOLON_LEN (sizeof(LDAP_URL_URLCOLON)-1)
+#define LDAP_URL_PREFIX "ldap://"
+#define LDAP_URL_PREFIX_LEN (sizeof(LDAP_URL_PREFIX)-1)
+#define LDAPS_URL_PREFIX "ldaps://"
+#define LDAPS_URL_PREFIX_LEN (sizeof(LDAPS_URL_PREFIX)-1)
+#define LDAPI_URL_PREFIX "ldapi://"
+#define LDAPI_URL_PREFIX_LEN (sizeof(LDAPI_URL_PREFIX)-1)
+#define LDAP_VFREE(v) { int _i; for (_i = 0; (v)[_i]; _i++) free((v)[_i]); }
+#define LDAP_FREE free
+#define LDAP_STRDUP strdup
+#define LDAP_CALLOC calloc
+#define LDAP_MALLOC malloc
+#define LDAP_REALLOC realloc
+#define ldap_utf8_strchr strchr
+#define ldap_utf8_strtok(n,d,s) strtok (n,d)
+#define Debug(a,b,c,d,e)
+void ldap_pvt_hex_unescape( char *s );
+
+
+/* $OpenLDAP: pkg/ldap/libraries/libldap/charray.c,v 1.9.2.2 2003/03/03 17:10:04 kurt Exp $ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* charray.c - routines for dealing with char * arrays */
+
+int
+ldap_charray_add(
+ char ***a,
+ char *s
+)
+{
+ int n;
+
+ if ( *a == NULL ) {
+ *a = (char **) LDAP_MALLOC( 2 * sizeof(char *) );
+ n = 0;
+
+ if( *a == NULL ) {
+ return -1;
+ }
+
+ } else {
+ char **new;
+
+ for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
+ ; /* NULL */
+ }
+
+ new = (char **) LDAP_REALLOC( (char *) *a,
+ (n + 2) * sizeof(char *) );
+
+ if( new == NULL ) {
+ /* caller is required to call ldap_charray_free(*a) */
+ return -1;
+ }
+
+ *a = new;
+ }
+
+ (*a)[n] = LDAP_STRDUP(s);
+
+ if( (*a)[n] == NULL ) {
+ return 1;
+ }
+
+ (*a)[++n] = NULL;
+
+ return 0;
+}
+
+int
+ldap_charray_merge(
+ char ***a,
+ char **s
+)
+{
+ int i, n, nn;
+ char **aa;
+
+ for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
+ ; /* NULL */
+ }
+ for ( nn = 0; s[nn] != NULL; nn++ ) {
+ ; /* NULL */
+ }
+
+ aa = (char **) LDAP_REALLOC( (char *) *a, (n + nn + 1) * sizeof(char *) );
+
+ if( aa == NULL ) {
+ return -1;
+ }
+
+ *a = aa;
+
+ for ( i = 0; i < nn; i++ ) {
+ (*a)[n + i] = LDAP_STRDUP(s[i]);
+
+ if( (*a)[n + i] == NULL ) {
+ for( --i ; i >= 0 ; i-- ) {
+ LDAP_FREE( (*a)[n + i] );
+ (*a)[n + i] = NULL;
+ }
+ return -1;
+ }
+ }
+
+ (*a)[n + nn] = NULL;
+ return 0;
+}
+
+void
+ldap_charray_free( char **a )
+{
+ char **p;
+
+ if ( a == NULL ) {
+ return;
+ }
+
+ for ( p = a; *p != NULL; p++ ) {
+ if ( *p != NULL ) {
+ LDAP_FREE( *p );
+ }
+ }
+
+ LDAP_FREE( (char *) a );
+}
+
+int
+ldap_charray_inlist(
+ char **a,
+ char *s
+)
+{
+ int i;
+
+ if( a == NULL ) return 0;
+
+ for ( i=0; a[i] != NULL; i++ ) {
+ if ( strcasecmp( s, a[i] ) == 0 ) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+char **
+ldap_charray_dup( char **a )
+{
+ int i;
+ char **new;
+
+ for ( i = 0; a[i] != NULL; i++ )
+ ; /* NULL */
+
+ new = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
+
+ if( new == NULL ) {
+ return NULL;
+ }
+
+ for ( i = 0; a[i] != NULL; i++ ) {
+ new[i] = LDAP_STRDUP( a[i] );
+
+ if( new[i] == NULL ) {
+ for( --i ; i >= 0 ; i-- ) {
+ LDAP_FREE( new[i] );
+ }
+ LDAP_FREE( new );
+ return NULL;
+ }
+ }
+ new[i] = NULL;
+
+ return( new );
+}
+
+char **
+ldap_str2charray( const char *str_in, const char *brkstr )
+{
+ char **res;
+ char *str, *s;
+ char *lasts;
+ int i;
+
+ /* protect the input string from strtok */
+ str = LDAP_STRDUP( str_in );
+ if( str == NULL ) {
+ return NULL;
+ }
+
+ i = 1;
+ for ( s = str; *s; s++ ) {
+ if ( ldap_utf8_strchr( brkstr, s ) != NULL ) {
+ i++;
+ }
+ }
+
+ res = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
+
+ if( res == NULL ) {
+ LDAP_FREE( str );
+ return NULL;
+ }
+
+ i = 0;
+
+ for ( s = ldap_utf8_strtok( str, brkstr, &lasts );
+ s != NULL;
+ s = ldap_utf8_strtok( NULL, brkstr, &lasts ) )
+ {
+ res[i] = LDAP_STRDUP( s );
+
+ if(res[i] == NULL) {
+ for( --i ; i >= 0 ; i-- ) {
+ LDAP_FREE( res[i] );
+ }
+ LDAP_FREE( res );
+ LDAP_FREE( str );
+ return NULL;
+ }
+
+ i++;
+ }
+
+ res[i] = NULL;
+
+ LDAP_FREE( str );
+ return( res );
+}
+
+char * ldap_charray2str( char **a, const char *sep )
+{
+ char *s, **v, *p;
+ int len;
+ int slen;
+
+ if( sep == NULL ) sep = " ";
+
+ slen = strlen( sep );
+ len = 0;
+
+ for ( v = a; *v != NULL; v++ ) {
+ len += strlen( *v ) + slen;
+ }
+
+ if ( len == 0 ) {
+ return NULL;
+ }
+
+ /* trim extra sep len */
+ len -= slen;
+
+ s = LDAP_MALLOC ( len + 1 );
+
+ if ( s == NULL ) {
+ return NULL;
+ }
+
+ p = s;
+ for ( v = a; *v != NULL; v++ ) {
+ if ( v != a ) {
+ strncpy( p, sep, slen );
+ p += slen;
+ }
+
+ len = strlen( *v );
+ strncpy( p, *v, len );
+ p += len;
+ }
+
+ *p = '\0';
+ return s;
+}
+
+
+
+/* $OpenLDAP: pkg/ldap/libraries/libldap/url.c,v 1.64.2.5 2003/03/03 17:10:05 kurt Exp $ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* Portions
+ * Copyright (c) 1996 Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * LIBLDAP url.c -- LDAP URL (RFC 2255) related routines
+ *
+ * LDAP URLs look like this:
+ * ldap[is]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]]
+ *
+ * where:
+ * attributes is a comma separated list
+ * scope is one of these three strings: base one sub (default=base)
+ * filter is an string-represented filter as in RFC 2254
+ *
+ * e.g., ldap://host:port/dc=com?o,cn?base?(o=openldap)?extension
+ *
+ * We also tolerate URLs that look like: <ldapurl> and <URL:ldapurl>
+ */
+
+/* local functions */
+static const char* skip_url_prefix LDAP_P((
+ const char *url,
+ int *enclosedp,
+ const char **scheme ));
+
+int
+ldap_is_ldap_url( LDAP_CONST char *url )
+{
+ int enclosed;
+ const char * scheme;
+
+ if( url == NULL ) {
+ return 0;
+ }
+
+ if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
+static const char*
+skip_url_prefix(
+ const char *url,
+ int *enclosedp,
+ const char **scheme )
+{
+ /*
+ * return non-zero if this looks like a LDAP URL; zero if not
+ * if non-zero returned, *urlp will be moved past "ldap://" part of URL
+ */
+ const char *p;
+
+ if ( url == NULL ) {
+ return( NULL );
+ }
+
+ p = url;
+
+ /* skip leading '<' (if any) */
+ if ( *p == '<' ) {
+ *enclosedp = 1;
+ ++p;
+ } else {
+ *enclosedp = 0;
+ }
+
+ /* skip leading "URL:" (if any) */
+ if ( strncasecmp( p, LDAP_URL_URLCOLON, LDAP_URL_URLCOLON_LEN ) == 0 ) {
+ p += LDAP_URL_URLCOLON_LEN;
+ }
+
+ /* check for "ldap://" prefix */
+ if ( strncasecmp( p, LDAP_URL_PREFIX, LDAP_URL_PREFIX_LEN ) == 0 ) {
+ /* skip over "ldap://" prefix and return success */
+ p += LDAP_URL_PREFIX_LEN;
+ *scheme = "ldap";
+ return( p );
+ }
+
+ /* check for "ldaps://" prefix */
+ if ( strncasecmp( p, LDAPS_URL_PREFIX, LDAPS_URL_PREFIX_LEN ) == 0 ) {
+ /* skip over "ldaps://" prefix and return success */
+ p += LDAPS_URL_PREFIX_LEN;
+ *scheme = "ldaps";
+ return( p );
+ }
+
+ /* check for "ldapi://" prefix */
+ if ( strncasecmp( p, LDAPI_URL_PREFIX, LDAPI_URL_PREFIX_LEN ) == 0 ) {
+ /* skip over "ldapi://" prefix and return success */
+ p += LDAPI_URL_PREFIX_LEN;
+ *scheme = "ldapi";
+ return( p );
+ }
+
+#ifdef LDAP_CONNECTIONLESS
+ /* check for "cldap://" prefix */
+ if ( strncasecmp( p, LDAPC_URL_PREFIX, LDAPC_URL_PREFIX_LEN ) == 0 ) {
+ /* skip over "cldap://" prefix and return success */
+ p += LDAPC_URL_PREFIX_LEN;
+ *scheme = "cldap";
+ return( p );
+ }
+#endif
+
+ return( NULL );
+}
+
+
+static int str2scope( const char *p )
+{
+ if ( strcasecmp( p, "one" ) == 0 ) {
+ return LDAP_SCOPE_ONELEVEL;
+
+ } else if ( strcasecmp( p, "onetree" ) == 0 ) {
+ return LDAP_SCOPE_ONELEVEL;
+
+ } else if ( strcasecmp( p, "base" ) == 0 ) {
+ return LDAP_SCOPE_BASE;
+
+ } else if ( strcasecmp( p, "sub" ) == 0 ) {
+ return LDAP_SCOPE_SUBTREE;
+
+ } else if ( strcasecmp( p, "subtree" ) == 0 ) {
+ return LDAP_SCOPE_SUBTREE;
+ }
+
+ return( -1 );
+}
+
+
+int
+ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
+{
+/*
+ * Pick apart the pieces of an LDAP URL.
+ */
+
+ LDAPURLDesc *ludp;
+ char *p, *q, *r;
+ int i, enclosed;
+ const char *scheme = NULL;
+ const char *url_tmp;
+ char *url;
+
+ if( url_in == NULL || ludpp == NULL ) {
+ return LDAP_URL_ERR_PARAM;
+ }
+
+#ifndef LDAP_INT_IN_KERNEL
+ /* Global options may not be created yet
+ * We can't test if the global options are initialized
+ * because a call to LDAP_INT_GLOBAL_OPT() will try to allocate
+ * the options and cause infinite recursion
+ */
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ENTRY, "ldap_url_parse_ext(%s)\n", url_in, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "ldap_url_parse_ext(%s)\n", url_in, 0, 0 );
+#endif
+#endif
+
+ *ludpp = NULL; /* pessimistic */
+
+ url_tmp = skip_url_prefix( url_in, &enclosed, &scheme );
+
+ if ( url_tmp == NULL ) {
+ return LDAP_URL_ERR_BADSCHEME;
+ }
+
+ assert( scheme );
+
+ /* make working copy of the remainder of the URL */
+ url = LDAP_STRDUP( url_tmp );
+ if ( url == NULL ) {
+ return LDAP_URL_ERR_MEM;
+ }
+
+ if ( enclosed ) {
+ p = &url[strlen(url)-1];
+
+ if( *p != '>' ) {
+ LDAP_FREE( url );
+ return LDAP_URL_ERR_BADENCLOSURE;
+ }
+
+ *p = '\0';
+ }
+
+ /* allocate return struct */
+ ludp = (LDAPURLDesc *)LDAP_CALLOC( 1, sizeof( LDAPURLDesc ));
+
+ if ( ludp == NULL ) {
+ LDAP_FREE( url );
+ return LDAP_URL_ERR_MEM;
+ }
+
+ ludp->lud_next = NULL;
+ ludp->lud_host = NULL;
+ ludp->lud_port = 0;
+ ludp->lud_dn = NULL;
+ ludp->lud_attrs = NULL;
+ ludp->lud_filter = NULL;
+ ludp->lud_scope = LDAP_SCOPE_DEFAULT;
+ ludp->lud_filter = NULL;
+ ludp->lud_exts = NULL;
+
+ ludp->lud_scheme = LDAP_STRDUP( scheme );
+
+ if ( ludp->lud_scheme == NULL ) {
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_MEM;
+ }
+
+ /* scan forward for '/' that marks end of hostport and begin. of dn */
+ p = strchr( url, '/' );
+
+ if( p != NULL ) {
+ /* terminate hostport; point to start of dn */
+ *p++ = '\0';
+ }
+
+ /* IPv6 syntax with [ip address]:port */
+ if ( *url == '[' ) {
+ r = strchr( url, ']' );
+ if ( r == NULL ) {
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_BADURL;
+ }
+ *r++ = '\0';
+ q = strchr( r, ':' );
+ } else {
+ q = strchr( url, ':' );
+ }
+
+ if ( q != NULL ) {
+ *q++ = '\0';
+ ldap_pvt_hex_unescape( q );
+
+ if( *q == '\0' ) {
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_BADURL;
+ }
+
+ ludp->lud_port = atoi( q );
+ }
+
+ ldap_pvt_hex_unescape( url );
+
+ /* If [ip address]:port syntax, url is [ip and we skip the [ */
+ ludp->lud_host = LDAP_STRDUP( url + ( *url == '[' ) );
+
+ if( ludp->lud_host == NULL ) {
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_MEM;
+ }
+
+ /*
+ * Kludge. ldap://111.222.333.444:389??cn=abc,o=company
+ *
+ * On early Novell releases, search references/referrals were returned
+ * in this format, i.e., the dn was kind of in the scope position,
+ * but the required slash is missing. The whole thing is illegal syntax,
+ * but we need to account for it. Fortunately it can't be confused with
+ * anything real.
+ */
+ if( (p == NULL) && (q != NULL) && ((q = strchr( q, '?')) != NULL)) {
+ q++;
+ /* ? immediately followed by question */
+ if( *q == '?') {
+ q++;
+ if( *q != '\0' ) {
+ /* parse dn part */
+ ldap_pvt_hex_unescape( q );
+ ludp->lud_dn = LDAP_STRDUP( q );
+ } else {
+ ludp->lud_dn = LDAP_STRDUP( "" );
+ }
+
+ if( ludp->lud_dn == NULL ) {
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_MEM;
+ }
+ }
+ }
+
+ if( p == NULL ) {
+ LDAP_FREE( url );
+ *ludpp = ludp;
+ return LDAP_URL_SUCCESS;
+ }
+
+ /* scan forward for '?' that may marks end of dn */
+ q = strchr( p, '?' );
+
+ if( q != NULL ) {
+ /* terminate dn part */
+ *q++ = '\0';
+ }
+
+ if( *p != '\0' ) {
+ /* parse dn part */
+ ldap_pvt_hex_unescape( p );
+ ludp->lud_dn = LDAP_STRDUP( p );
+ } else {
+ ludp->lud_dn = LDAP_STRDUP( "" );
+ }
+
+ if( ludp->lud_dn == NULL ) {
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_MEM;
+ }
+
+ if( q == NULL ) {
+ /* no more */
+ LDAP_FREE( url );
+ *ludpp = ludp;
+ return LDAP_URL_SUCCESS;
+ }
+
+ /* scan forward for '?' that may marks end of attributes */
+ p = q;
+ q = strchr( p, '?' );
+
+ if( q != NULL ) {
+ /* terminate attributes part */
+ *q++ = '\0';
+ }
+
+ if( *p != '\0' ) {
+ /* parse attributes */
+ ldap_pvt_hex_unescape( p );
+ ludp->lud_attrs = ldap_str2charray( p, "," );
+
+ if( ludp->lud_attrs == NULL ) {
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_BADATTRS;
+ }
+ }
+
+ if ( q == NULL ) {
+ /* no more */
+ LDAP_FREE( url );
+ *ludpp = ludp;
+ return LDAP_URL_SUCCESS;
+ }
+
+ /* scan forward for '?' that may marks end of scope */
+ p = q;
+ q = strchr( p, '?' );
+
+ if( q != NULL ) {
+ /* terminate the scope part */
+ *q++ = '\0';
+ }
+
+ if( *p != '\0' ) {
+ /* parse the scope */
+ ldap_pvt_hex_unescape( p );
+ ludp->lud_scope = str2scope( p );
+
+ if( ludp->lud_scope == -1 ) {
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_BADSCOPE;
+ }
+ }
+
+ if ( q == NULL ) {
+ /* no more */
+ LDAP_FREE( url );
+ *ludpp = ludp;
+ return LDAP_URL_SUCCESS;
+ }
+
+ /* scan forward for '?' that may marks end of filter */
+ p = q;
+ q = strchr( p, '?' );
+
+ if( q != NULL ) {
+ /* terminate the filter part */
+ *q++ = '\0';
+ }
+
+ if( *p != '\0' ) {
+ /* parse the filter */
+ ldap_pvt_hex_unescape( p );
+
+ if( ! *p ) {
+ /* missing filter */
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_BADFILTER;
+ }
+
+ LDAP_FREE( ludp->lud_filter );
+ ludp->lud_filter = LDAP_STRDUP( p );
+
+ if( ludp->lud_filter == NULL ) {
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_MEM;
+ }
+ }
+
+ if ( q == NULL ) {
+ /* no more */
+ LDAP_FREE( url );
+ *ludpp = ludp;
+ return LDAP_URL_SUCCESS;
+ }
+
+ /* scan forward for '?' that may marks end of extensions */
+ p = q;
+ q = strchr( p, '?' );
+
+ if( q != NULL ) {
+ /* extra '?' */
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_BADURL;
+ }
+
+ /* parse the extensions */
+ ludp->lud_exts = ldap_str2charray( p, "," );
+
+ if( ludp->lud_exts == NULL ) {
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_BADEXTS;
+ }
+
+ for( i=0; ludp->lud_exts[i] != NULL; i++ ) {
+ ldap_pvt_hex_unescape( ludp->lud_exts[i] );
+
+ if( *ludp->lud_exts[i] == '!' ) {
+ /* count the number of critical extensions */
+ ludp->lud_crit_exts++;
+ }
+ }
+
+ if( i == 0 ) {
+ /* must have 1 or more */
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_BADEXTS;
+ }
+
+ /* no more */
+ *ludpp = ludp;
+ LDAP_FREE( url );
+ return LDAP_URL_SUCCESS;
+}
+
+int
+ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
+{
+ int rc = ldap_url_parse_ext( url_in, ludpp );
+
+ if( rc != LDAP_URL_SUCCESS ) {
+ return rc;
+ }
+
+ if ((*ludpp)->lud_scope == LDAP_SCOPE_DEFAULT) {
+ (*ludpp)->lud_scope = LDAP_SCOPE_BASE;
+ }
+
+ if ((*ludpp)->lud_host != NULL && *(*ludpp)->lud_host == '\0') {
+ LDAP_FREE( (*ludpp)->lud_host );
+ (*ludpp)->lud_host = NULL;
+ }
+
+ if ((*ludpp)->lud_port == 0) {
+ if( strcmp((*ludpp)->lud_scheme, "ldap") == 0 ) {
+ (*ludpp)->lud_port = LDAP_PORT;
+#ifdef LDAP_CONNECTIONLESS
+ } else if( strcmp((*ludpp)->lud_scheme, "cldap") == 0 ) {
+ (*ludpp)->lud_port = LDAP_PORT;
+#endif
+ } else if( strcmp((*ludpp)->lud_scheme, "ldaps") == 0 ) {
+ (*ludpp)->lud_port = LDAPS_PORT;
+ }
+ }
+
+ return rc;
+}
+
+
+void
+ldap_free_urldesc( LDAPURLDesc *ludp )
+{
+ if ( ludp == NULL ) {
+ return;
+ }
+
+ if ( ludp->lud_scheme != NULL ) {
+ LDAP_FREE( ludp->lud_scheme );
+ }
+
+ if ( ludp->lud_host != NULL ) {
+ LDAP_FREE( ludp->lud_host );
+ }
+
+ if ( ludp->lud_dn != NULL ) {
+ LDAP_FREE( ludp->lud_dn );
+ }
+
+ if ( ludp->lud_filter != NULL ) {
+ LDAP_FREE( ludp->lud_filter);
+ }
+
+ if ( ludp->lud_attrs != NULL ) {
+ LDAP_VFREE( ludp->lud_attrs );
+ }
+
+ if ( ludp->lud_exts != NULL ) {
+ LDAP_VFREE( ludp->lud_exts );
+ }
+
+ LDAP_FREE( ludp );
+}
+
+
+static int
+ldap_int_unhex( int c )
+{
+ return( c >= '0' && c <= '9' ? c - '0'
+ : c >= 'A' && c <= 'F' ? c - 'A' + 10
+ : c - 'a' + 10 );
+}
+
+void
+ldap_pvt_hex_unescape( char *s )
+{
+ /*
+ * Remove URL hex escapes from s... done in place. The basic concept for
+ * this routine is borrowed from the WWW library HTUnEscape() routine.
+ */
+ char *p;
+
+ for ( p = s; *s != '\0'; ++s ) {
+ if ( *s == '%' ) {
+ if ( *++s == '\0' ) {
+ break;
+ }
+ *p = ldap_int_unhex( *s ) << 4;
+ if ( *++s == '\0' ) {
+ break;
+ }
+ *p++ += ldap_int_unhex( *s );
+ } else {
+ *p++ = *s;
+ }
+ }
+
+ *p = '\0';
+}
+
Modified: trunk/src/ldap.c
===================================================================
--- trunk/src/ldap.c 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/src/ldap.c 2007-07-25 23:20:23 UTC (rev 248)
@@ -37,6 +37,11 @@
#include "dirmngr.h"
#include "misc.h"
+#if HAVE_W32_SYSTEM
+#define setenv(a,b,c) SetEnvironmentVariable ((a),(b))
+#define pth_yield(a) /* FIXME */
+#endif
+
/* In case sysconf does not return a value we need to have a limit. */
#ifdef _POSIX_OPEN_MAX
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
Modified: trunk/src/no-libgcrypt.h
===================================================================
--- trunk/src/no-libgcrypt.h 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/src/no-libgcrypt.h 2007-07-25 23:20:23 UTC (rev 248)
@@ -21,6 +21,8 @@
#ifndef NO_LIBGCRYPT_H
#define NO_LIBGCRYPT_H
+#define NO_LIBGCRYPT 1
+
void *gcry_malloc (size_t n);
void *gcry_xmalloc (size_t n);
void *gcry_realloc (void *a, size_t n);
Modified: trunk/src/util.h
===================================================================
--- trunk/src/util.h 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/src/util.h 2007-07-25 23:20:23 UTC (rev 248)
@@ -22,7 +22,9 @@
#define UTIL_H
#include <gpg-error.h>
+#ifndef NO_LIBGCRYPT
#include <gcrypt.h>
+#endif
/* Get all the stuff from jnlib. */
#include "../jnlib/logging.h"
Added: trunk/src/vasprintf.c
===================================================================
--- trunk/src/vasprintf.c 2007-07-23 16:22:05 UTC (rev 247)
+++ trunk/src/vasprintf.c 2007-07-25 23:20:23 UTC (rev 248)
@@ -0,0 +1,192 @@
+/* Like vsprintf but provides a pointer to malloc'd storage, which must
+ be freed by the caller.
+ Copyright (C) 1994, 2002 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+
+#ifndef va_copy /* According to POSIX, va_copy is a macro. */
+#if defined (__GNUC__) && defined (__PPC__) \
+ && (defined (_CALL_SYSV) || defined (_WIN32))
+#define va_copy(d, s) (*(d) = *(s))
+#elif defined (MUST_COPY_VA_BYVAL)
+#define va_copy(d, s) ((d) = (s))
+#else
+#define va_copy(d, s) memcpy ((d), (s), sizeof (va_list))
+#endif
+#endif
+
+
+#ifdef TEST
+int global_total_width;
+#endif
+
+static int int_vasprintf (char **, const char *, va_list *);
+
+static int
+int_vasprintf (result, format, args)
+ char **result;
+ const char *format;
+ va_list *args;
+{
+ const char *p = format;
+ /* Add one to make sure that it is never zero, which might cause malloc
+ to return NULL. */
+ int total_width = strlen (format) + 1;
+ va_list ap;
+
+ va_copy (ap, *args);
+
+ while (*p != '\0')
+ {
+ if (*p++ == '%')
+ {
+ while (strchr ("-+ #0", *p))
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ total_width += strtoul (p, (char **) &p, 10);
+ if (*p == '.')
+ {
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ total_width += strtoul (p, (char **) &p, 10);
+ }
+ while (strchr ("hlL", *p))
+ ++p;
+ /* Should be big enough for any format specifier except %s and floats. */
+ total_width += 30;
+ switch (*p)
+ {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ (void) va_arg (ap, int);
+ break;
+ case 'f':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ (void) va_arg (ap, double);
+ /* Since an ieee double can have an exponent of 307, we'll
+ make the buffer wide enough to cover the gross case. */
+ total_width += 307;
+ break;
+ case 's':
+ {
+ char *tmp = va_arg (ap, char *);
+ if (tmp)
+ total_width += strlen (tmp);
+ else /* in case the vsprintf does prints a text */
+ total_width += 25; /* e.g. "(null pointer reference)" */
+ }
+ break;
+ case 'p':
+ case 'n':
+ (void) va_arg (ap, char *);
+ break;
+ }
+ p++;
+ }
+ }
+#ifdef TEST
+ global_total_width = total_width;
+#endif
+ *result = malloc (total_width);
+ if (*result != NULL)
+ return vsprintf (*result, format, *args);
+ else
+ return 0;
+}
+
+int
+vasprintf (result, format, args)
+ char **result;
+ const char *format;
+#if defined (_BSD_VA_LIST_) && defined (__FreeBSD__)
+ _BSD_VA_LIST_ args;
+#else
+ va_list args;
+#endif
+{
+ return int_vasprintf (result, format, &args);
+}
+
+
+int
+asprintf (char **buf, const char *fmt, ...)
+{
+ int status;
+ va_list ap;
+
+ va_start (ap, fmt);
+ status = vasprintf (buf, fmt, ap);
+ va_end (ap);
+ return status;
+}
+
+
+#ifdef TEST
+void
+checkit (const char* format, ...)
+{
+ va_list args;
+ char *result;
+
+ va_start (args, format);
+ vasprintf (&result, format, args);
+ if (strlen (result) < global_total_width)
+ printf ("PASS: ");
+ else
+ printf ("FAIL: ");
+ printf ("%d %s\n", global_total_width, result);
+}
+
+int
+main (void)
+{
+ checkit ("%d", 0x12345678);
+ checkit ("%200d", 5);
+ checkit ("%.300d", 6);
+ checkit ("%100.150d", 7);
+ checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
+777777777777777777333333333333366666666666622222222222777777777777733333");
+ checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
+}
+#endif /* TEST */
More information about the Gnupg-commits
mailing list