Update to latest version (see CHANGES file). Docs may not be totally

up to date.
This commit is contained in:
Randy Kunkee 2000-05-03 17:01:46 +00:00
parent 1ce2f09193
commit 076edefb26
9 changed files with 705 additions and 259 deletions

11
contrib/ldaptcl/CHANGES Normal file
View File

@ -0,0 +1,11 @@
Package version 1.2:
- Filter no longer a required controlArray member, defaults to objectclass=*.
- Sets errorCode with LDAP macro string value (better to test than the more
human readable values).
- Shorten minimum required characters for search scope definitions: now allows
"base", "one", and "sub". For the latter two, additional characters are
ignored.
- Now compiles successfully with -devel branch.
- Client cache management code enabled for OpenLDAP versions <= 1.2.4. (This
code is relatively untested and feedback is welcome.)

View File

@ -21,24 +21,24 @@ exec_prefix = @exec_prefix@
# The following definition can be set to non-null for special systems # The following definition can be set to non-null for special systems
# like AFS with replication. It allows the pathnames used for installation # like AFS with replication. It allows the pathnames used for installation
# to be different than those used for actually reference files at # to be different than those used for actually reference files at
# run-time. INSTALL_ROOT is prepended to $prefix and $exec_prefix # run-time. DESTDIR is prepended to $prefix and $exec_prefix
# when installing files. # when installing files.
INSTALL_ROOT = DESTDIR =
# Directory in which to search for tcl libraries # Directory in which to search for tcl libraries
NEO_LIBRARY = $(exec_prefix)/lib/ldaptcl$(VERSION) NEO_LIBRARY = $(exec_prefix)/lib/ldaptcl$(VERSION)
# Directory in which to install the ldaptcl binary: # Directory in which to install the ldaptcl binary:
BIN_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/bin BIN_INSTALL_DIR = $(DESTDIR)$(exec_prefix)/bin
# Directory in which to install the .a or .so binary for the Neo library: # Directory in which to install the .a or .so binary for the Neo library:
LIB_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/lib LIB_INSTALL_DIR = $(DESTDIR)$(exec_prefix)/lib
# Path to use at runtime to refer to LIB_INSTALL_DIR: # Path to use at runtime to refer to LIB_INSTALL_DIR:
LIB_RUNTIME_DIR = $(exec_prefix)/lib LIB_RUNTIME_DIR = $(exec_prefix)/lib
# Top-level directory for man entries: # Top-level directory for man entries:
MANN_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/man/mann MANN_INSTALL_DIR = $(DESTDIR)$(prefix)/man/mann
# The symbols below provide support for dynamic loading and shared # The symbols below provide support for dynamic loading and shared
@ -85,6 +85,7 @@ SHLIB_LD = @SHLIB_LD@
LDAP_LIBFLAGS = @ldaplibflags@ LDAP_LIBFLAGS = @ldaplibflags@
LDAP_CFLAGS = @ldapinclude@ LDAP_CFLAGS = @ldapinclude@
LDAP_INCDIR = @ldapincdir@
LDAP_BUILD = @ldapbuild@ LDAP_BUILD = @ldapbuild@
LDAP_DIR = @ldapdir@ LDAP_DIR = @ldapdir@
@ -120,13 +121,11 @@ LIBS= @LIBS@ @TCLX_LIB_SPEC@ @TCL_LIB_SPEC@ @TCL_LIBS@ $(LDAP_LIBFLAGS) -lc
TK_LIBS=@TKX_LIB_SPEC@ @TK_LIB_SPEC@ @TK_LIBS@ TK_LIBS=@TKX_LIB_SPEC@ @TK_LIB_SPEC@ @TK_LIBS@
TK_VERSION=@TK_VERSION@ TK_VERSION=@TK_VERSION@
LDAPINCDIR=/usr/local/include
CC = @CC@ CC = @CC@
CC_SWITCHES = ${CFLAGS} @NEO_SHLIB_CFLAGS@ -I. \ CC_SWITCHES = ${CFLAGS} @NEO_SHLIB_CFLAGS@ -I. \
-I@prefix@/include ${AC_FLAGS} ${PROTO_FLAGS} \ -I@prefix@/include ${AC_FLAGS} ${PROTO_FLAGS} \
${SECURITY_FLAGS} ${MEM_DEBUG_FLAGS} ${KEYSYM_FLAGS} \ ${SECURITY_FLAGS} ${MEM_DEBUG_FLAGS} ${KEYSYM_FLAGS} \
-DNEO_LIBRARY=\"${NEO_LIBRARY}\" -DNEO_LIBRARY=\"${NEO_LIBRARY}\" -DVERSION=\"${VERSION}\"
TK_SWITCHES = ${CC_SWITCHES} @TK_XINCLUDES@ TK_SWITCHES = ${CC_SWITCHES} @TK_XINCLUDES@
@ -140,15 +139,20 @@ all: @NEO_LIB_FILE@ ldaptclsh @LDAPWISH@
@MAKE_LIB@ @MAKE_LIB@
$(RANLIB) @NEO_LIB_FILE@ $(RANLIB) @NEO_LIB_FILE@
neoXldap.o: neoXldap.c neoXldap.o: neoXldap.c ldaptclerr.h
$(CC) -c $(LDAP_CFLAGS) $(CC_SWITCHES) $< $(CC) -c $(LDAP_CFLAGS) $(CC_SWITCHES) $<
ldaptclerr.h: ldaperr.tcl
tcl ldaperr.tcl $(LDAP_INCDIR)/ldap.h > ldaptclerr.h
clean: clean:
-rm -f ldaptclsh ldapwish -rm -f ldaptclsh ldapwish
-rm -f *.o *.a *.so* -rm -f *.o *.a *.so*
distclean: clean distclean: clean
rm -f Makefile pkgIndex.tcl config.cache config.log config.status rm -f Makefile pkgIndex.tcl config.cache config.log config.status \
ldaptclerr.h
install: install-binaries install-man install: install-binaries install-man

View File

@ -1,7 +1,7 @@
Copyright (c) 1998-1999 NeoSoft, Inc. Copyright (c) 1998-1999 NeoSoft, Inc.
For licensing information, see the file neoXldap.c and the COPYRIGHT For licensing information, see the file neoXldap.c and/or the COPYRIGHT
file contains in the directory you found this file. file contained in the directory you found this file.
This directory contains an extension to Tcl to interface with an This directory contains an extension to Tcl to interface with an
LDAP server. While this software is being released to the OpenLDAP LDAP server. While this software is being released to the OpenLDAP
@ -10,7 +10,8 @@ be added) for other client libraries as well. As time goes on, it
is expected that code will converge rather than diverge. is expected that code will converge rather than diverge.
Support is provided for University of Michigan LDAP version 3.3, Support is provided for University of Michigan LDAP version 3.3,
OpenLDAP, and Netscape. OpenLDAP, and Netscape. The default configuration supports
OpenLDAP 1.2.4. OpenLDAP 2.x is not yet supported.
It uses GNU autoconf. It builds and installs without requiring It uses GNU autoconf. It builds and installs without requiring
parallel directories, but it does require that Tcl and Extended Tcl parallel directories, but it does require that Tcl and Extended Tcl
@ -21,8 +22,8 @@ For further info, try "./configure --help".
For example, I run: For example, I run:
./configure --prefix=/opt/neosoft97 --enable-shared \ ./configure --prefix=/opt/neotcl --enable-shared \
--with-ldap=/usr/isp2000/ldap --with-ldap=/usr/local/ldap
Remember that --prefix must be the same prefix used when building Remember that --prefix must be the same prefix used when building
and installint Tcl. and installint Tcl.
@ -36,30 +37,24 @@ This module will install a regular shell (ldaptclsh) a windowing
shell (ldapwish) a library, a pkgIndex.tcl, and a manpage (ldap.n). shell (ldapwish) a library, a pkgIndex.tcl, and a manpage (ldap.n).
If your Tcl installation has been configured with --enable-shared, If your Tcl installation has been configured with --enable-shared,
then it is highly recommended that you also use --enable-shared then you must also use --enable-shared here.
here.
Shared libraries and Tcl packages. Shared libraries and Tcl packages.
If Tcl is built with --enable-shared, and OpenLDAP (or another version If Tcl is built with --enable-shared, AND OpenLDAP (or another version
for that matter) has been build to create -llber and -lldap as shared for that matter) has been build to create -llber and -lldap as shared
libaries, and you build ldaptcl with --enable-shared, it should be libaries, AND you build ldaptcl with --enable-shared, it should be
possible to run a plain Tcl interpreter (eg. tclsh8.0) and do possible to run a plain Tcl interpreter (eg. tclsh8.0) and do
package require Ldaptcl package require Ldaptcl
which will install the "ldap" command into the interpreter. which will install the "ldap" command into the interpreter.
This may require that you set the LD_LIBRARY_PATH environment variable You may need to set the LD_LIBRARY_PATH environment variable appropriately,
appropriately, or use -R or -W,-rpath ld command options. or use -R or -W,-rpath ld command options to resolve the search for ldap
It also may require that you modify the and lber libraries.
If you configure with --enable-shared, and you have shared libraries
for -lldap and -llber, then you might be able to
"package require Ldaptcl", provided that everything is set up
exactly right, ie. -R ld flags, LD_LIBRARY_PATH environment variables,
etc.
This package was test built on a Sparc Solaris 2.5 using the SUN Pro C This package was test built on a Alpha OSF4.0e with the native C
compiler. compiler.
You may email comments or bug fixes to openldap-devel@OpenLDAP.org, You may email comments or bug fixes to openldap-devel@OpenLDAP.org,

