+ make bindings fit to API described as in the LDAP C API draft

+ use automake for building an external module
+ tools for importing c constants
+ numerous changes
This commit is contained in:
eknauel 2003-12-31 15:40:26 +00:00
parent 10c0e539ba
commit 273b96373b
26 changed files with 7206 additions and 711 deletions

View File

@ -1,4 +1,4 @@
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
Foundation, Inc.
This file is free documentation; the Free Software Foundation gives

View File

@ -1,15 +1,2 @@
SUBDIRS= c
SUBDIRS = c scheme
scheme/load-ldap.scm:
(echo '(user)'; \
echo "(open 'dynamic-externals)"; \
echo "(open 'external-calls)"; \
echo '(run '; \
echo " '(let ((initializer-name \"scsh_yp_main\")"; \
echo ' (module-file "$(prefix)/lib/libldap.so"))'; \
echo ' (dynamic-load module-file)'; \
echo ' (call-external (get-external initializer-name))))'; \
echo '(config)'; \
echo '(load "ldap-interfaces.scm")'; \
echo '(load "ldap-packages.scm")'; \
) > $@

View File

@ -1,545 +0,0 @@
# Makefile.in generated by automake 1.7.8 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
scsh_includes = @scsh_includes@
scsh_libraries = @scsh_libraries@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
SUBDIRS = c
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = $(top_builddir)/c/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
ps-recursive install-info-recursive uninstall-info-recursive \
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive
DIST_COMMON = README $(srcdir)/Makefile.in $(srcdir)/configure \
../config.guess ../config.sub ../install-sh ../ltmain.sh \
../missing ../mkinstalldirs AUTHORS COPYING ChangeLog INSTALL \
Makefile.am NEWS aclocal.m4 configure configure.in
DIST_SUBDIRS = $(SUBDIRS)
all: all-recursive
.SUFFIXES:
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)
$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): configure.in
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if (etags --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
else \
include_option=--include; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = .
distdir = $(PACKAGE)-$(VERSION)
am__remove_distdir = \
{ test ! -d $(distdir) \
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr $(distdir); }; }
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
$(mkinstalldirs) $(distdir)/..
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r $(distdir)
dist-gzip: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist dist-all: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
$(am__remove_distdir)
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& cd $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && $(mkinstalldirs) "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist-gzip \
&& rm -f $(distdir).tar.gz \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
$(am__remove_distdir)
@echo "$(distdir).tar.gz is ready for distribution" | \
sed 'h;s/./=/g;p;x;p;x'
distuninstallcheck:
@cd $(distuninstallcheck_dir) \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-libtool \
distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
clean-generic clean-libtool clean-recursive ctags \
ctags-recursive dist dist-all dist-gzip distcheck distclean \
distclean-generic distclean-libtool distclean-recursive \
distclean-tags distcleancheck distdir distuninstallcheck dvi \
dvi-am dvi-recursive info info-am info-recursive install \
install-am install-data install-data-am install-data-recursive \
install-exec install-exec-am install-exec-recursive \
install-info install-info-am install-info-recursive install-man \
install-recursive install-strip installcheck installcheck-am \
installdirs installdirs-am installdirs-recursive \
maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-generic \
mostlyclean-libtool mostlyclean-recursive pdf pdf-am \
pdf-recursive ps ps-am ps-recursive tags tags-recursive \
uninstall uninstall-am uninstall-info-am \
uninstall-info-recursive uninstall-recursive
scheme/load-ldap.scm:
(echo '(user)'; \
echo "(open 'dynamic-externals)"; \
echo "(open 'external-calls)"; \
echo '(run '; \
echo " '(let ((initializer-name \"scsh_yp_main\")"; \
echo ' (module-file "$(prefix)/lib/libldap.so"))'; \
echo ' (dynamic-load module-file)'; \
echo ' (call-external (get-external initializer-name))))'; \
echo '(config)'; \
echo '(load "ldap-interfaces.scm")'; \
echo '(load "ldap-packages.scm")'; \
) > $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,5 +1,18 @@
INCLUDES = -I@top_srcdir@/c -I@scsh_includes@
SCSH= @SCSH@
lib_LTLIBRARIES = libscshldap.la
GENERATED_CODE= ldap-consts.c const-decls-h
SCHEME_DIR= ../scheme
CLEANFILES= $(GENERATED_CODE)
noinst_LTLIBRARIES = libscshldap.la
libscshldap_la_SOURCES = ldap.c
libscshldap_la_LDFLAGS=
$(GENERATED_CODE):
$(SCSH) -lm $(SCHEME_DIR)/ffi-tools-packages.scm \
-lm $(SCHEME_DIR)/ldap-constants.scm \
-o ldap-constants -c '(make-c-files command-line-arguments)' \
`pwd`

535
c/ldap.c
View File