View File

@ -1,7 +1,7 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated automatically using autoconf version 2.12 # Generated automatically using autoconf version 2.13
# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
# #
# This configure script is free software; the Free Software Foundation # This configure script is free software; the Free Software Foundation
@ -67,6 +67,7 @@ mandir='${prefix}/man'
# Initialize some other variables. # Initialize some other variables.
subdirs= subdirs=
MFLAGS= MAKEFLAGS= MFLAGS= MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}
# Maximum number of lines to put in a shell here document. # Maximum number of lines to put in a shell here document.
ac_max_here_lines=12 ac_max_here_lines=12
@ -350,7 +351,7 @@ EOF
verbose=yes ;; verbose=yes ;;
-version | --version | --versio | --versi | --vers) -version | --version | --versio | --versi | --vers)
echo "configure generated by autoconf version 2.12" echo "configure generated by autoconf version 2.13"
exit 0 ;; exit 0 ;;
-with-* | --with-*) -with-* | --with-*)
@ -520,9 +521,11 @@ ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS' ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross cross_compiling=$ac_cv_prog_cc_cross
ac_exeext=
ac_objext=o
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
# Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
@ -536,11 +539,11 @@ else
fi fi
# $Id: configure,v 1.1 1999/02/10 22:56:49 kunkee Exp $ # $Id: configure,v 1.3 1999/08/03 05:23:03 kunkee Exp $
NEO_VERSION=1.0 NEO_VERSION=1.2
NEO_MAJOR_VERSION=1 NEO_MAJOR_VERSION=1
NEO_MINOR_VERSION=0 NEO_MINOR_VERSION=2
VERSION=${NEO_VERSION} VERSION=${NEO_VERSION}
if test "${prefix}" = "NONE"; then if test "${prefix}" = "NONE"; then
@ -562,15 +565,16 @@ if test "$neo_ok" = "yes"; then
# Extract the first word of "gcc", so it can be a program name with args. # Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2 set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:566: checking for $ac_word" >&5 echo "configure:569: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
if test -n "$CC"; then if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test. ac_cv_prog_CC="$CC" # Let the user override the test.
else else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
for ac_dir in $PATH; do ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=. test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="gcc" ac_cv_prog_CC="gcc"
@ -591,16 +595,17 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args. # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2 set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:595: checking for $ac_word" >&5 echo "configure:599: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
if test -n "$CC"; then if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test. ac_cv_prog_CC="$CC" # Let the user override the test.
else else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_prog_rejected=no ac_prog_rejected=no
for ac_dir in $PATH; do ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=. test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then if test -f $ac_dir/$ac_word; then
if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
@ -635,25 +640,61 @@ else
echo "$ac_t""no" 1>&6 echo "$ac_t""no" 1>&6
fi fi
if test -z "$CC"; then
case "`uname -s`" in
*win32* | *WIN32*)
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:650: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="cl"
break
fi
done
IFS="$ac_save_ifs"
fi
fi
CC="$ac_cv_prog_CC"
if test -n "$CC"; then
echo "$ac_t""$CC" 1>&6
else
echo "$ac_t""no" 1>&6
fi
;;
esac
fi
test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
fi fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
echo "configure:643: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 echo "configure:682: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS' ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext << EOF
#line 653 "configure"
#line 693 "configure"
#include "confdefs.h" #include "confdefs.h"
main(){return(0);} main(){return(0);}
EOF EOF
if { (eval echo configure:657: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then if { (eval echo configure:698: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler. # If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then if (./conftest; exit) 2>/dev/null; then
@ -667,18 +708,24 @@ else
ac_cv_prog_cc_works=no ac_cv_prog_cc_works=no
fi fi
rm -fr conftest* rm -fr conftest*
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
if test $ac_cv_prog_cc_works = no; then if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
echo "configure:677: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "configure:724: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
echo "configure:682: checking whether we are using GNU C" >&5 echo "configure:729: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -687,7 +734,7 @@ else
yes; yes;
#endif #endif
EOF EOF
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:691: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:738: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes ac_cv_prog_gcc=yes
else else
ac_cv_prog_gcc=no ac_cv_prog_gcc=no
@ -698,11 +745,15 @@ echo "$ac_t""$ac_cv_prog_gcc" 1>&6
if test $ac_cv_prog_gcc = yes; then if test $ac_cv_prog_gcc = yes; then
GCC=yes GCC=yes
ac_test_CFLAGS="${CFLAGS+set}" else
ac_save_CFLAGS="$CFLAGS" GCC=
CFLAGS= fi
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
echo "configure:706: checking whether ${CC-cc} accepts -g" >&5 ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
echo "configure:757: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -717,16 +768,20 @@ rm -f conftest*
fi fi
echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
if test "$ac_test_CFLAGS" = set; then if test "$ac_test_CFLAGS" = set; then
CFLAGS="$ac_save_CFLAGS" CFLAGS="$ac_save_CFLAGS"
elif test $ac_cv_prog_cc_g = yes; then elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
CFLAGS="-g -O2" CFLAGS="-g -O2"
else else
CFLAGS="-O2" CFLAGS="-g"
fi fi
else else
GCC= if test "$GCC" = yes; then
test "${CFLAGS+set}" = set || CFLAGS="-g" CFLAGS="-O2"
else
CFLAGS=
fi
fi fi
else else
@ -734,7 +789,7 @@ else
fi fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
echo "configure:738: checking how to run the C preprocessor" >&5 echo "configure:793: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory. # On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then if test -n "$CPP" && test -d "$CPP"; then
CPP= CPP=
@ -749,14 +804,14 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser, # On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. # not just through cpp.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 753 "configure" #line 808 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <assert.h> #include <assert.h>
Syntax Error Syntax Error
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:759: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:814: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
: :
else else
@ -766,14 +821,31 @@ else
rm -rf conftest* rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp" CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 770 "configure" #line 825 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <assert.h> #include <assert.h>
Syntax Error Syntax Error
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:776: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } { (eval echo configure:831: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out` ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
#line 842 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:848: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then if test -z "$ac_err"; then
: :
else else
@ -785,6 +857,8 @@ else
fi fi
rm -f conftest* rm -f conftest*
fi fi
rm -f conftest*
fi
rm -f conftest* rm -f conftest*
ac_cv_prog_CPP="$CPP" ac_cv_prog_CPP="$CPP"
fi fi
@ -807,15 +881,16 @@ if test "$neo_ok" = "yes"; then
# Extract the first word of "gcc", so it can be a program name with args. # Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2 set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:811: checking for $ac_word" >&5 echo "configure:885: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
if test -n "$CC"; then if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test. ac_cv_prog_CC="$CC" # Let the user override the test.
else else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
for ac_dir in $PATH; do ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=. test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="gcc" ac_cv_prog_CC="gcc"
@ -836,16 +911,17 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args. # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2 set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:840: checking for $ac_word" >&5 echo "configure:915: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
if test -n "$CC"; then if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test. ac_cv_prog_CC="$CC" # Let the user override the test.
else else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_prog_rejected=no ac_prog_rejected=no
for ac_dir in $PATH; do ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=. test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then if test -f $ac_dir/$ac_word; then
if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
@ -880,25 +956,61 @@ else
echo "$ac_t""no" 1>&6 echo "$ac_t""no" 1>&6
fi fi
if test -z "$CC"; then
case "`uname -s`" in
*win32* | *WIN32*)
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:966: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="cl"
break
fi
done
IFS="$ac_save_ifs"
fi
fi
CC="$ac_cv_prog_CC"
if test -n "$CC"; then
echo "$ac_t""$CC" 1>&6
else
echo "$ac_t""no" 1>&6
fi
;;
esac
fi
test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
fi fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
echo "configure:888: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 echo "configure:998: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS' ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext << EOF
#line 898 "configure"
#line 1009 "configure"
#include "confdefs.h" #include "confdefs.h"
main(){return(0);} main(){return(0);}
EOF EOF
if { (eval echo configure:902: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then if { (eval echo configure:1014: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler. # If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then if (./conftest; exit) 2>/dev/null; then
@ -912,18 +1024,24 @@ else
ac_cv_prog_cc_works=no ac_cv_prog_cc_works=no
fi fi
rm -fr conftest* rm -fr conftest*
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
if test $ac_cv_prog_cc_works = no; then if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
echo "configure:922: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "configure:1040: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
echo "configure:927: checking whether we are using GNU C" >&5 echo "configure:1045: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -932,7 +1050,7 @@ else
yes; yes;
#endif #endif
EOF EOF
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:936: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1054: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes ac_cv_prog_gcc=yes
else else
ac_cv_prog_gcc=no ac_cv_prog_gcc=no
@ -943,11 +1061,15 @@ echo "$ac_t""$ac_cv_prog_gcc" 1>&6
if test $ac_cv_prog_gcc = yes; then if test $ac_cv_prog_gcc = yes; then
GCC=yes GCC=yes
ac_test_CFLAGS="${CFLAGS+set}" else
ac_save_CFLAGS="$CFLAGS" GCC=
CFLAGS= fi
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
echo "configure:951: checking whether ${CC-cc} accepts -g" >&5 ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
echo "configure:1073: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -962,16 +1084,20 @@ rm -f conftest*
fi fi
echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
if test "$ac_test_CFLAGS" = set; then if test "$ac_test_CFLAGS" = set; then
CFLAGS="$ac_save_CFLAGS" CFLAGS="$ac_save_CFLAGS"
elif test $ac_cv_prog_cc_g = yes; then elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
CFLAGS="-g -O2" CFLAGS="-g -O2"
else else
CFLAGS="-O2" CFLAGS="-g"
fi fi
else else
GCC= if test "$GCC" = yes; then
test "${CFLAGS+set}" = set || CFLAGS="-g" CFLAGS="-O2"
else
CFLAGS=
fi
fi fi
else else
@ -1005,28 +1131,30 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
# SunOS /usr/etc/install # SunOS /usr/etc/install
# IRIX /sbin/install # IRIX /sbin/install
# AIX /bin/install # AIX /bin/install
# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args # AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh. # ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:1013: checking for a BSD compatible install" >&5 echo "configure:1140: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
for ac_dir in $PATH; do for ac_dir in $PATH; do
# Account for people who put trailing slashes in PATH elements. # Account for people who put trailing slashes in PATH elements.
case "$ac_dir/" in case "$ac_dir/" in
/|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
*) *)
# OSF1 and SCO ODT 3.0 have their own names for install. # OSF1 and SCO ODT 3.0 have their own names for install.
for ac_prog in ginstall installbsd scoinst install; do # Don't use installbsd from OSF since it installs stuff as root
# by default.
for ac_prog in ginstall scoinst install; do
if test -f $ac_dir/$ac_prog; then if test -f $ac_dir/$ac_prog; then
if test $ac_prog = install && if test $ac_prog = install &&
grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention. # AIX install. It has an incompatible calling convention.
# OSF/1 installbsd also uses dspmsg, but is usable.
: :
else else
ac_cv_path_install="$ac_dir/$ac_prog -c" ac_cv_path_install="$ac_dir/$ac_prog -c"
@ -1056,20 +1184,23 @@ echo "$ac_t""$INSTALL" 1>&6
# It thinks the first close brace ends the variable substitution. # It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
# Extract the first word of "ranlib", so it can be a program name with args. # Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2 set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1065: checking for $ac_word" >&5 echo "configure:1195: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
if test -n "$RANLIB"; then if test -n "$RANLIB"; then
ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
for ac_dir in $PATH; do ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=. test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then if test -f $ac_dir/$ac_word; then
ac_cv_prog_RANLIB="ranlib" ac_cv_prog_RANLIB="ranlib"
@ -1170,8 +1301,8 @@ DL_LIBS=$TCL_DL_LIBS
LD_FLAGS=$TCL_LD_FLAGS LD_FLAGS=$TCL_LD_FLAGS
NEO_LD_SEARCH_FLAGS=$TCL_LD_SEARCH_FLAGS NEO_LD_SEARCH_FLAGS=$TCL_LD_SEARCH_FLAGS
eval "NEO_SHARED_LIB_FILE=libldap${TCL_SHARED_LIB_SUFFIX}" eval "NEO_SHARED_LIB_FILE=libldaptcl${TCL_SHARED_LIB_SUFFIX}"
eval "NEO_UNSHARED_LIB_FILE=libldap${TCL_UNSHARED_LIB_SUFFIX}" eval "NEO_UNSHARED_LIB_FILE=libldaptcl${TCL_UNSHARED_LIB_SUFFIX}"
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# The statements below define a collection of symbols related to # The statements below define a collection of symbols related to
@ -1192,7 +1323,7 @@ fi
if test "$ok" = "yes" -a "${SHLIB_SUFFIX}" != ""; then if test "$ok" = "yes" -a "${SHLIB_SUFFIX}" != ""; then
NEO_SHLIB_CFLAGS="${SHLIB_CFLAGS}" NEO_SHLIB_CFLAGS="${SHLIB_CFLAGS}"
eval "NEO_LIB_FILE=libldaptcl${TCL_SHARED_LIB_SUFFIX}" eval "NEO_LIB_FILE=libldaptcl${TCL_SHARED_LIB_SUFFIX}"
MAKE_LIB="\${SHLIB_LD} $TCL_LIB_HNAME -o ${NEO_LIB_FILE} \${OBJS}" MAKE_LIB="\${SHLIB_LD} $TCL_LIB_HNAME -o ${NEO_LIB_FILE} \${OBJS} \${LDAP_LIBFLAGS}"
RANLIB=":" RANLIB=":"
else else
NEO_SHLIB_CFLAGS="" NEO_SHLIB_CFLAGS=""
@ -1256,6 +1387,7 @@ ldapbuild=yes
VERSION=${NEO_VERSION} VERSION=${NEO_VERSION}
# Note: in the following variable, it's important to use the absolute # Note: in the following variable, it's important to use the absolute
# path name of the Tcl directory rather than "..": this is because # path name of the Tcl directory rather than "..": this is because
@ -1327,7 +1459,7 @@ EOF
# Ultrix sh set writes to stderr and can't be redirected directly, # Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars. # and sets the high bit in the cache file unless we assign to the vars.
(set) 2>&1 | (set) 2>&1 |
case `(ac_space=' '; set) 2>&1` in case `(ac_space=' '; set | grep ac_space) 2>&1` in
*ac_space=\ *) *ac_space=\ *)
# `set' does not quote correctly, so add quotes (double-quote substitution # `set' does not quote correctly, so add quotes (double-quote substitution
# turns \\\\ into \\, and sed turns \\ into \). # turns \\\\ into \\, and sed turns \\ into \).
@ -1406,7 +1538,7 @@ do
echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v) -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
echo "$CONFIG_STATUS generated by autoconf version 2.12" echo "$CONFIG_STATUS generated by autoconf version 2.13"
exit 0 ;; exit 0 ;;
-help | --help | --hel | --he | --h) -help | --help | --hel | --he | --h)
echo "\$ac_cs_usage"; exit 0 ;; echo "\$ac_cs_usage"; exit 0 ;;
@ -1426,9 +1558,11 @@ sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
$ac_vpsub $ac_vpsub
$extrasub $extrasub
s%@SHELL@%$SHELL%g
s%@CFLAGS@%$CFLAGS%g s%@CFLAGS@%$CFLAGS%g
s%@CPPFLAGS@%$CPPFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g
s%@CXXFLAGS@%$CXXFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g
s%@FFLAGS@%$FFLAGS%g
s%@DEFS@%$DEFS%g s%@DEFS@%$DEFS%g
s%@LDFLAGS@%$LDFLAGS%g s%@LDFLAGS@%$LDFLAGS%g
s%@LIBS@%$LIBS%g s%@LIBS@%$LIBS%g
@ -1450,6 +1584,7 @@ s%@mandir@%$mandir%g
s%@CC@%$CC%g s%@CC@%$CC%g
s%@CPP@%$CPP%g s%@CPP@%$CPP%g
s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
s%@INSTALL_DATA@%$INSTALL_DATA%g s%@INSTALL_DATA@%$INSTALL_DATA%g
s%@RANLIB@%$RANLIB%g s%@RANLIB@%$RANLIB%g
s%@TK_LIBS@%$TK_LIBS%g s%@TK_LIBS@%$TK_LIBS%g
@ -1462,6 +1597,7 @@ s%@ldaplibflags@%$ldaplibflags%g
s%@ldapinclude@%$ldapinclude%g s%@ldapinclude@%$ldapinclude%g
s%@ldapbuild@%$ldapbuild%g s%@ldapbuild@%$ldapbuild%g
s%@ldapdir@%$ldapdir%g s%@ldapdir@%$ldapdir%g
s%@ldapincdir@%$ldapincdir%g
s%@DL_LIBS@%$DL_LIBS%g s%@DL_LIBS@%$DL_LIBS%g
s%@LD_FLAGS@%$LD_FLAGS%g s%@LD_FLAGS@%$LD_FLAGS%g
s%@MATH_LIBS@%$MATH_LIBS%g s%@MATH_LIBS@%$MATH_LIBS%g

View File

@ -2,11 +2,11 @@ dnl This file is an input file used by the GNU "autoconf" program to
dnl generate the file "configure", which is run during Tk installation dnl generate the file "configure", which is run during Tk installation
dnl to configure the system for the local environment. dnl to configure the system for the local environment.
AC_INIT(neoXldap.c) AC_INIT(neoXldap.c)
# $Id: configure.in,v 1.1 1999/02/10 22:56:49 kunkee Exp $ # $Id: configure.in,v 1.3 1999/08/03 05:23:03 kunkee Exp $
NEO_VERSION=1.0 NEO_VERSION=1.2
NEO_MAJOR_VERSION=1 NEO_MAJOR_VERSION=1
NEO_MINOR_VERSION=0 NEO_MINOR_VERSION=2
VERSION=${NEO_VERSION} VERSION=${NEO_VERSION}
if test "${prefix}" = "NONE"; then if test "${prefix}" = "NONE"; then
@ -109,8 +109,8 @@ DL_LIBS=$TCL_DL_LIBS
LD_FLAGS=$TCL_LD_FLAGS LD_FLAGS=$TCL_LD_FLAGS
NEO_LD_SEARCH_FLAGS=$TCL_LD_SEARCH_FLAGS NEO_LD_SEARCH_FLAGS=$TCL_LD_SEARCH_FLAGS
eval "NEO_SHARED_LIB_FILE=libldap${TCL_SHARED_LIB_SUFFIX}" eval "NEO_SHARED_LIB_FILE=libldaptcl${TCL_SHARED_LIB_SUFFIX}"
eval "NEO_UNSHARED_LIB_FILE=libldap${TCL_UNSHARED_LIB_SUFFIX}" eval "NEO_UNSHARED_LIB_FILE=libldaptcl${TCL_UNSHARED_LIB_SUFFIX}"
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# The statements below define a collection of symbols related to # The statements below define a collection of symbols related to
@ -126,7 +126,7 @@ AC_ARG_ENABLE(shared,
if test "$ok" = "yes" -a "${SHLIB_SUFFIX}" != ""; then if test "$ok" = "yes" -a "${SHLIB_SUFFIX}" != ""; then
NEO_SHLIB_CFLAGS="${SHLIB_CFLAGS}" NEO_SHLIB_CFLAGS="${SHLIB_CFLAGS}"
eval "NEO_LIB_FILE=libldaptcl${TCL_SHARED_LIB_SUFFIX}" eval "NEO_LIB_FILE=libldaptcl${TCL_SHARED_LIB_SUFFIX}"
MAKE_LIB="\${SHLIB_LD} $TCL_LIB_HNAME -o ${NEO_LIB_FILE} \${OBJS}" MAKE_LIB="\${SHLIB_LD} $TCL_LIB_HNAME -o ${NEO_LIB_FILE} \${OBJS} \${LDAP_LIBFLAGS}"
RANLIB=":" RANLIB=":"
else else
NEO_SHLIB_CFLAGS="" NEO_SHLIB_CFLAGS=""
@ -169,6 +169,7 @@ AC_SUBST(ldaplibflags)
AC_SUBST(ldapinclude) AC_SUBST(ldapinclude)
AC_SUBST(ldapbuild) AC_SUBST(ldapbuild)
AC_SUBST(ldapdir) AC_SUBST(ldapdir)
AC_SUBST(ldapincdir)
VERSION=${NEO_VERSION} VERSION=${NEO_VERSION}

View File

@ -26,7 +26,7 @@ A new command by the name of \fIcommand\fR will be created to access
the LDAP database at \fIhostlist\fR. \fIhostlist\fR may contain elements the LDAP database at \fIhostlist\fR. \fIhostlist\fR may contain elements
of the format \fBhost:port\fR if a port other than the default LDAP port of the format \fBhost:port\fR if a port other than the default LDAP port
of 389 is required. The LDAP library will attempt to connect to each of 389 is required. The LDAP library will attempt to connect to each
host in turn until it succeeds. host in turn until it succeeds or exhausts the list.
.PP .PP
The \fBexplode\fR form provides a means (via ldap_explode(3)) to explode a DN The \fBexplode\fR form provides a means (via ldap_explode(3)) to explode a DN
into its component parts. \fB-nonames\fR strips off the attribute names, into its component parts. \fB-nonames\fR strips off the attribute names,
@ -64,9 +64,6 @@ deferred until we actually try to do something.
For the purposes of this example, we're going to assume that "foo" is the For the purposes of this example, we're going to assume that "foo" is the
command created by opening a connection using "ldap open". command created by opening a connection using "ldap open".
Note: Karl is particularly dissatisfied with the syntax of this option,
so it is one of the most likely things to change in a subsequent release.
.SH BINDING .SH BINDING
After a connection is made to an LDAP server, an LDAP bind operation must After a connection is made to an LDAP server, an LDAP bind operation must
@ -74,11 +71,10 @@ be performed before other operations can be attempted over the connection.
Both simple authentication and kerberos authentication are available. Both simple authentication and kerberos authentication are available.
LDAP version 3 supports many new "SSL"-style authentication and encryption LDAP version 3 supports many new "SSL"-style authentication and encryption
systems, which are not currently supported by the UMich server, and hence systems, which are not currently supported by the OpenLDAP v1.2 server, and
by this interface package. hence by this interface package.
Currently simple authentication, and kerberos-based authentication, are Currently simple and kerberos-based authentication, are supported.
supported.
To use LDAP and still have reasonable security in a networked, To use LDAP and still have reasonable security in a networked,
Internet/Intranet environment, secure shell can be used to setup Internet/Intranet environment, secure shell can be used to setup
@ -140,17 +136,19 @@ This creates a new distinguished name and defines zero or more attributes.
"attributePairList" is a list of key-value pairs, the same as would "attributePairList" is a list of key-value pairs, the same as would
be returned by "array get" if an array had been set up containing the be returned by "array get" if an array had been set up containing the
key-value pairs. Note that, right now, the sort of lowest-level pair key-value pairs.
of the DN must also appear in the attributePairList, as in:
foo add "cn=karl, ou=People, o=NeoSoft Inc, c=US" {cn karl ...} foo add "cn=karl, ou=People, o=NeoSoft Inc, c=US" {cn karl ...}
Some directory servers and/or their client SDKs will automatically
add the leaf attribute value for you.
Here is a more precise description of how an attributePairList looks: Here is a more precise description of how an attributePairList looks:
{cn {karl {Karl Lehenbauer}} telephone 713-968-5800} {cn {karl {Karl Lehenbauer}} telephone 713-968-5800}
Note here that two cn values, "karl" and "Karl Lehenbauer", are added. Note here that two cn values, "karl" and "Karl Lehenbauer", are added.
A command error is to write Is it an error to write:
{cn {Karl Lehenbauer}} {cn {Karl Lehenbauer}}
@ -161,11 +159,11 @@ typing hard-coded lists.
We have noticed that the Netscape server will automatically add the We have noticed that the Netscape server will automatically add the
left-most rdn portion of the DN (ie. cn=karl), whereas the University left-most rdn portion of the DN (ie. cn=karl), whereas the University
of Michigan version does not. of Michigan and OpenLDAP 1.2 versions do not.
.SH ADDING, DELETING, AND REPLACING OBJECT ATTRIBUTES .SH ADDING, DELETING, AND REPLACING OBJECT ATTRIBUTES
You can have multiple occurrences of the same attribute in a record. You can have multiple values for a given attribute in an LDAP object.
These are represented in search results, through the Tcl interface, These are represented in search results, through the Tcl interface,
as a list. as a list.
@ -173,21 +171,23 @@ as a list.
This adds key-value pairs to an existing DN. If an attribute being This adds key-value pairs to an existing DN. If an attribute being
added already exists, the new value will be appended to the list. added already exists, the new value will be appended to the list.
If a particular value being added to an attribute already exists in
the object a Tcl error is raised.
foo replace_attributes dn attributePairList foo replace_attributes dn attributePairList
This replaces specified key-value pairs in an existing DN, leaving This replaces the specified attributes in an existing DN, leaving
unnamed ones untouched. unnamed ones untouched. Any previous values for the supplied attributes
(if any) are discarded.
foo delete_attributes dn attributePairList foo delete_attributes dn attributePairList
This deletes attributes in the list. If a pair is "foo {bar snap}" and This deletes attributes in the list. If an attribute "foo" has the
you delete "foo bar", "foo" will still have "snap". value list {bar snap}, and you delete using the attributePairList "foo bar",
"foo" will still have "snap".
If you provide an empty string ("") for the value part of the key-value If you provide an empty string ("") for the value list,
pair, the entire attribute will be deleted. To reiterate, if you provide the entire attribute will be deleted.
a non-empty string for the value part, only that value will be removed
from the value list.
.SH SEARCHING .SH SEARCHING
@ -219,6 +219,10 @@ search criteria.
controlArray(attributes) is a list of attributes to be fetched. controlArray(attributes) is a list of attributes to be fetched.
If not specified, all attributes are fetched. If not specified, all attributes are fetched.
controlArray(timeout) a timeout value in seconds (may contain
fractional values -- extremely very small values are useful
for forcing timeout conditions to test timeouts).
For each matching record, destArray is populated with none, For each matching record, destArray is populated with none,
some or all attribute-value pairs. some or all attribute-value pairs.
@ -229,8 +233,8 @@ version.
.SH CACHING (Note: Netscape clients do not have caching interfaces). .SH CACHING (Note: Netscape clients do not have caching interfaces).
The UMich LDAP library offers the client application fairly fine- The UMich and OpenLDAP client libraries offers the client application fairly
grained control of caching of results retrieved from searches, fine-grained control of caching of results retrieved from searches,
offering significant performance improvement and reduced offering significant performance improvement and reduced
network traffic. network traffic.
@ -241,7 +245,7 @@ To enable caching of data received from an LDAP connection,
foo cache enable timeout maxmem foo cache enable timeout maxmem
...where timeout is specified in seconds, and maxmem is the ...where timeout is specified in seconds, and maxmem is the
maximum memory to be used fo caching, in bytes. maximum memory to be used for caching, in bytes.
If maxmem is 0, the cache size is restricted only by the timeout. If maxmem is 0, the cache size is restricted only by the timeout.
@ -268,7 +272,10 @@ To enable caching of data received from an LDAP connection,
This should be used, for example, after doing an add_attributes, This should be used, for example, after doing an add_attributes,
delete_attributes, or replace_attributes (ldap_modify(3)) delete_attributes, or replace_attributes (ldap_modify(3))
involving the requested DN. involving the requested DN. Generally this should not be needed,
as the Tcl interface automatically performs this operation on
any dn that is modified (add,replace,delete) while caching is
enabled.
foo cache no_errors foo cache no_errors
@ -291,7 +298,8 @@ Because we used the new "Tcl object" C interfaces, this package only works
with Tcl 8.0 or above. with Tcl 8.0 or above.
This package interfaces with the University of Michigan LDAP protocol This package interfaces with the University of Michigan LDAP protocol
package, version 3.3, an implementation of version 2 of the LDAP protocol. package, version 3.3, and OpenLDAP version 1.2, both of which are
implementations of version 2 of the LDAP protocol.
Although an LDAP client (or server) could be written in native Tcl 8.0, Although an LDAP client (or server) could be written in native Tcl 8.0,
as Tcl 8.0 and above can do binary I/O, and Tcl 8 and above have strings as Tcl 8.0 and above can do binary I/O, and Tcl 8 and above have strings
@ -330,8 +338,8 @@ related to LDAP services.
.SH AUTHORS .SH AUTHORS
It was written by Karl Lehenbauer, of NeoSoft, Inc., in August and It was written by Karl Lehenbauer, of NeoSoft, Inc., in August and
September of 1997. Ldap explode, and numerous bug fixes by Randy September of 1997. Ldap explode, and numerous bug fixes and extensions
Kunkee, also of NeoSoft, Inc., in 1998. by Randy Kunkee, also of NeoSoft, Inc., in 1998-1999.
.SH KEYWORDS .SH KEYWORDS
element, join, list, separator element, join, list, separator

View File

@ -0,0 +1,33 @@
#
# ldaperr.tcl: scan ldap.h for error return codes for initializing
# errorCode table.
#
proc genstrings {path} {
set fp [open $path]
while {[gets $fp line] != -1 &&
![string match "#define LDAP_SUCCESS*" $line]} { }
puts "/* This file automatically generated, hand edit at your own risk! */"
puts -nonewline "char *ldaptclerrorcode\[\] = {
NULL"
set lasterr 0
while {[gets $fp line] != -1} {
if {[clength $line] == 0 || [ctype space $line]} continue
if {![string match #define* $line]} break
if {![string match "#define LDAP_*" $line]} continue
lassign $line define macro value
incr lasterr
while {$lasterr < $value} {
puts -nonewline ",\n\tNULL"
incr lasterr
}
puts -nonewline ",\n\t\"$macro\""
}
puts "\n};"
puts "#define LDAPTCL_MAXERR\t$value"
}
#cmdtrace on
if !$tcl_interactive {
genstrings [lindex $argv 0]
}

View File

@ -23,7 +23,7 @@
* Requests for permission may be sent to NeoSoft Inc, 1770 St. James Place, * Requests for permission may be sent to NeoSoft Inc, 1770 St. James Place,
* Suite 500, Houston, TX, 77056. * Suite 500, Houston, TX, 77056.
* *
* $Id: neoXldap.c,v 1.1 1999/02/10 22:56:49 kunkee Exp $ * $Id: neoXldap.c,v 1.5 1999/08/03 05:23:03 kunkee Exp $
* *
*/ */
@ -34,7 +34,12 @@
* Umich-3.3 client code. The UMICH_LDAP define is used to include * Umich-3.3 client code. The UMICH_LDAP define is used to include
* code that will work with the Umich-3.3 LDAP, but not with Netscape's * code that will work with the Umich-3.3 LDAP, but not with Netscape's
* SDK. OpenLDAP may support some of these, but they have not been tested. * SDK. OpenLDAP may support some of these, but they have not been tested.
* Current support is by Randy Kunkee. * Currently supported by Randy Kunkee (kunkee@OpenLDAP.org).
*/
/*
* Add timeout to controlArray to set timeout for ldap_result.
* 4/14/99 - Randy
*/ */
#include "tclExtend.h" #include "tclExtend.h"
@ -42,6 +47,8 @@
#include <lber.h> #include <lber.h>
#include <ldap.h> #include <ldap.h>
#include <string.h> #include <string.h>
#include <sys/time.h>
#include <math.h>
/* /*
* Macros to do string compares. They pre-check the first character before * Macros to do string compares. They pre-check the first character before
@ -50,6 +57,8 @@
#define STREQU(str1, str2) \ #define STREQU(str1, str2) \
(((str1) [0] == (str2) [0]) && (strcmp (str1, str2) == 0)) (((str1) [0] == (str2) [0]) && (strcmp (str1, str2) == 0))
#define STRNEQU(str1, str2, n) \
(((str1) [0] == (str2) [0]) && (strncmp (str1, str2, n) == 0))
/* /*
* The following section defines some common macros used by the rest * The following section defines some common macros used by the rest
@ -58,8 +67,8 @@
* against the Netscape LDAP server and the much more reliable SDK, * against the Netscape LDAP server and the much more reliable SDK,
* and then again backported to the Umich-3.3 client code. * and then again backported to the Umich-3.3 client code.
*/ */
#define OPEN_LDAP 1
#if defined(LDAP_API_VERSION) #if defined(OPEN_LDAP)
/* LDAP_API_VERSION must be defined per the current draft spec /* LDAP_API_VERSION must be defined per the current draft spec
** it's value will be assigned RFC number. However, as ** it's value will be assigned RFC number. However, as
** no RFC is defined, it's value is currently implementation ** no RFC is defined, it's value is currently implementation
@ -67,41 +76,92 @@
** In OpenLDAP 2.x-devel, its 2000 + the draft number, ie 2002. ** In OpenLDAP 2.x-devel, its 2000 + the draft number, ie 2002.
** This section is for OPENLDAP. ** This section is for OPENLDAP.
*/ */
#define ldap_attributefree(p) ldap_memfree(p) #define ldap_memfree(p) free(p)
#ifdef LDAP_OPT_ERROR_NUMBER
#define ldap_get_lderrno(ld) (ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &lderrno), lderrno)
#else
#define ldap_get_lderrno(ld) (ld->ld_errno)
#endif
#define LDAP_ERR_STRING(ld) \ #define LDAP_ERR_STRING(ld) \
ldap_err2string(ldap_get_lderrno(ldap)) ldap_err2string(ldap_get_lderrno(ld))
#elif defined( LDAP_OPT_SIZELIMIT ) #elif defined( LDAP_OPT_SIZELIMIT )
/* /*
** Netscape SDK w/ ldap_set_option, ldap_get_option ** Netscape SDK w/ ldap_set_option, ldap_get_option
*/ */
#define ldap_attributefree(p) ldap_memfree(p)
#define LDAP_ERR_STRING(ld) \ #define LDAP_ERR_STRING(ld) \
ldap_err2string(ldap_get_lderrno(ldap, (char**)NULL, (char**)NULL)) ldap_err2string(ldap_get_lderrno(ldap))
#else #else
/* U-Mich/OpenLDAP 1.x API */ /* U-Mich/OpenLDAP 1.x API */
/* RFC-1823 w/ changes */ /* RFC-1823 w/ changes */
#define UMICH_LDAP #define UMICH_LDAP 1
#define ldap_memfree(p) free(p) #define ldap_memfree(p) free(p)
#define ldap_ber_free(p, n) ber_free(p, n) #define ldap_ber_free(p, n) ber_free(p, n)
#define ldap_get_lderrno(ld, dummy1, dummy2) (ld->ld_errno)
#define ldap_value_free_len(bvals) ber_bvecfree(bvals) #define ldap_value_free_len(bvals) ber_bvecfree(bvals)
#define ldap_attributefree(p) #define ldap_get_lderrno(ld) (ld->ld_errno)
#define LDAP_ERR_STRING(ld) \ #define LDAP_ERR_STRING(ld) \
ldap_err2string(ldap_get_lderrno(ldap)) ldap_err2string(ld->ld_errno)
#endif #endif
#if defined(LDAP_API_VERSION) typedef struct ldaptclobj {
#ifdef LDAP_OPT_ERROR_NUMBER LDAP *ldap;
static int ldap_get_lderrno(LDAP *ld) int caching; /* flag 1/0 if caching is enabled */
long timeout; /* timeout from last cache enable */
long maxmem; /* maxmem from last cache enable */
Tcl_Obj *trapCmdObj; /* error handler */
int *traplist; /* list of errorCodes to trap */
int flags;
} LDAPTCL;
#define LDAPTCL_INTERRCODES 0x001
#include "ldaptclerr.h"
static
LDAP_SetErrorCode(LDAPTCL *ldaptcl, int code, Tcl_Interp *interp)
{ {
int ld_errno = 0; char shortbuf[16];
ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, (void*)&ld_errno); char *errp;
return ld_errno; int lderrno;
if (code == -1)
code = ldap_get_lderrno(ldaptcl->ldap);
if ((ldaptcl->flags & LDAPTCL_INTERRCODES) || code > LDAPTCL_MAXERR ||
ldaptclerrorcode[code] == NULL) {
sprintf(shortbuf, "0x%03x", code);
errp = shortbuf;
} else
errp = ldaptclerrorcode[code];
Tcl_SetErrorCode(interp, errp, NULL);
if (ldaptcl->trapCmdObj) {
int *i;
Tcl_Obj *cmdObj;
if (ldaptcl->traplist != NULL) {
for (i = ldaptcl->traplist; *i && *i != code; i++)
;
if (*i == 0) return;
}
(void) Tcl_EvalObj(interp, ldaptcl->trapCmdObj);
}
} }
#endif
#endif
static
LDAP_ErrorStringToCode(Tcl_Interp *interp, char *s)
{
int offset;
int code;
offset = (strncasecmp(s, "LDAP_", 5) == 0) ? 0 : 5;
for (code = 0; code < LDAPTCL_MAXERR; code++) {
if (!ldaptclerrorcode[code]) continue;
if (strcasecmp(s, ldaptclerrorcode[code]+offset) == 0)
return code;
}
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, s, " is an invalid code", (char *) NULL);
return -1;
}
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
* LDAP_ProcessOneSearchResult -- * LDAP_ProcessOneSearchResult --
@ -119,7 +179,7 @@ static int ldap_get_lderrno(LDAP *ld)
* o TCL_ERROR if an error occured, with error message in interp. * o TCL_ERROR if an error occured, with error message in interp.
*----------------------------------------------------------------------------- *-----------------------------------------------------------------------------
*/ */
static int int
LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj) LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
Tcl_Interp *interp; Tcl_Interp *interp;
LDAP *ldap; LDAP *ldap;
@ -134,6 +194,7 @@ LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
BerElement *ber; BerElement *ber;
struct berval **bvals; struct berval **bvals;
char *dn; char *dn;
int lderrno;
Tcl_UnsetVar (interp, Tcl_GetStringFromObj (destArrayNameObj, NULL), 0); Tcl_UnsetVar (interp, Tcl_GetStringFromObj (destArrayNameObj, NULL), 0);
@ -147,6 +208,8 @@ LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
return TCL_ERROR; return TCL_ERROR;
ldap_memfree(dn); ldap_memfree(dn);
} }
attributeNameObj = Tcl_NewObj();
Tcl_IncrRefCount (attributeNameObj);
for (attributeName = ldap_first_attribute (ldap, entry, &ber); for (attributeName = ldap_first_attribute (ldap, entry, &ber);
attributeName != NULL; attributeName != NULL;
attributeName = ldap_next_attribute(ldap, entry, ber)) { attributeName = ldap_next_attribute(ldap, entry, ber)) {
@ -160,17 +223,17 @@ LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
as an error, we ignore it to present a consistent interface as an error, we ignore it to present a consistent interface
with Netscape's server with Netscape's server
*/ */
attributeNameObj = Tcl_NewStringObj (attributeName, -1);
Tcl_IncrRefCount (attributeNameObj);
attributeDataObj = Tcl_NewObj(); attributeDataObj = Tcl_NewObj();
Tcl_SetStringObj(attributeNameObj, attributeName, -1);
for (i = 0; bvals[i] != NULL; i++) { for (i = 0; bvals[i] != NULL; i++) {
Tcl_Obj *singleAttributeValueObj; Tcl_Obj *singleAttributeValueObj;
singleAttributeValueObj = Tcl_NewStringObj (bvals[i]->bv_val, -1); singleAttributeValueObj = Tcl_NewStringObj(bvals[i]->bv_val, bvals[i]->bv_len);
if (Tcl_ListObjAppendElement (interp, if (Tcl_ListObjAppendElement (interp,
attributeDataObj, attributeDataObj,
singleAttributeValueObj) singleAttributeValueObj)
== TCL_ERROR) { == TCL_ERROR) {
ber_free(ber, 0);
return TCL_ERROR; return TCL_ERROR;
} }
} }
@ -184,10 +247,9 @@ LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
TCL_LEAVE_ERR_MSG) == NULL) { TCL_LEAVE_ERR_MSG) == NULL) {
return TCL_ERROR; return TCL_ERROR;
} }
Tcl_DecrRefCount (attributeNameObj);
} }
ldap_attributefree(attributeName);
} }
Tcl_DecrRefCount (attributeNameObj);
return Tcl_EvalObj (interp, evalCodeObj); return Tcl_EvalObj (interp, evalCodeObj);
} }
@ -213,10 +275,11 @@ LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
* o TCL_ERROR if an error occured, with error message in interp. * o TCL_ERROR if an error occured, with error message in interp.
*----------------------------------------------------------------------------- *-----------------------------------------------------------------------------
*/ */
static int int
LDAP_PerformSearch (interp, ldap, base, scope, attrs, filtpatt, value, destArrayNameObj, evalCodeObj) LDAP_PerformSearch (interp, ldaptcl, base, scope, attrs, filtpatt, value,
destArrayNameObj, evalCodeObj, timeout_p, all, sortattr)
Tcl_Interp *interp; Tcl_Interp *interp;
LDAP *ldap; LDAPTCL *ldaptcl;
char *base; char *base;
int scope; int scope;
char **attrs; char **attrs;
@ -224,93 +287,115 @@ LDAP_PerformSearch (interp, ldap, base, scope, attrs, filtpatt, value, destArray
char *value; char *value;
Tcl_Obj *destArrayNameObj; Tcl_Obj *destArrayNameObj;
Tcl_Obj *evalCodeObj; Tcl_Obj *evalCodeObj;
struct timeval *timeout_p;
int all;
char *sortattr;
{ {
LDAP *ldap = ldaptcl->ldap;
char filter[BUFSIZ]; char filter[BUFSIZ];
int resultCode; int resultCode;
int errorCode; int errorCode;
int abandon; int abandon;
int tclResult = TCL_OK; int tclResult = TCL_OK;
int msgid; int msgid;
LDAPMessage *resultMessage; LDAPMessage *resultMessage = 0;
LDAPMessage *entryMessage; LDAPMessage *entryMessage = 0;
char *sortKey;
Tcl_Obj *resultObj; int lderrno;
int lderr;
resultObj = Tcl_GetObjResult (interp);
sprintf(filter, filtpatt, value); sprintf(filter, filtpatt, value);
fflush(stderr);
if ((msgid = ldap_search (ldap, base, scope, filter, attrs, 0)) == -1) { if ((msgid = ldap_search (ldap, base, scope, filter, attrs, 0)) == -1) {
Tcl_AppendStringsToObj (resultObj, Tcl_AppendResult (interp,
"LDAP start search error: ", "LDAP start search error: ",
LDAP_ERR_STRING(ldap), LDAP_ERR_STRING(ldap),
(char *)NULL); (char *)NULL);
LDAP_SetErrorCode(ldaptcl, -1, interp);
return TCL_ERROR; return TCL_ERROR;
} }
abandon = 0; abandon = 0;
while ((resultCode = ldap_result (ldap, if (sortattr)
msgid, all = 1;
0, tclResult = TCL_OK;
NULL, while (!abandon) {
&resultMessage)) == LDAP_RES_SEARCH_ENTRY) { resultCode = ldap_result (ldap, msgid, all, timeout_p, &resultMessage);
if (resultCode != LDAP_RES_SEARCH_RESULT &&
resultCode != LDAP_RES_SEARCH_ENTRY)
break;
if (sortattr) {
sortKey = (strcasecmp(sortattr, "dn") == 0) ? NULL : sortattr;
ldap_sort_entries(ldap, &resultMessage, sortKey, strcasecmp);
}
entryMessage = ldap_first_entry(ldap, resultMessage); entryMessage = ldap_first_entry(ldap, resultMessage);
tclResult = LDAP_ProcessOneSearchResult (interp, while (entryMessage) {
ldap, tclResult = LDAP_ProcessOneSearchResult (interp,
entryMessage, ldap,
destArrayNameObj, entryMessage,
evalCodeObj); destArrayNameObj,
ldap_msgfree(resultMessage); evalCodeObj);
if (tclResult != TCL_OK) { if (tclResult != TCL_OK) {
if (tclResult == TCL_CONTINUE) { if (tclResult == TCL_CONTINUE) {
tclResult = TCL_OK; tclResult = TCL_OK;
} else if (tclResult == TCL_BREAK) { } else if (tclResult == TCL_BREAK) {
tclResult = TCL_OK; tclResult = TCL_OK;
abandon = 1; abandon = 1;
break; break;
} else if (tclResult == TCL_ERROR) { } else if (tclResult == TCL_ERROR) {
char msg[100]; char msg[100];
sprintf(msg, "\n (\"search\" body line %d)", sprintf(msg, "\n (\"search\" body line %d)",
interp->errorLine); interp->errorLine);
Tcl_AddObjErrorInfo(interp, msg, -1); Tcl_AddObjErrorInfo(interp, msg, -1);
abandon = 1; abandon = 1;
break; break;
} else { } else {
abandon = 1; abandon = 1;
break; break;
}
} }
entryMessage = ldap_next_entry(ldap, entryMessage);
} }
if (resultCode == LDAP_RES_SEARCH_RESULT || all)
break;
if (resultMessage)
ldap_msgfree(resultMessage);
resultMessage = NULL;
} }
if (abandon) { if (abandon) {
ldap_abandon(ldap, msgid); if (resultMessage)
} else {
if (resultCode == LDAP_RES_SEARCH_RESULT) {
if ((errorCode = ldap_result2error (ldap, resultMessage, 0))
!= LDAP_SUCCESS) {
Tcl_AppendStringsToObj (resultObj,
"LDAP search error: ",
ldap_err2string(errorCode),
(char *)NULL);
ldap_msgfree(resultMessage);
return TCL_ERROR;
}
}
if (resultCode == -1) {
Tcl_AppendStringsToObj (resultObj,
"LDAP result search error: ",
LDAP_ERR_STRING(ldap),
(char *)NULL);
return TCL_ERROR;
} else
ldap_msgfree(resultMessage); ldap_msgfree(resultMessage);
if (resultCode == LDAP_RES_SEARCH_ENTRY)
ldap_abandon(ldap, msgid);
return tclResult;
}
if (resultCode == -1) {
Tcl_ResetResult (interp);
Tcl_AppendResult (interp,
"LDAP result search error: ",
LDAP_ERR_STRING(ldap),
(char *)NULL);
LDAP_SetErrorCode(ldaptcl, -1, interp);
return TCL_ERROR;
} }
if ((errorCode = ldap_result2error (ldap, resultMessage, 0))
!= LDAP_SUCCESS) {
Tcl_ResetResult (interp);
Tcl_AppendResult (interp,
"LDAP search error: ",
ldap_err2string(errorCode),
(char *)NULL);
if (resultMessage)
ldap_msgfree(resultMessage);
LDAP_SetErrorCode(ldaptcl, errorCode, interp);
return TCL_ERROR;
}
if (resultMessage)
ldap_msgfree(resultMessage);
return tclResult; return tclResult;
} }
@ -326,7 +411,7 @@ LDAP_PerformSearch (interp, ldap, base, scope, attrs, filtpatt, value, destArray
* See the user documentation. * See the user documentation.
*----------------------------------------------------------------------------- *-----------------------------------------------------------------------------
*/ */
static int int
NeoX_LdapTargetObjCmd (clientData, interp, objc, objv) NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
ClientData clientData; ClientData clientData;
Tcl_Interp *interp; Tcl_Interp *interp;
@ -335,13 +420,15 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
{ {
char *command; char *command;
char *subCommand; char *subCommand;
LDAP *ldap = (LDAP *)clientData; LDAPTCL *ldaptcl = (LDAPTCL *)clientData;
LDAP *ldap = ldaptcl->ldap;
char *dn; char *dn;
int is_add = 0; int is_add = 0;
int is_add_or_modify = 0; int is_add_or_modify = 0;
int mod_op = 0; int mod_op = 0;
char *m, *s, *errmsg; char *m, *s, *errmsg;
int errcode; int errcode;
int tclResult;
Tcl_Obj *resultObj = Tcl_GetObjResult (interp); Tcl_Obj *resultObj = Tcl_GetObjResult (interp);
@ -421,6 +508,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
"LDAP bind error: ", "LDAP bind error: ",
ldap_err2string(errcode), ldap_err2string(errcode),
(char *)NULL); (char *)NULL);
LDAP_SetErrorCode(ldaptcl, errcode, interp);
return TCL_ERROR; return TCL_ERROR;
} }
return TCL_OK; return TCL_OK;
@ -444,6 +532,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
"LDAP delete error: ", "LDAP delete error: ",
ldap_err2string(errcode), ldap_err2string(errcode),
(char *)NULL); (char *)NULL);
LDAP_SetErrorCode(ldaptcl, errcode, interp);
return TCL_ERROR; return TCL_ERROR;
} }
return TCL_OK; return TCL_OK;
@ -472,6 +561,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
" error: ", " error: ",
ldap_err2string(errcode), ldap_err2string(errcode),
(char *)NULL); (char *)NULL);
LDAP_SetErrorCode(ldaptcl, errcode, interp);
return TCL_ERROR; return TCL_ERROR;
} }
return TCL_OK; return TCL_OK;
@ -542,11 +632,11 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
nPairs = attribObjc / 2; nPairs = attribObjc / 2;
modArray = (LDAPMod **)ckalloc (sizeof(LDAPMod *) * (nPairs + 1)); modArray = (LDAPMod **)malloc (sizeof(LDAPMod *) * (nPairs + 1));
modArray[nPairs] = (LDAPMod *) NULL; modArray[nPairs] = (LDAPMod *) NULL;
for (i = 0; i < nPairs; i++) { for (i = 0; i < nPairs; i++) {
mod = modArray[i] = (LDAPMod *) ckalloc (sizeof(LDAPMod)); mod = modArray[i] = (LDAPMod *) malloc (sizeof(LDAPMod));
mod->mod_op = mod_op; mod->mod_op = mod_op;
mod->mod_type = Tcl_GetStringFromObj (attribObjv [i * 2], NULL); mod->mod_type = Tcl_GetStringFromObj (attribObjv [i * 2], NULL);
@ -556,7 +646,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
} }
valPtrs = mod->mod_vals.modv_strvals = \ valPtrs = mod->mod_vals.modv_strvals = \
(char **)ckalloc (sizeof (char *) * (valuesObjc + 1)); (char **)malloc (sizeof (char *) * (valuesObjc + 1));
valPtrs[valuesObjc] = (char *)NULL; valPtrs[valuesObjc] = (char *)NULL;
for (j = 0; j < valuesObjc; j++) { for (j = 0; j < valuesObjc; j++) {
@ -566,7 +656,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
* value be NULL to indicate entire attribute is to be * value be NULL to indicate entire attribute is to be
* deleted */ * deleted */
if ((*valPtrs [j] == '\0') if ((*valPtrs [j] == '\0')
&& (mod->mod_op == LDAP_MOD_DELETE)) { && (mod->mod_op == LDAP_MOD_DELETE || mod->mod_op == LDAP_MOD_REPLACE)) {
valPtrs [j] = NULL; valPtrs [j] = NULL;
} }
} }
@ -576,14 +666,16 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
result = ldap_add_s (ldap, dn, modArray); result = ldap_add_s (ldap, dn, modArray);
} else { } else {
result = ldap_modify_s (ldap, dn, modArray); result = ldap_modify_s (ldap, dn, modArray);
if (ldaptcl->caching)
ldap_uncache_entry (ldap, dn);
} }
/* free the modArray elements, then the modArray itself. */ /* free the modArray elements, then the modArray itself. */
for (i = 0; i < nPairs; i++) { for (i = 0; i < nPairs; i++) {
ckfree ((char *) modArray[i]->mod_vals.modv_strvals); free ((char *) modArray[i]->mod_vals.modv_strvals);
ckfree ((char *) modArray[i]); free ((char *) modArray[i]);
} }
ckfree ((char *) modArray); free ((char *) modArray);
/* FIX: memory cleanup required all over the place here */ /* FIX: memory cleanup required all over the place here */
if (result != LDAP_SUCCESS) { if (result != LDAP_SUCCESS) {
@ -593,6 +685,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
" error: ", " error: ",
ldap_err2string(result), ldap_err2string(result),
(char *)NULL); (char *)NULL);
LDAP_SetErrorCode(ldaptcl, result, interp);
return TCL_ERROR; return TCL_ERROR;
} }
return TCL_OK; return TCL_OK;
@ -617,6 +710,16 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
char *filterPatternString; char *filterPatternString;
char *timeoutString;
double timeoutTime;
struct timeval timeout, *timeout_p;
char *paramString;
int cacheThis = -1;
int all = 0;
char *sortattr;
Tcl_Obj *destArrayNameObj; Tcl_Obj *destArrayNameObj;
Tcl_Obj *evalCodeObj; Tcl_Obj *evalCodeObj;
@ -652,14 +755,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
"filter", "filter",
0); 0);
if (filterPatternString == (char *)NULL) { if (filterPatternString == (char *)NULL) {
Tcl_AppendStringsToObj (resultObj, filterPatternString = "(objectclass=*)";
"required element \"filter\" ",
"is missing from ldap control array \"",
controlArrayName,
"\"",
(char *)NULL);
return TCL_ERROR;
} }
/* Fetch scope setting from control array. /* Fetch scope setting from control array.
@ -671,16 +767,16 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
} else { } else {
if (STREQU(scopeString, "base")) if (STREQU(scopeString, "base"))
scope = LDAP_SCOPE_BASE; scope = LDAP_SCOPE_BASE;
else if (STREQU(scopeString, "onelevel")) else if (STRNEQU(scopeString, "one", 3))
scope = LDAP_SCOPE_ONELEVEL; scope = LDAP_SCOPE_ONELEVEL;
else if (STREQU(scopeString, "subtree")) else if (STRNEQU(scopeString, "sub", 3))
scope = LDAP_SCOPE_SUBTREE; scope = LDAP_SCOPE_SUBTREE;
else { else {
Tcl_AppendStringsToObj (resultObj, Tcl_AppendStringsToObj (resultObj,
"\"scope\" element of \"", "\"scope\" element of \"",
controlArrayName, controlArrayName,
"\" array is not one of ", "\" array is not one of ",
"\"base\", \"one_level\", ", "\"base\", \"onelevel\", ",
"or \"subtree\"", "or \"subtree\"",
(char *) NULL); (char *) NULL);
return TCL_ERROR; return TCL_ERROR;
@ -735,6 +831,38 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
} }
} }
/* Fetch timeout value if there is one
*/
timeoutString = Tcl_GetVar2 (interp,
controlArrayName,
"timeout",
0);
timeout.tv_usec = 0;
if (timeoutString == (char *)NULL) {
timeout_p = NULL;
timeout.tv_sec = 0;
} else {
if (Tcl_GetDouble(interp, timeoutString, &timeoutTime) != TCL_OK)
return TCL_ERROR;
timeout.tv_sec = floor(timeoutTime);
timeout.tv_usec = (timeoutTime-timeout.tv_sec) * 1000000;
timeout_p = &timeout;
}
paramString = Tcl_GetVar2 (interp, controlArrayName, "cache", 0);
if (paramString) {
if (Tcl_GetInt(interp, paramString, &cacheThis) == TCL_ERROR)
return TCL_ERROR;
}
paramString = Tcl_GetVar2 (interp, controlArrayName, "all", 0);
if (paramString) {
if (Tcl_GetInt(interp, paramString, &all) == TCL_ERROR)
return TCL_ERROR;
}
sortattr = Tcl_GetVar2 (interp, controlArrayName, "sort", 0);
#ifdef UMICH_LDAP #ifdef UMICH_LDAP
ldap->ld_deref = deref; ldap->ld_deref = deref;
ldap->ld_timelimit = 0; ldap->ld_timelimit = 0;
@ -742,18 +870,48 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
ldap->ld_options = 0; ldap->ld_options = 0;
#endif #endif
return LDAP_PerformSearch (interp, /* Caching control within the search: if the "cache" control array */
ldap, /* value is set, disable/enable caching accordingly */
#if 0
if (cacheThis >= 0 && ldaptcl->caching != cacheThis) {
if (cacheThis) {
if (ldaptcl->timeout == 0) {
Tcl_SetStringObj(resultObj, "Caching never before enabled, I have no timeout value to use", -1);
return TCL_ERROR;
}
ldap_enable_cache(ldap, ldaptcl->timeout, ldaptcl->maxmem);
}
else
ldap_disable_cache(ldap);
}
#endif
tclResult = LDAP_PerformSearch (interp,
ldaptcl,
baseString, baseString,
scope, scope,
attributesArray, attributesArray,
filterPatternString, filterPatternString,
"", "",
destArrayNameObj, destArrayNameObj,
evalCodeObj); evalCodeObj,
timeout_p,
all,
sortattr);
/* Following the search, if we changed the caching behavior, change */
/* it back. */
#if 0
if (cacheThis >= 0 && ldaptcl->caching != cacheThis) {
if (cacheThis)
ldap_disable_cache(ldap);
else
ldap_enable_cache(ldap, ldaptcl->timeout, ldaptcl->maxmem);
}
#endif
return tclResult;
} }
#if UMICH_LDAP #if defined(UMICH_LDAP) || (defined(OPEN_LDAP) && !defined(LDAP_API_VERSION))
if (STREQU (subCommand, "cache")) { if (STREQU (subCommand, "cache")) {
char *cacheCommand; char *cacheCommand;
@ -779,27 +937,40 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
} }
if (STREQU (cacheCommand, "enable")) { if (STREQU (cacheCommand, "enable")) {
long timeout; long timeout = ldaptcl->timeout;
long maxmem; long maxmem = ldaptcl->maxmem;
if (objc != 5) if (objc > 5)
return TclX_WrongArgs (interp, return TclX_WrongArgs (interp,
objv [0], objv [0],
"cache enable timeout maxmem"); "cache enable ?timeout? ?maxmem?");
if (Tcl_GetLongFromObj (interp, objv [3], &timeout) == TCL_ERROR) if (objc > 3) {
if (Tcl_GetLongFromObj (interp, objv [3], &timeout) == TCL_ERROR)
return TCL_ERROR;
}
if (timeout == 0) {
Tcl_SetStringObj(resultObj,
objc > 3 ? "timeouts must be greater than 0" :
"no previous timeout to reference", -1);
return TCL_ERROR; return TCL_ERROR;
}
if (Tcl_GetLongFromObj (interp, objv [4], &maxmem) == TCL_ERROR) if (objc > 4)
return TCL_ERROR; if (Tcl_GetLongFromObj (interp, objv [4], &maxmem) == TCL_ERROR)
return TCL_ERROR;
if (ldap_enable_cache (ldap, timeout, maxmem) == -1) { if (ldap_enable_cache (ldap, timeout, maxmem) == -1) {
Tcl_AppendStringsToObj (resultObj, Tcl_AppendStringsToObj (resultObj,
"LDAP cache enable error: ", "LDAP cache enable error: ",
LDAP_ERR_STRING(ldap), LDAP_ERR_STRING(ldap),
(char *)NULL); (char *)NULL);
LDAP_SetErrorCode(ldaptcl, -1, interp);
return TCL_ERROR; return TCL_ERROR;
} }
ldaptcl->caching = 1;
ldaptcl->timeout = timeout;
ldaptcl->maxmem = maxmem;
return TCL_OK; return TCL_OK;
} }
@ -807,11 +978,13 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
if (STREQU (cacheCommand, "disable")) { if (STREQU (cacheCommand, "disable")) {
ldap_disable_cache (ldap); ldap_disable_cache (ldap);
ldaptcl->caching = 0;
return TCL_OK; return TCL_OK;
} }
if (STREQU (cacheCommand, "destroy")) { if (STREQU (cacheCommand, "destroy")) {
ldap_destroy_cache (ldap); ldap_destroy_cache (ldap);
ldaptcl->caching = 0;
return TCL_OK; return TCL_OK;
} }
@ -849,6 +1022,75 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
return TCL_ERROR; return TCL_ERROR;
} }
#endif #endif
if (STREQU (subCommand, "trap")) {
Tcl_Obj *listObj, *resultObj;
int *p, l, i, code;
if (objc > 4)
return TclX_WrongArgs (interp, objv [0],
"trap command ?errorCode-list?");
if (objc == 2) {
if (!ldaptcl->trapCmdObj)
return TCL_OK;
resultObj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(interp, resultObj, ldaptcl->trapCmdObj);
if (ldaptcl->traplist) {
listObj = Tcl_NewObj();
for (p = ldaptcl->traplist; *p; p++) {
Tcl_ListObjAppendElement(interp, listObj,
Tcl_NewStringObj(ldaptclerrorcode[*p], -1));
}
Tcl_ListObjAppendElement(interp, resultObj, listObj);
}
Tcl_SetObjResult(interp, resultObj);
return TCL_OK;
}
if (ldaptcl->trapCmdObj) {
Tcl_DecrRefCount (ldaptcl->trapCmdObj);
ldaptcl->trapCmdObj = NULL;
}
if (ldaptcl->traplist) {
free(ldaptcl->traplist);
ldaptcl->traplist = NULL;
}
Tcl_GetStringFromObj(objv[2], &l);
if (l == 0)
return TCL_OK; /* just turn off trap */
ldaptcl->trapCmdObj = objv[2];
Tcl_IncrRefCount (ldaptcl->trapCmdObj);
if (objc < 4)
return TCL_OK; /* no code list */
if (Tcl_ListObjLength(interp, objv[3], &l) != TCL_OK)
return TCL_ERROR;
if (l == 0)
return TCL_OK; /* empty code list */
ldaptcl->traplist = (int*)malloc(sizeof(int) * (l + 1));
ldaptcl->traplist[l] = 0;
for (i = 0; i < l; i++) {
Tcl_ListObjIndex(interp, objv[3], i, &resultObj);
code = LDAP_ErrorStringToCode(interp, Tcl_GetStringFromObj(resultObj, NULL));
if (code == -1) {
free(ldaptcl->traplist);
ldaptcl->traplist = NULL;
return TCL_ERROR;
}
ldaptcl->traplist[i] = code;
}
return TCL_OK;
}
if (STREQU (subCommand, "trapcodes")) {
int code;
Tcl_Obj *resultObj;
Tcl_Obj *stringObj;
resultObj = Tcl_GetObjResult(interp);
for (code = 0; code < LDAPTCL_MAXERR; code++) {
if (!ldaptclerrorcode[code]) continue;
Tcl_ListObjAppendElement(interp, resultObj,
Tcl_NewStringObj(ldaptclerrorcode[code], -1));
}
return TCL_OK;
}
#ifdef LDAP_DEBUG #ifdef LDAP_DEBUG
if (STREQU (subCommand, "debug")) { if (STREQU (subCommand, "debug")) {
if (objc != 3) { if (objc != 3) {
@ -883,9 +1125,15 @@ static void
NeoX_LdapObjDeleteCmd(clientData) NeoX_LdapObjDeleteCmd(clientData)
ClientData clientData; ClientData clientData;
{ {
LDAP *ldap = (LDAP *)clientData; LDAPTCL *ldaptcl = (LDAPTCL *)clientData;
LDAP *ldap = ldaptcl->ldap;
if (ldaptcl->trapCmdObj)
Tcl_DecrRefCount (ldaptcl->trapCmdObj);
if (ldaptcl->traplist)
free(ldaptcl->traplist);
ldap_unbind(ldap); ldap_unbind(ldap);
free((char*) ldaptcl);
} }
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
@ -915,6 +1163,7 @@ NeoX_LdapObjCmd (clientData, interp, objc, objv)
char *ldapHost; char *ldapHost;
int ldapPort = 389; int ldapPort = 389;
LDAP *ldap; LDAP *ldap;
LDAPTCL *ldaptcl;
Tcl_Obj *resultObj = Tcl_GetObjResult (interp); Tcl_Obj *resultObj = Tcl_GetObjResult (interp);
@ -1016,10 +1265,19 @@ NeoX_LdapObjCmd (clientData, interp, objc, objv)
ldap->ld_deref = LDAP_DEREF_NEVER; /* Turn off alias dereferencing */ ldap->ld_deref = LDAP_DEREF_NEVER; /* Turn off alias dereferencing */
#endif #endif
ldaptcl = (LDAPTCL *) malloc(sizeof(LDAPTCL));
ldaptcl->ldap = ldap;
ldaptcl->caching = 0;
ldaptcl->timeout = 0;
ldaptcl->maxmem = 0;
ldaptcl->trapCmdObj = NULL;
ldaptcl->traplist = NULL;
ldaptcl->flags = 0;
Tcl_CreateObjCommand (interp, Tcl_CreateObjCommand (interp,
newCommand, newCommand,
NeoX_LdapTargetObjCmd, NeoX_LdapTargetObjCmd,
(ClientData) ldap, (ClientData) ldaptcl,
NeoX_LdapObjDeleteCmd); NeoX_LdapObjDeleteCmd);
return TCL_OK; return TCL_OK;
} }
@ -1038,6 +1296,6 @@ Tcl_Interp *interp;
NeoX_LdapObjCmd, NeoX_LdapObjCmd,
(ClientData) NULL, (ClientData) NULL,
(Tcl_CmdDeleteProc*) NULL); (Tcl_CmdDeleteProc*) NULL);
Tcl_PkgProvide(interp, "Ldaptcl", "1.1"); Tcl_PkgProvide(interp, "Ldaptcl", VERSION);
return TCL_OK; return TCL_OK;
} }

View File

@ -1 +1 @@
package ifneeded Neo @NEO_VERSION@ "package require Tclx 8.0; load [file join $dir .. @NEO_SHARED_LIB_FILE@] Ldaptcl" package ifneeded Ldaptcl @NEO_VERSION@ "package require Tclx 8.0; load [file join $dir .. @NEO_SHARED_LIB_FILE@] Ldaptcl"