@ -1,43 +1,40 @@
#include "scsh-ldap.h"
/* prototypes */
s48_value scsh_enter_string_list(char **list);
char** scsh_extract_string_vector(s48_value vector);
FFIT_MAKE_ENTER_RECORD(scsh_enter_ldap, scsh_ldap_record_type,
LDAP*);
s48_value scsh_enter_ldap(LDAP *ldap)
{
s48_value rec = S48_FALSE;
S48_DECLARE_GC_PROTECT(1);
FFIT_MAKE_ENTER_RECORD(scsh_enter_ldapmessage, scsh_ldapmessage_record_type,
LDAPMessage*);
S48_GC_PROTECT_1(rec);
rec = s48_make_record(scsh_ldap_record_type);
S48_RECORD_SET(rec, 0, s48_enter_integer((long) ldap));
S48_GC_UNPROTECT();
return rec;
}
FFIT_MAKE_ENTER_RECORD(scsh_enter_ldapmod, scsh_ldapmod_record_type,
LDAPMod*);
s48_value scsh_enter_ldapmessage(LDAPMessage *lm)
{
s48_value rec = S48_FALSE;
S48_DECLARE_GC_PROTECT(1);
FFIT_MAKE_ENTER_RECORD(scsh_enter_ldapiinfo, scsh_ldapapiinfo_record_type,
LDAPAPIInfo*);
S48_GC_PROTECT_1(rec);
rec = s48_make_record(scsh_ldapmessage_record_type);
S48_RECORD_SET(rec, 0, s48_enter_integer((long) lm));
S48_GC_UNPROTECT();
return rec;
}
FFIT_STRUCT_GET_INT(scsh_ldapapiinfo_get_info_version,
scsh_ldapapiinfo_record_type, LDAPAPIInfo*,
ldapai_info_version);
s48_value scsh_ldap_open(s48_value host, s48_value port)
{
LDAP *ldap;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(host, port);
ldap = ldap_open(s48_extract_string(host), s48_extract_integer(port));
S48_GC_UNPROTECT();
return ldap == NULL ? S48_FALSE : scsh_enter_ldap(ldap);
}
FFIT_STRUCT_GET_INT(scsh_ldapapiinfo_get_api_version,
scsh_ldapapiinfo_record_type, LDAPAPIInfo*,
ldapai_api_version);
FFIT_STRUCT_GET_INT(scsh_ldapapiinfo_get_protocol_version,
scsh_ldapapiinfo_record_type, LDAPAPIInfo*,
ldapai_protocol_version);
FFIT_STRUCT_GET_STRING(scsh_ldapapiinfo_get_vendor_name,
scsh_ldapapiinfo_record_type, LDAPAPIInfo*,
ldapai_vendor_name);
FFIT_STRUCT_GET_INT(scsh_ldapapiinfo_get_vendor_version,
scsh_ldapapiinfo_record_type, LDAPAPIInfo*,
ldapai_vendor_version);
FFIT_STRUCT_GET(scsh_ldapapiinfo_get_extensions,
scsh_ldapapiinfo_record_type, LDAPAPIInfo*,
ldapai_extensions, ffit_enter_string_array);
s48_value scsh_ldap_init(s48_value host, s48_value port)
{
@ -50,19 +47,6 @@ s48_value scsh_ldap_init(s48_value host, s48_value port)
return ldap == NULL ? S48_FALSE : scsh_enter_ldap(ldap);
}
s48_value scsh_ldap_bind_s(s48_value ldap, s48_value user,
s48_value cred, s48_value method)
{
int r;
S48_DECLARE_GC_PROTECT(4);
S48_GC_PROTECT_4(ldap, user, cred, method);
r = ldap_bind_s(scsh_extract_ldap(ldap), s48_extract_string(user),
s48_extract_string(cred), s48_extract_integer(method));
S48_GC_UNPROTECT();
return s48_enter_integer(r);
}
s48_value scsh_ldap_simple_bind_s(s48_value ldap, s48_value user, s48_value cred)
{
int r;
@ -75,28 +59,25 @@ s48_value scsh_ldap_simple_bind_s(s48_value ldap, s48_value user, s48_value cred
return s48_enter_integer(r);
}
s48_value scsh_ldap_kerberos_bind_s(s48_value ldap, s48_value dn)
s48_value scsh_ldap_sasl_bind_s(s48_value ldap, s48_value dn,
s48_value mechanism, s48_value cred,
s48_value server_controls,
s48_value client_controls,
s48_value server_cred_p)
{
#if HAVE_LDAP_KERBEROS_BIND_S
int r;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, dn);
r = ldap_kerberos_bind_s(scsh_extract_ldap(ldap), s48_extract_string(dn));
S48_GC_UNPROTECT();
return s48_enter_integer(r);
#else
/* need to implement bindings for berval stuff first */
return S48_FALSE;
#endif
}
s48_value scsh_ldap_unbind_s(s48_value ldap)
{
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
return s48_enter_integer(ldap_unbind_s(scsh_extract_ldap(ldap)));
}
s48_value scsh_ldap_error_string(s48_value errcode)
{
FFIT_CHECK_INTEGER(errcode);
return s48_enter_string(ldap_err2string(s48_extract_integer(errcode)));
}
@ -114,12 +95,14 @@ s48_value scsh_ldap_result_error(s48_value ldap, s48_value res)
s48_value scsh_ldap_memfree(s48_value ldap)
{
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
ldap_memfree(scsh_extract_ldap(ldap));
return S48_UNSPECIFIC;
}
s48_value scsh_ldap_msgfree(s48_value ldapmsg)
{
FFIT_CHECK_RECORD_TYPE(ldapmsg, scsh_ldapmessage_record_type);
ldap_msgfree(scsh_extract_ldapmessage(ldapmsg));
return S48_UNSPECIFIC;
}
@ -135,7 +118,9 @@ s48_value scsh_ldap_search_s(s48_value ldap, s48_value base,
S48_DECLARE_GC_PROTECT(7);
S48_GC_PROTECT_7(ldap, base, scope, filter, attrs, attrsonly, res);
a = scsh_extract_string_vector(attrs);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
a = ffit_extract_list_of_strings(attrs);
r = ldap_search_s(scsh_extract_ldap(ldap),
s48_extract_string(base),
s48_extract_integer(scope),
@ -161,12 +146,14 @@ s48_value scsh_ldap_search_st(s48_value ldap, s48_value base,
s48_value res = S48_FALSE;
S48_DECLARE_GC_PROTECT(9);
S48_GC_PROTECT_4(ldap, base, scope, filter);
S48_GC_PROTECT_3(attrs, attrsonly, res);
S48_GC_PROTECT_2(timeout_sec, timeout_usec);
S48_GC_PROTECT_9(ldap, base, scope, filter, attrs, attrsonly, res,
timeout_sec, timeout_usec);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
timeout.tv_sec = s48_extract_integer(timeout_sec);
timeout.tv_usec = s48_extract_integer(timeout_usec);
a = scsh_extract_string_vector(attrs);
a = ffit_extract_list_of_strings(attrs);
r = ldap_search_st(scsh_extract_ldap(ldap), s48_extract_string(base),
s48_extract_integer(scope), s48_extract_string(filter),
a, S48_TRUE_P(attrsonly), &timeout, msg);
@ -176,12 +163,34 @@ s48_value scsh_ldap_search_st(s48_value ldap, s48_value base,
return res;
}
s48_value scsh_ldap_compare_s(s48_value ldap, s48_value dn,
s48_value attr, s48_value value)
{
s48_value res;
int r;
S48_DECLARE_GC_PROTECT(5);
S48_GC_PROTECT_5(ldap, dn, attr, value, res);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
r = ldap_compare_s(scsh_extract_ldap(ldap), s48_extract_string(dn),
s48_extract_string(attr), s48_extract_string(value));
S48_GC_UNPROTECT();
switch (r) {
case LDAP_COMPARE_TRUE: return S48_TRUE;
case LDAP_COMPARE_FALSE: return S48_FALSE;
default: return s48_enter_integer(r);
}
}
s48_value scsh_ldap_count_entries(s48_value ldap, s48_value lm)
{
int r;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
r = ldap_count_entries(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
@ -191,35 +200,122 @@ s48_value scsh_ldap_count_entries(s48_value ldap, s48_value lm)
s48_value scsh_ldap_first_entry(s48_value ldap, s48_value lm)
{
LDAPMessage *lm_new;
s48_value res = S48_FALSE;
S48_DECLARE_GC_PROTECT(3);
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_3(ldap, lm, res);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
lm_new = ldap_first_entry(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
res = scsh_enter_ldapmessage(lm_new);
S48_GC_UNPROTECT();
return res;
return (lm_new == NULL) ? S48_FALSE : scsh_enter_ldapmessage(lm_new);
}
s48_value scsh_ldap_next_entry(s48_value ldap, s48_value lm)
{
LDAPMessage *lm_new;
s48_value res = S48_FALSE;
S48_DECLARE_GC_PROTECT(3);
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
S48_GC_PROTECT_3(ldap, lm, res);
lm_new = ldap_next_entry(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
res = scsh_enter_ldapmessage(lm_new);
S48_GC_UNPROTECT();
return res;
return (lm_new == NULL) ? S48_FALSE : scsh_enter_ldapmessage(lm_new);
}
s48_value scsh_ldap_first_message(s48_value ldap, s48_value lm)
{
LDAPMessage *first;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
first = ldap_first_message(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (first == NULL) ? S48_FALSE : scsh_enter_ldapmessage(first);
}
s48_value scsh_ldap_next_message(s48_value ldap, s48_value lm)
{
LDAPMessage *next;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
next = ldap_next_message(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (next == NULL) ? S48_FALSE : scsh_enter_ldapmessage(next);
}
s48_value scsh_ldap_count_messages(s48_value ldap, s48_value lm)
{
int c;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
c = ldap_count_messages(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (c == -1) ? S48_FALSE : s48_enter_integer(c);
}
s48_value scsh_ldap_first_reference(s48_value ldap, s48_value lm)
{
LDAPMessage *new_lm;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
new_lm = ldap_first_reference(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (new_lm == NULL) ? S48_FALSE : scsh_enter_ldapmessage(new_lm);
}
s48_value scsh_ldap_next_reference(s48_value ldap, s48_value lm)
{
LDAPMessage *new_lm;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
new_lm = ldap_next_reference(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (new_lm == NULL) ? S48_FALSE : scsh_enter_ldapmessage(new_lm);
}
s48_value scsh_ldap_count_references(s48_value ldap, s48_value lm)
{
int c;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, lm);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
c = ldap_count_references(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(lm));
S48_GC_UNPROTECT();
return (c == -1) ? S48_FALSE : s48_enter_integer(c);
}
s48_value scsh_ldap_msgtype(s48_value lm)
{
int r;
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
r = ldap_msgtype(scsh_extract_ldapmessage(lm));
return s48_enter_integer(r);
}
@ -228,10 +324,69 @@ s48_value scsh_ldap_msgid(s48_value lm)
{
int r;
FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type);
r = ldap_msgid(scsh_extract_ldapmessage(lm));
return s48_enter_integer(r);
}
/* may raise ldap error */
s48_value scsh_ldap_get_dn(s48_value ldap, s48_value entry)
{
char *s;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, entry);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(entry, scsh_ldapmessage_record_type);
s = ldap_get_dn(scsh_extract_ldap(ldap), scsh_extract_ldapmessage(entry));
S48_GC_UNPROTECT();
return (s == NULL) ? S48_FALSE : s48_enter_string(s);
}
s48_value scsh_ldap_explode_dn(s48_value dn, s48_value notypes)
{
char **a;
s48_value res = S48_FALSE;
S48_DECLARE_GC_PROTECT(3);
S48_GC_PROTECT_3(dn, notypes, res);
a = ldap_explode_dn(s48_extract_string(dn),
S48_TRUE_P(notypes) ? 0 : 1);
res = ffit_enter_string_array(a);
S48_GC_UNPROTECT();
ldap_value_free(a);
return res;
}
s48_value scsh_ldap_explode_rdn(s48_value rdn, s48_value notypes)
{
char **a;
s48_value res = S48_FALSE;
S48_DECLARE_GC_PROTECT(3);
S48_GC_PROTECT_3(rdn, notypes, res);
a = ldap_explode_rdn(s48_extract_string(rdn),
S48_TRUE_P(notypes) ? 0 : 1);
res = ffit_enter_string_array(a);
S48_GC_UNPROTECT();
ldap_value_free(a);
return res;
}
s48_value scsh_ldap_dn2ufn(s48_value dn)
{
char *a;
s48_value res = S48_FALSE;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(dn, res);
a = ldap_dn2ufn(s48_extract_string(dn));
res = s48_enter_string(a);
S48_GC_UNPROTECT();
ldap_memfree(a);
return res;
}
s48_value scsh_ldap_get_values(s48_value ldap, s48_value entry,
s48_value attr)
{
@ -240,61 +395,225 @@ s48_value scsh_ldap_get_values(s48_value ldap, s48_value entry,
S48_DECLARE_GC_PROTECT(4);
S48_GC_PROTECT_4(ldap, entry, attr, res);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_RECORD_TYPE(entry, scsh_ldapmessage_record_type);
val = ldap_get_values(scsh_extract_ldap(ldap),
scsh_extract_ldapmessage(entry),
s48_extract_string(attr));
res = scsh_enter_string_list(val);
res = ffit_enter_string_array(val);
ldap_value_free(val);
S48_GC_UNPROTECT();
return res;
}
/* TODO: ldap_get_values_len() -- for binary attribute values */
s48_value scsh_enter_string_list(char **list)
s48_value scsh_ldap_modify(s48_value ldap, s48_value dn, s48_value mods)
{
int i;
s48_value res = S48_NULL;
S48_DECLARE_GC_PROTECT(1);
int r;
S48_DECLARE_GC_PROTECT(3);
S48_GC_PROTECT_1(res);
for (i = 0; list[i] != NULL; i++)
res = s48_cons(s48_enter_string(list[i]), res);
S48_GC_PROTECT_3(ldap, dn, mods);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
r = ldap_modify_s(scsh_extract_ldap(ldap), s48_extract_string(dn),
scsh_extract_ldapmod_vector(mods));
S48_GC_UNPROTECT();
return res;
return s48_enter_integer(r);
}
char** scsh_extract_string_vector(s48_value vector)
s48_value scsh_ldap_add(s48_value ldap, s48_value dn, s48_value mods)
{
char** a;
int r;
S48_DECLARE_GC_PROTECT(3);
S48_GC_PROTECT_3(ldap, dn, mods);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
if (!S48_VECTOR_P(mods))
s48_raise_argument_type_error(mods);
r = ldap_add_s(scsh_extract_ldap(ldap), s48_extract_string(dn),
scsh_extract_ldapmod_vector(mods));
S48_GC_UNPROTECT();
return s48_enter_integer(r);
}
s48_value scsh_ldap_delete(s48_value ldap, s48_value dn)
{
int r;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, dn);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
r = ldap_delete_s(scsh_extract_ldap(ldap), s48_extract_string(dn));
S48_GC_UNPROTECT();
return s48_enter_integer(r);
}
s48_value scsh_ldap_abandon(s48_value ldap, s48_value msgid)
{
int r;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(ldap, msgid);
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
r = ldap_abandon(scsh_extract_ldap(ldap), s48_extract_integer(msgid));
S48_GC_UNPROTECT();
return s48_enter_integer(r);
}
s48_value scsh_ldap_get_set_option(s48_value ldap, s48_value option,
s48_value set, s48_value inval)
{
int opt, r;
LDAP *ld;
void *outvalue;
s48_value res = S48_UNSPECIFIC;
FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type);
FFIT_CHECK_BOOLEAN(set);
ld = scsh_extract_ldap(ldap);
switch (opt) {
case LDAP_OPT_API_INFO:
{
if (S48_TRUE_P(set))
raise_ldap_read_only_option();
r = ldap_get_option(ld, opt, outvalue);
if (r == LDAP_SUCCESS)
res = scsh_enter_ldapiinfo((LDAPAPIInfo *) outvalue);
break;
}
case LDAP_OPT_DEREF:
{
}
case LDAP_OPT_SIZELIMIT:
case LDAP_OPT_TIMELIMIT:
{
int l;
if (S48_TRUE_P(set)) {
FFIT_CHECK_INTEGER(inval);
l = s48_extract_integer(inval);
r = ldap_set_option(ld, opt, &l);
}
else
if ((r = ldap_get_option(ld, opt, outvalue)) == LDAP_SUCCESS)
res = s48_enter_integer(*((int*)outvalue));
break;
}
case LDAP_OPT_REFERRALS:
case LDAP_OPT_RESTART:
{
if (S48_TRUE_P(set)) {
FFIT_CHECK_BOOLEAN(inval);
r = ldap_set_option(ld, opt, S48_TRUE_P(inval) ? LDAP_OPT_ON : LDAP_OPT_OFF);
}
else
if ((r = ldap_get_option(ld, opt, outvalue)) == LDAP_SUCCESS)
res = outvalue == 0 ? S48_TRUE : S48_FALSE;
break;
}
case LDAP_OPT_PROTOCOL_VERSION:
{
int v;
if (S48_TRUE_P(set)) {
FFIT_CHECK_INTEGER(inval);
v = s48_extract_integer(inval);
r = ldap_set_option(ld, opt, &v);
}
else
if ((r = ldap_get_option(ld, opt, outvalue)) == LDAP_SUCCESS)
res = s48_enter_integer(*(int *)outvalue);
break;
}
case LDAP_OPT_SERVER_CONTROLS:
case LDAP_OPT_CLIENT_CONTROLS:
{
raise_ldap_read_only_option();
}
}
}
/* ************************************************************************ */
/* FIXME: support modv_bvals (binary values) */
s48_value scsh_ldapmod_create(s48_value op, s48_value type, s48_value data_vector)
{
LDAPMod *m;
S48_DECLARE_GC_PROTECT(3);
S48_GC_PROTECT_3(op, type, data_vector);
if ((m = (LDAPMod*) calloc(1, sizeof(LDAPMod))) == NULL)
raise_ldap_memory_alloc_error();
m->mod_op = s48_extract_integer(op);
m->mod_type = s48_extract_string(type);
m->mod_vals.modv_strvals = ffit_extract_list_of_strings(data_vector);
return scsh_enter_ldapmod(m);
}
LDAPMod** scsh_extract_ldapmod_vector(s48_value vector)
{
LDAPMod **a;
int l, i;
S48_DECLARE_GC_PROTECT(1);
S48_GC_PROTECT_1(vector);
l = S48_VECTOR_LENGTH(vector);
if ((a = calloc (l, sizeof(char *))) == NULL)
RAISE_MEMORY_ALLOC_ERROR("scsh_extract_string_vector");
if ((*a = (LDAPMod *) calloc(l+1, sizeof(LDAPMod*))) == NULL)
raise_ldap_memory_alloc_error();
for (i = 0; i < l; i++)
a[i] = s48_extract_string(S48_VECTOR_REF(vector, i));
a[i] = scsh_extract_ldapmod(S48_VECTOR_REF(vector, i));
a[l] = NULL;
S48_GC_UNPROTECT();
return a;
}
void scsh_ldap_main(void)
void raise_ldap_memory_alloc_error(void)
{
s48_raise_scheme_exception(condition_ldap_memory_alloc_error, 0);
}
void raise_ldap_feature_not_supported(void)
{
S48_GC_PROTECT_GLOBAL(scsh_ldap_record_type);
scsh_ldap_record_type = s48_get_imported_binding("ldap");
s48_raise_scheme_exception(condition_ldap_feature_not_supported, 0);
}
S48_GC_PROTECT_GLOBAL(scsh_ldapmessage_record_type);
scsh_ldapmessage_record_type = s48_get_imported_binding("ldap-message");
void raise_ldap_read_only_option(void)
{
s48_raise_scheme_exception(condition_ldap_read_only_option, 0);
}
S48_GC_PROTECT_GLOBAL(raise_ldap_memory_alloc_error);
raise_ldap_memory_alloc_error = s48_get_imported_binding("raise-ldap-memory-alloc-error");
void scsh_init_ldap_bindings(void)
{
ffit_init_hook();
scsh_ldap_gc_protect_globals();
S48_GC_PROTECT_GLOBAL(condition_ldap_memory_alloc_error);
S48_GC_PROTECT_GLOBAL(condition_ldap_feature_not_supported);
S48_GC_PROTECT_GLOBAL(condition_ldap_read_only_option);
condition_ldap_memory_alloc_error =
s48_get_imported_binding("condition-ldap-memory-alloc-error");
condition_ldap_feature_not_supported =
s48_get_imported_binding("condition-ldap-feature-not-supported");
condition_ldap_read_only_option =
s48_get_imported_binding("condition-ldap-read-only-option");
scsh_ldap_enter_ldap_constants();
FFIT_RECORD_TYPE_INIT(scsh_ldap_record_type, ldap);
FFIT_RECORD_TYPE_INIT(scsh_ldapmessage_record_type, ldap-message);
FFIT_RECORD_TYPE_INIT(scsh_ldapmod_record_type, ldap-modification);
FFIT_RECORD_TYPE_INIT(scsh_ldapapiinfo_record_type, ldap-api-info);
S48_EXPORT_FUNCTION(scsh_ldapapiinfo_get_info_version);
S48_EXPORT_FUNCTION(scsh_ldapapiinfo_get_protocol_version);
S48_EXPORT_FUNCTION(scsh_ldapapiinfo_get_vendor_name);
S48_EXPORT_FUNCTION(scsh_ldapapiinfo_get_vendor_version);
S48_EXPORT_FUNCTION(scsh_ldapapiinfo_get_extensions);
S48_EXPORT_FUNCTION(scsh_ldap_open);
S48_EXPORT_FUNCTION(scsh_ldap_init);
S48_EXPORT_FUNCTION(scsh_ldap_bind_s);
S48_EXPORT_FUNCTION(scsh_ldap_simple_bind_s);
S48_EXPORT_FUNCTION(scsh_ldap_kerberos_bind_s);
S48_EXPORT_FUNCTION(scsh_ldap_sasl_bind_s);
S48_EXPORT_FUNCTION(scsh_ldap_unbind_s);
S48_EXPORT_FUNCTION(scsh_ldap_error_string);
S48_EXPORT_FUNCTION(scsh_ldap_result_error);
@ -302,11 +621,27 @@ void scsh_ldap_main(void)
S48_EXPORT_FUNCTION(scsh_ldap_msgfree);
S48_EXPORT_FUNCTION(scsh_ldap_search_s);
S48_EXPORT_FUNCTION(scsh_ldap_search_st);
S48_EXPORT_FUNCTION(scsh_ldap_compare_s);
S48_EXPORT_FUNCTION(scsh_ldap_count_entries);
S48_EXPORT_FUNCTION(scsh_ldap_first_entry);
S48_EXPORT_FUNCTION(scsh_ldap_next_entry);
S48_EXPORT_FUNCTION(scsh_ldap_first_message);
S48_EXPORT_FUNCTION(scsh_ldap_next_message);
S48_EXPORT_FUNCTION(scsh_ldap_count_messages);
S48_EXPORT_FUNCTION(scsh_ldap_first_reference);
S48_EXPORT_FUNCTION(scsh_ldap_next_reference);
S48_EXPORT_FUNCTION(scsh_ldap_count_references);
S48_EXPORT_FUNCTION(scsh_ldap_msgtype);
S48_EXPORT_FUNCTION(scsh_ldap_msgid);
S48_EXPORT_FUNCTION(scsh_ldap_get_dn);
S48_EXPORT_FUNCTION(scsh_ldap_explode_dn);
S48_EXPORT_FUNCTION(scsh_ldap_explode_rdn);
S48_EXPORT_FUNCTION(scsh_ldap_dn2ufn);
S48_EXPORT_FUNCTION(scsh_ldap_get_values);
S48_EXPORT_FUNCTION(scsh_ldap_modify);
S48_EXPORT_FUNCTION(scsh_ldap_add);
S48_EXPORT_FUNCTION(scsh_ldap_delete);
S48_EXPORT_FUNCTION(scsh_ldap_abandon);
S48_EXPORT_FUNCTION(scsh_ldap_get_set_option);
S48_EXPORT_FUNCTION(scsh_ldapmod_create);
}

View File

@ -1,13 +1,13 @@
#include "scheme48.h"
#include "c/config.h"
#include "config.h"
extern void scsh_ldap_main();
int main(int argc, char **argv)
{
s48_add_external_init(scsh_ldap_main);
extern void scsh_init_ldap_bindings(void);
int main(int argc, char **argv) {
s48_add_external_init(scsh_init_ldap_bindings);
return s48_main(10000000, 64000,
SCSHIMAGE,
--argc, ++argv);
}

View File

@ -1,32 +1,105 @@
#include "scheme48.h"
#include "config.h"
#include <stdlib.h>
#include <sys/time.h>
/* time.h */
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include "scheme48.h"
#include "ffi-tools/ffi-tools.h"
#include <ldap.h>
static s48_value scsh_ldap_record_type = S48_FALSE;
static s48_value scsh_ldapmessage_record_type = S48_FALSE;
static s48_value scsh_ldapmod_record_type = S48_FALSE;
static s48_value scsh_ldapapiinfo_record_type = S48_FALSE;
s48_value scsh_enter_ldap(LDAP *ldap);
FFIT_MAKE_ENTER_RECORD_PROTOTYPE(scsh_enter_ldap, LDAP*);
#define scsh_extract_ldap(x) \
((LDAP *) \
s48_extract_integer(S48_RECORD_REF(x, 0)))
s48_value scsh_enter_ldapmessage(LDAPMessage *lm);
FFIT_MAKE_ENTER_RECORD_PROTOTYPE(scsh_enter_ldapmessage, LDAPMessage*);
#define scsh_extract_ldapmessage(x) \
((LDAPMessage *) \
s48_extract_integer(S48_RECORD_REF(x, 0)))
FFIT_MAKE_ENTER_RECORD_PROTOTYPE(scsh_enter_ldapmod, LDAPMod*);
#define scsh_extract_ldapmod(x) \
((LDAPMod *) \
s48_extract_integer(S48_RECORD_REF(x, 0)))
FFIT_MAKE_ENTER_RECORD_PROTOTYPE(scsh_enter_ldapapiinfo, LDAPAPIInfo*);
#define scsh_extract_ldapapiinfo(x) \
((LDAPAPIInfo *) \
s48_extract_integer(S48_RECORD_REF(x, 0)))
/* conditions */
static s48_value raise_ldap_memory_alloc_error = S48_FALSE;
static s48_value condition_ldap_memory_alloc_error = S48_FALSE;
static s48_value condition_ldap_feature_not_supported = S48_FALSE;
static s48_value condition_ldap_read_only_option = S48_FALSE;
#define RAISE_MEMORY_ALLOC_ERROR(FUNNAME) \
s48_call_scheme(S48_SHARED_BINDING_REF(raise_ldap_memory_alloc_error), \
1, s48_enter_string(FUNNAME));
char** scsh_extract_string_vector(s48_value vector);
/* prototypes */
void scsh_ldap_main(void);
/* function body generated by ffi-tools */
void scsh_ldap_enter_ldap_constants(void);
/* function body generated by ffi-tools */
void scsh_ldap_gc_protect_globals(void);
LDAPMod** scsh_extract_ldapmod_vector(s48_value);
void raise_ldap_memory_alloc_error(void);
void raise_ldap_feature_not_supported(void);
void raise_ldap_read_only_option(void);
s48_value scsh_ldap_init(s48_value, s48_value);
s48_value scsh_ldap_simple_bind_s(s48_value, s48_value, s48_value);
s48_value scsh_ldap_sasl_bind_s(s48_value, s48_value, s48_value, s48_value,
s48_value, s48_value, s48_value);
s48_value scsh_ldap_unbind_s(s48_value);
s48_value scsh_ldap_error_string(s48_value);
s48_value scsh_ldap_result_error(s48_value, s48_value);
s48_value scsh_ldap_memfree(s48_value);
s48_value scsh_ldap_msgfree(s48_value);
s48_value scsh_ldap_search_s(s48_value, s48_value, s48_value, s48_value,
s48_value, s48_value);
s48_value scsh_ldap_search_st(s48_value, s48_value, s48_value, s48_value,
s48_value, s48_value, s48_value, s48_value);
s48_value scsh_ldap_compare_s(s48_value, s48_value, s48_value, s48_value);
s48_value scsh_ldap_count_entries(s48_value, s48_value);
s48_value scsh_ldap_first_entry(s48_value, s48_value);
s48_value scsh_ldap_next_entry(s48_value, s48_value);
s48_value scsh_ldap_first_message(s48_value, s48_value);
s48_value scsh_ldap_next_message(s48_value, s48_value);
s48_value scsh_ldap_count_messages(s48_value, s48_value);
s48_value scsh_ldap_first_reference(s48_value, s48_value);
s48_value scsh_ldap_next_reference(s48_value, s48_value);
s48_value scsh_ldap_count_references(s48_value, s48_value);
s48_value scsh_ldap_msgtype(s48_value);
s48_value scsh_ldap_msgid(s48_value);
s48_value scsh_ldap_get_dn(s48_value, s48_value);
s48_value scsh_ldap_explode_dn(s48_value, s48_value);
s48_value scsh_ldap_explode_rdn(s48_value, s48_value);
s48_value scsh_ldap_dn2ufn(s48_value);
s48_value scsh_ldap_get_values(s48_value, s48_value, s48_value);
s48_value scsh_ldap_modify(s48_value, s48_value, s48_value);
s48_value scsh_ldap_add(s48_value, s48_value, s48_value);
s48_value scsh_ldap_delete(s48_value, s48_value);
s48_value scsh_ldap_abandon(s48_value, s48_value);
s48_value scsh_ldap_get_set_option(s48_value, s48_value, s48_value, s48_value);
s48_value scsh_ldapmod_create(s48_value, s48_value, s48_value);
void scsh_init_ldap_bindings(void);

View File

@ -4,11 +4,12 @@ AM_INIT_AUTOMAKE
dnl AM_MAINTAINER_MODE
AC_CONFIG_HEADERS(c/config.h)
AM_CONFIG_HEADER(c/config.h)
AC_PROG_LIBTOOL
AC_PROG_CC
define([PREPEND], [[$2]="$[$2] [$1]"])
AC_HEADER_STDC
AC_CHECK_HEADERS(sys/time.h)
AC_ARG_WITH(scsh-includes,
AC_HELP_STRING([--with-scsh-includes=DIR],
@ -16,13 +17,15 @@ AC_ARG_WITH(scsh-includes,
scsh_includes=$withval,
scsh_includes=/usr/local/include)
AC_SUBST(scsh_includes)
dnl AC_SUBST(CFLAGS, "$CFLAGS -I${scsh_includes}")
dnl AC_CHECK_HEADER([scheme48.h], [],
dnl AC_MSG_FAILURE("Could not find scheme48.h"))
AC_ARG_WITH(scsh-libraries,
AC_HELP_STRING([--with-scsh-libraries=DIR],
[scsh libraries are in DIR [/usr/local/lib/scsh]]),
scsh_libraries=$withval,
scsh_libraries=/usr/local/lib/scsh)
AC_SUBST(scsh_libraries)
AC_PATH_PROG([SCSH], [scsh], [-not found-], [$PATH])
if test "$SCSH" = "-not found-"; then
AC_MSG_FAILURE("No scsh binary in path")
fi
AC_SUBST(SCSH)
AC_ARG_WITH(ldap-prefix,
AC_HELP_STRING([--with-ldap-prefix=DIR],
@ -69,6 +72,13 @@ AC_CHECK_FUNC([ldap_get_values], [],
AC_CHECK_FUNCS([ldap_kerberos_bind_s])
schemedir='${prefix}'"/scheme"
libdir='${prefix}'"/lib"
libsysdir=${libdir}"/`scsh -lm ${srcdir}/scheme/configure.scm -o configure -c '(display (host))'`"
AC_SUBST(libdir)
AC_SUBST(libsysdir)
AC_SUBST(schemedir)
AC_SUBST(LIBS)
AC_SUBST(CC)
AC_OUTPUT([Makefile c/Makefile])
AC_OUTPUT([Makefile c/Makefile scheme/Makefile])

47
doc/TODO Normal file
View File

@ -0,0 +1,47 @@
-*- outline -*-
* Missing functionality
** Server/Client-controls
plus all _ext_s() functions:
ldap_unbind_ext()
ldap_search_ext_s()
ldap_compare_ext_s()
ldap_modify_ext_s()
ldap_rename_s()
ldap_add_ext_s()
ldap_delete_ext_s()
ldap_extended_operation_s()
ldap_abandon_ext()
ldap_parse_result()
ldap_parse_sasl_bind_result()
ldap_parse_extended_result()
* Fixing needed
* Need ber-stuff first
ldap_sasl_bind_s()
ldap_first_attribute()
ldap_next_attribute()
ldap_get_value_len()
* Not implemented
** Check for errors in ldap_{first, next}_{entries, references, messages}
These functions may return S48_FALSE if the corresponding C
function returns NULL. This is ambigious: a) end of list b) error
solution: check for error in Scheme
ldap_explode_dn()
ldap_explode_rdn()
ldap_dn2ufn()
ldap_get_entry_controls()
ldap_parse_reference()
* structures and accessors
struct berval
struct ldapmod

File diff suppressed because it is too large Load Diff

1235
doc/rfc1823.txt Normal file

File diff suppressed because it is too large Load Diff

14
etc/notes.txt Normal file
View File

@ -0,0 +1,14 @@
-*- outline -*-
* LDAP server
** Starting slapd
su -m
/afs/wsi/ppc_macx66/openldap-2.1.23/libexec/slapd -d 9 -f slapd.conf
** Adding entries of a ldif file
ldapadd -v -W -x -h localhost -p 389 -D
cn=Manager,dc=informatik,dc=uni-tuebingen,dc=de -f file.ldif
** Querying an LDAP server
ldapsearch -b "dc=informatik,dc=uni-tuebingen,dc=de"

68
etc/slapd.conf Normal file
View File

@ -0,0 +1,68 @@
# $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.23.2.8 2003/05/24 23:19:14 kurt Exp $
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /afs/informatik.uni-tuebingen.de/ppc_macx66/openldap-2.1.23/etc/openldap/schema/core.schema
# Define global ACLs to disable default read access.
# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org
pidfile /tmp/knauel/slapd.pid
argsfile /tmp/knauel/slapd.args
# Load dynamic backend modules:
# modulepath /Users/Shared/sw/openldap-2.1.23/libexec/openldap
# moduleload back_bdb.la
# moduleload back_ldap.la
# moduleload back_ldbm.la
# moduleload back_passwd.la
# moduleload back_shell.la
# Sample security restrictions
# Require integrity protection (prevent hijacking)
# Require 112-bit (3DES or better) encryption for updates
# Require 63-bit encryption for simple bind
# security ssf=1 update_ssf=112 simple_bind=64
# Sample access control policy:
# Root DSE: allow anyone to read it
# Subschema (sub)entry DSE: allow anyone to read it
# Other DSEs:
# Allow self write access
# Allow authenticated users read access
# Allow anonymous users to authenticate
# Directives needed to implement policy:
# access to dn.base="" by * read
# access to dn.base="cn=Subschema" by * read
# access to *
# by self write
# by users read
# by anonymous auth
#
# if no access controls are present, the default policy is:
# Allow read by all
#
# rootdn can always write!
#######################################################################
# ldbm database definitions
#######################################################################
database bdb
suffix "dc=informatik,dc=uni-tuebingen,dc=de"
rootdn "cn=Manager,dc=informatik,dc=uni-tuebingen,dc=de"
# Cleartext passwords, especially for the rootdn, should
# be avoid. See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw secret
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory /Users/knauel/cool-stuff/scsh-ldap/etc/data
# Indices to maintain
index objectClass eq

View File

@ -0,0 +1,27 @@
(define-interface ffi-import-constants-interface
(export
make-constant
constant?
constant-type-int?
constant-type-char?
constant-type-string?
constant-c-name
constant-scheme-name
constant-c-value-name
constant-type
make-constant-from-c-name
make-constant-from-c-name-integer
generate-c-declarations
generate-c-enter-values-function
generate-c-gc-protect-globals-function
generate-finite-type-definition
make-drop-common-prefix-name-converter))
(define-structure ffi-import-constants ffi-import-constants-interface
(open
scheme signals
srfi-1 srfi-9 srfi-13 srfi-28)
(files ffi-tools))

View File

@ -0,0 +1,34 @@
(define-interface ffi-tools-rts-interface
(export
(lookup-shared-value :syntax)
make-finite-type-import-function))
(define-structure ffi-tools-rts ffi-tools-rts-interface
(open scheme)
(begin
(define-syntax lookup-shared-value
(syntax-rules ()
((lookup-shared-value %s)
(shared-binding-ref
(lookup-imported-binding %s)))))
(define (make-finite-type-alist elements id-proc)
(map
(lambda (e) (cons (id-proc e) e))
(vector->list elements)))
(define (make-finite-type-import-function finite-type-name elements id-proc)
(let ((alist (make-finite-type-alist elements id-proc)))
(lambda (id)
(cond
((assoc id alis) => cdr)
(else
(error "Could not map value to finite type "
finite-type-name id))))))
))

96
ffi-tools/ffi-tools.c Normal file
View File

@ -0,0 +1,96 @@
#include "ffi-tools.h"
/* convert null-terminated array of strings to a list of Scheme strings */
s48_value ffit_enter_string_array(char **array)
{
int i;
s48_value res = S48_NULL;
S48_DECLARE_GC_PROTECT(1);
S48_GC_PROTECT_1(res);
for (i = 0; array[i] != NULL; i++)
res = s48_cons(s48_enter_string(array[i]), res);
S48_GC_UNPROTECT();
return res;
}
int length_scheme_list(s48_value list)
{
s48_value res;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(list, res);
FFIT_CHECK_LIST(list);
res = s48_call_scheme(scheme_list_length_function, 1, list);
S48_GC_UNPROTECT();
return s48_extract_integer(res);
}
int call_scheme_boolean_p(s48_value v)
{
s48_value res;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(v, res);
res = s48_call_scheme(scheme_boolean_p_function, 1, v);
S48_GC_UNPROTECT();
return S48_TRUE_P(res);
}
int call_scheme_integer_p(s48_value v)
{
s48_value res;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(v, res);
res = s48_call_scheme(scheme_integer_p_function, 1, v);
S48_GC_UNPROTECT();
return S48_TRUE_P(res);
}
/* convert a Scheme list of strings into an null-terminated array of strings */
char** ffit_extract_list_of_strings(s48_value list)
{
char **a;
int l, i;
s48_value res, e;
S48_DECLARE_GC_PROTECT(3);
S48_GC_PROTECT_3(list, res, e);
l = length_scheme_list(list);
if ((*a = (char *) calloc(l + 1, sizeof(char *))) == NULL)
s48_raise_out_of_memory_error();
a[l] = NULL;
e = list;
i = 0;
while (e != S48_NULL) {
if (S48_PAIR_P(e))
if (S48_STRING_P(e)) {
a[i] = s48_extract_string(e);
e = S48_CDR(e);
i++;
}
else {
free(a);
s48_raise_argument_type_error(e);
}
else {
free(a);
s48_raise_argument_type_error(e);
}
}
return a;
}
void ffit_init_hook(void)
{
S48_GC_PROTECT_GLOBAL(scheme_list_length_function);
S48_GC_PROTECT_GLOBAL(scheme_integer_p_function);
S48_GC_PROTECT_GLOBAL(scheme_boolean_p_function);
scheme_list_length_function = s48_get_imported_binding("length");
scheme_integer_p_function = s48_get_imported_binding("integer?");
scheme_boolean_p_function = s48_get_imported_binding("boolean?");
}

76
ffi-tools/ffi-tools.h Normal file
View File

@ -0,0 +1,76 @@
#include <unistd.h>
#include "scheme48.h"
/* variables */
static s48_value scheme_list_length_function = S48_FALSE;
static s48_value scheme_boolean_p_function = S48_FALSE;
static s48_value scheme_integer_p_function = S48_FALSE;
/* prototypes */
s48_value ffit_enter_string_array(char**);
int length_scheme_list(s48_value);
int call_scheme_boolean_p(s48_value);
int call_scheme_integer_p(s48_value);
char** ffit_extract_list_of_strings(s48_value);
void ffit_init_hook(void);
/* macros */
#define FFIT_MAKE_ENTER_RECORD(FUNNAME, SCM_RECTYPE, C_RECTYPE) \
s48_value FUNNAME(C_RECTYPE c_rec) { \
s48_value scm_rec = S48_FALSE; \
S48_DECLARE_GC_PROTECT(1); \
\
S48_GC_PROTECT_1(scm_rec); \
scm_rec = s48_make_record(SCM_RECTYPE); \
S48_RECORD_SET(scm_rec, 0, s48_enter_integer((long) c_rec)); \
S48_GC_UNPROTECT(); \
return scm_rec; \
}
#define FFIT_MAKE_ENTER_RECORD_PROTOTYPE(FUNNAME, C_RECTYPE) \
s48_value FUNNAME(C_RECTYPE c_rec);
#define FFIT_RECORD_TYPE_INIT(C_RECTYPE, SCM_NAME) \
S48_GC_PROTECT_GLOBAL(C_RECTYPE); \
C_RECTYPE = s48_get_imported_binding("SCM_NAME");
#if 0
#define FFIT_CHECK_RECORD_TYPE(SCM_VAL, SCM_RECTYPE) \
if (!(S48_RECORD_P(SCM_VAL) && (S48_RECORD_TYPE(SCM_VAL) == SCM_RECTYPE))) \
s48_raise_argument_type_error(SCM_VAL)
#endif
#define FFIT_CHECK_RECORD_TYPE(SCM_VAL, SCM_RECTYPE) ;
#define FFIT_STRUCT_GET(FUNNAME, SCM_RECTYPE, C_RECTYPE, C_FIELD, FIELD_SCM_ENTER_FUN) \
s48_value FUNNAME(s48_value scm_rec) { \
s48_value res = S48_FALSE; \
C_RECTYPE c_rec; \
S48_DECLARE_GC_PROTECT(2); \
\
S48_GC_PROTECT_2(res, scm_rec); \
FFIT_CHECK_RECORD_TYPE(scm_rec, SCM_RECTYPE); \
c_rec = (C_RECTYPE) s48_extract_integer(S48_RECORD_REF(scm_rec, 0)); \
res = FIELD_SCM_ENTER_FUN(c_rec->C_FIELD); \
S48_GC_UNPROTECT(); \
return res; \
}
#define FFIT_STRUCT_GET_INT(FUNNAME, SCM_RECTYPE, C_RECTYPE, C_FIELD) \
FFIT_STRUCT_GET(FUNNAME, SCM_RECTYPE, C_RECTYPE, C_FIELD, s48_enter_integer);
#define FFIT_STRUCT_GET_CHAR(FUNNAME, SCM_RECTYPE, C_RECTYPE, C_FIELD) \
FFIT_STRUCT_GET(FUNNAMEm SCM_RECTYPE, C_RECTYPE, C_FIELD, s48_enter_char);
#define FFIT_STRUCT_GET_STRING(FUNNAME, SCM_RECTYPE, C_RECTYPE, C_FIELD) \
FFIT_STRUCT_GET(FUNNAME, SCM_RECTYPE, C_RECTYPE, C_FIELD, s48_enter_string);
/* predicates */
#define FFIT_LIST_P(x) (S48_PAIR_P(x) || (x == S48_NULL))
#define FFIT_CHECK_LIST(v) \
do { if (!FFIT_LIST_P(v)) s48_raise_argument_type_error(v); } while (0)
#define FFIT_CHECK_INTEGER(v) \
do { if (!call_scheme_integer_p(v)) s48_raise_argument_type_error(v); } while (0)
#define FFIT_CHECK_BOOLEAN(v) \
do { if (!call_scheme_boolean_p(v)) s48_raise_argument_type_error(v); } while (0)

128
ffi-tools/ffi-tools.scm Normal file
View File

@ -0,0 +1,128 @@
(define-record-type constant
(make-constant c-name scheme-name c-value-name type)
constant?
(c-name constant-c-name)
(scheme-name constant-scheme-name)
(c-value-name constant-c-value-name)
(type constant-type))
(define constant-type-int 'constant-type-int)
(define (constant-type-int? thing)
(equal? (constant-type thing) constant-type-int))
(define constant-type-char 'constant-type-char)
(define (constant-type-char? thing)
(equal? (constant-type thing) constant-type-char))
(define constant-type-string 'constant-type-string)
(define (constant-type-string? thing)
(equal? (constant-type thing) constant-type-string))
(define (constant-name->scheme-name constant-name)
(let ((replace-underscore
(lambda (c) (if (char=? c #\_) #\- c))))
(string-map replace-underscore (string-downcase constant-name))))
(define c-value-name-prefix "scheme_")
(define (constant-name->value-name constant-name)
(string-append c-value-name-prefix constant-name))
(define (make-constant-from-c-name c-name type)
(let ((scheme-name (constant-name->scheme-name c-name)))
(make-constant c-name scheme-name
(constant-name->value-name c-name)
type)))
(define (make-constant-from-c-name-integer c-name)
(make-constant-from-c-name c-name constant-type-int))
(define (generate-c-declarations constant-list)
(string-join
(map
(lambda (c)
(format "static s48_value ~a = S48_FALSE;~%"
(constant-c-value-name c)))
constant-list)))
(define (generate-c-gc-protect-globals constant-list)
(string-join
(map
(lambda (c)
(format "S48_GC_PROTECT_GLOBAL(~a);~%"
(constant-c-value-name c)))
constant-list)))
(define (generate-c-enter-value c)
(cond
((constant-type-int? c)
(format "~a = s48_enter_integer(~a);~%"
(constant-c-value-name c) (constant-c-name c)))
((constant-type-string? c)
(format "~a = s48_enter_integer(~a);~%"
(constant-c-value-name c) (constant-c-name c)))
(else
(error "Don't know how to handle this constant type: "
(constant-type c)))))
(define (generate-c-enter-values constant-list)
(string-join
(map generate-c-enter-value constant-list)))
(define (wrap-in-c-function fun-name body)
(format
(string-append
"void ~a(void) {~%"
"~a~%"
"}~%~%")
fun-name body))
(define (generate-c-enter-values-function c-fun-name constant-list)
(wrap-in-c-function c-fun-name
(generate-c-enter-values constant-list)))
(define (generate-c-gc-protect-globals-function c-fun-name constant-list)
(wrap-in-c-function c-fun-name
(generate-c-gc-protect-globals constant-list)))
;;; generating scheme code
(define (generate-finite-type-definition ft-name name-converter constants)
(let ((predicate-name (string-append ft-name "-object?"))
(elements-name (string-append ft-name "-elments"))
(name-name (string-append ft-name "-name"))
(index-name (string-append ft-name "-index"))
(id-name (string-append ft-name "-id")))
(format
(string-append
"(define-finite-type ~a :~a~%"
" (id)~%"
" ~a~% ~a~% ~a~% ~a~%"
" (~a)~%"
" ~a)~%~%")
ft-name ft-name
predicate-name elements-name name-name index-name
(string-append "id " id-name)
(generate-finite-type-items name-converter constants))))
(define (generate-finite-type-items name-converter constants)
(string-join
(map (lambda (c) (generate-finite-type-item name-converter c))
constants)))
(define (generate-finite-type-item name-converter constant)
(format " (~a\t(lookup-shared-binding \"~a\"))~%"
(name-converter constant)
(constant-c-value-name constant)))
(define (make-drop-common-prefix-name-converter prefix)
(let ((len (string-length prefix)))
(lambda (constant)
(let ((name (constant-c-name constant)))
(constant-name->scheme-name
(if (string-prefix? prefix name)
(string-drop name len)
name))))))

27
scheme/Makefile.am Normal file
View File

@ -0,0 +1,27 @@
SCSH= @SCSH@
scheme_SCRIPTS=load-ldap.scm
nobase_scheme_SCRIPTS= \
ldap.scm
EXTRA_DIST= load-ldap.scm.in $(nobase_scheme_SCRIPTS)
GENERATED_CODE= const-gen.scm
CLEANFILES= load-ldap.scm $(GENERATED_CODE)
$(GENERATED_CODE):
$(SCSH) -lm ffi-tools-packages.scm -lm ldap-constants.scm \
-o ldap-constants -c '(make-c-files command-line-arguments)' \
`pwd`
load-ldap.scm: $(srcdir)/load-ldap.scm.in
sed -e "s|@scshldapschemedir@|`pwd`/$(srcdir)|g" \
-e "s|@scshldaphost@||g" \
-e "s|@scshldaplibdir@|`pwd`/../c/.libs|g" \
$< > $@
install-data-hook:
sed -e "s|@scshldapschemedir@|$(schemedir)|g" \
-e "s|@scshldaphost@|(host)|g" \
-e "s|@scshldaplibdir@|$(libdir)|g" \
$(srcdir)/load-ldap.scm.in \
> $(DESTDIR)/$(schemedir)/load-ldap.scm

24
scheme/configure.scm Normal file
View File

@ -0,0 +1,24 @@
(define-structure configure (export host)
(open scheme-with-scsh
srfi-13)
(begin
(define (canonical-machine uname-record)
(let* ((machine (uname:machine uname-record))
(os (uname:os-name uname-record)))
(cond
((member machine '("i386" "i486" "i586" "i686")) "i386")
((or (string=? machine "Power Macintosh")
(and (string=? os "AIX")
(regexp-search? (rx (: "00" (= 6 digit) any any "00"))
machine)))
"powerpc")
(else machine))))
(define (canonical-os-name uname-record)
(string-downcase (uname:os-name uname-record)))
(define (host)
(let ((uname-record (uname)))
(string-append (canonical-machine uname-record)
"-"
(canonical-os-name uname-record))))))

128
scheme/ldap-constants.scm Normal file
View File

@ -0,0 +1,128 @@
(define-interface ldap-constants-interface
(export
make-c-files
make-scm-files))
(define-structure ldap-constants ldap-constants-interface
(open
scheme signals
ffi-import-constants)
(begin
(define ldap-return-codes
(map make-constant-from-c-name-integer
'("LDAP_SUCCESS"
"LDAP_OPERATIONS_ERROR"
"LDAP_PROTOCOL_ERROR"
"LDAP_TIMELIMIT_EXCEEDED"
"LDAP_SIZELIMIT_EXCEEDED"
"LDAP_COMPARE_FALSE"
"LDAP_COMPARE_TRUE"
"LDAP_STRONG_AUTH_NOT_SUPPORTED"
"LDAP_STRONG_AUTH_REQUIRED"
"LDAP_REFERRAL"
"LDAP_ADMINLIMIT_EXCEEDED"
"LDAP_UNAVAILABLE_CRITICAL_EXTENSION"
"LDAP_CONFIDENTIALITY_REQUIRED"
"LDAP_SASL_BIND_IN_PROGRESS"
"LDAP_NO_SUCH_ATTRIBUTE"
"LDAP_UNDEFINED_TYPE"
"LDAP_INAPPROPRIATE_MATCHING"
"LDAP_CONSTRAINT_VIOLATION"
"LDAP_TYPE_OR_VALUE_EXISTS"
"LDAP_INVALID_SYNTAX"
"LDAP_NO_SUCH_OBJECT"
"LDAP_ALIAS_PROBLEM"
"LDAP_INVALID_DN_SYNTAX"
"LDAP_IS_LEAF"
"LDAP_ALIAS_DEREF_PROBLEM"
"LDAP_INAPPROPRIATE_AUTH"
"LDAP_INVALID_CREDENTIALS"
"LDAP_INSUFFICIENT_ACCESS"
"LDAP_BUSY"
"LDAP_UNAVAILABLE"
"LDAP_UNWILLING_TO_PERFORM"
"LDAP_LOOP_DETECT"
"LDAP_NAMING_VIOLATION"
"LDAP_OBJECT_CLASS_VIOLATION"
"LDAP_NOT_ALLOWED_ON_NONLEAF"
"LDAP_NOT_ALLOWED_ON_RDN"
"LDAP_ALREADY_EXISTS"
"LDAP_NO_OBJECT_CLASS_MODS"
"LDAP_RESULTS_TOO_LARGE"
"LDAP_AFFECTS_MULTIPLE_DSAS"
"LDAP_OTHER"
"LDAP_SERVER_DOWN"
"LDAP_LOCAL_ERROR"
"LDAP_ENCODING_ERROR"
"LDAP_DECODING_ERROR"
"LDAP_TIMEOUT"
"LDAP_AUTH_UNKNOWN"
"LDAP_FILTER_ERROR"
"LDAP_USER_CANCELLED"
"LDAP_PARAM_ERROR"
"LDAP_NO_MEMORY"
"LDAP_CONNECT_ERROR"
"LDAP_NOT_SUPPORTED"
"LDAP_CONTROL_NOT_FOUND"
"LDAP_NO_RESULTS_RETURNED"
"LDAP_MORE_RESULTS_TO_RETURN"
"LDAP_CLIENT_LOOP"
"LDAP_REFERRAL_LIMIT_EXCEEDED")))
(define ldap-opt-protocol-version
(map make-constant-from-c-name-integer
'("LDAP_VERSION" "LDAP_VERSION3")))
(define ldap-all-constants
(append ldap-return-codes
ldap-opt-protocol-version))
(define (write-source-file name string)
(call-with-output-file name
(lambda (port)
(display string port))))
(define (generate-ldap-consts-c path)
(write-source-file
(string-append path "/ldap-consts.c")
(string-append
"#include \"scheme48.h\"\n"
"#include <ldap.h>\n"
(generate-c-declarations ldap-all-constants)
(generate-c-enter-values-function
"scsh_ldap_enter_ldap_constants"
ldap-all-constants)
(generate-c-gc-protect-globals-function
"scsh_ldap_gc_protect_globals"
ldap-all-constants))))
(define (generate-const-gen-scm path)
(write-source-file
(string-append path "/const-gen.scm")
(string-append
(generate-finite-type-definition
"ldap-return" (make-drop-common-prefix-name-converter "LDAP_")
ldap-return-codes)
(generate-finite-type-definition
"ldap-option-version" (make-drop-common-prefix-name-converter "LDAP_")
ldap-opt-protocol-version))))
(define (make-c-files args)
(if (null? args)
(error "missing parameter")
(let ((path (car args)))
(generate-ldap-consts-c path))))
(define (make-scm-files args)
(if (null? args)
(error "missing parameter")
(let ((path (car args)))
(generate-const-gen-scm path))))
))

View File

@ -8,4 +8,17 @@
ldap-bind-sync
ldap-unbind-sync
ldap-error-string
ldap-result-error))
ldap-result-error))
(define-interface ldap-types-interface
(export
ldap?
ldap-message?
ldap-modification?
ldap-api-info?
ldap-api-info-info-version
ldap-api-info-api-version
ldap-api-info-protocol-version
ldap-api-info-vendor-name
ldap-api-info-vendor-version))

View File

@ -1,6 +1,7 @@
(define-structure ldap-low ldap-low-interface
(open scheme
primitives
define-record-types
external-calls)
(files ldap))
primitives
external-calls
ffi-tools-rts)
(files ldap const-gen))

47
scheme/ldap-records.scm Normal file
View File

@ -0,0 +1,47 @@
(define-record-type ldap :ldap
(make-ldap c-pointer)
ldap?
(c-pointer ldap-c-pointer))
(define-exported-binding "ldap" :ldap)
(define-record-type ldap-message :ldap-message
(make-ldap-message c-pointer)
ldap-message?
(c-pointer ldap-message-c-pointer))
(define-exported-binding "ldap-message" :ldap-message)
(define-record-type ldap-modification :ldap-modification
(make-ldap-modification c-pointer)
ldap-modification?
(c-pointer ldap-modification-c-pointer))
(define-exported-binding "ldap-modification" :ldap-modification)
(define-record-type ldap-api-info :ldap-api-info
(make-ldap-api-info c-pointer)
ldap-api-info?
(c-pointer ldap-api-info-c-pointer))
(define-exported-binding "ldap-api-info" :ldap-api-info)
(import-lambda-definition ldap-api-info-info-version
(ldap-ai)
"scsh_ldapapiinfo_get_info_version")
(import-lambda-definition ldap-api-info-api-version
(ldap-ai)
"scsh_ldapapiinfo_get_api_version")
(import-lambda-definition ldap-api-info-protocol-version
(ldap-ai)
"scsh_ldapapiinfo_get_protocol_version")
(import-lambda-definition ldap-api-info-vendor-name
(ldap-ai)
"scsh_ldapapiinfo_get_vendor_name")
(import-lambda-definition ldap-api-info-vendor-version
(ldap-ai)
"scsh_ldapapiinfo_get_vendor_version")

View File

@ -1,26 +1,4 @@
(define-record-type ldap :ldap
(make-ldap c-pointer)
ldap?
(c-pointer ldap-c-pointer))
(define-exported-binding "ldap" :ldap)
(define-record-type ldap-message :ldap-message
(make-ldap-message c-pointer)
ldap-message?
(c-pointer ldap-message-c-pointer))
(define-exported-binding "ldap-message" :ldap-message)
(define (ldap-open host port)
(let ((ldap (ldap-open-internal host port)))
(if ldap (add-finalizer! ldap ldap-memfree))
ldap))
(define (ldap-init host port)
(let ((ldap (ldap-init-internal host port)))
(if ldap (add-finalizer! ldap ldap-memfree))
ldap))
; ,open define-record-types external-calls
(import-lambda-definition ldap-open-internal
(host port)
@ -95,4 +73,19 @@
(ldap message attribute)
"scsh_ldap_get_values")
(define (ldap-open host port)
(let ((ldap (ldap-open-internal host port)))
(if ldap (add-finalizer! ldap ldap-memfree))
ldap))
(define (ldap-init host port)
(let ((ldap (ldap-init-internal host port)))
(if ldap (add-finalizer! ldap ldap-memfree))
ldap))
;;; import functions from C
(define c-value->ldap-success
(make-finite-type-import-function
'ldap-success ldap-success-elements ldap-success-id))

17
scheme/load-ldap.scm.in Normal file
View File

@ -0,0 +1,17 @@
(config)
(load "@scshldapschemedir@/configure.scm")
(user)
(load-package 'dynamic-externals)
(open 'dynamic-externals)
(open 'external-calls)
(load-package 'configure)
(open 'configure)
(run '(let ((initializer-name "scx_init_xlib")
(module-file (string-append "@scshldaplibdir@/" @scshldaphost@ "/libscshldap.so")))
(dynamic-load module-file)
(call-external (get-external initializer-name))))
(config)
(load "@scshldapschemedir@/ldap-interfaces.scm")
(load "@schhldapschemedir@/ldap-packages.scm")