summaryrefslogtreecommitdiffstats
path: root/ldap/servers/plugins/syntaxes
diff options
context:
space:
mode:
Diffstat (limited to 'ldap/servers/plugins/syntaxes')
-rw-r--r--ldap/servers/plugins/syntaxes/Makefile87
-rw-r--r--ldap/servers/plugins/syntaxes/bin.c201
-rw-r--r--ldap/servers/plugins/syntaxes/ces.c168
-rw-r--r--ldap/servers/plugins/syntaxes/cis.c298
-rw-r--r--ldap/servers/plugins/syntaxes/debug.c20
-rw-r--r--ldap/servers/plugins/syntaxes/dllmain.c133
-rw-r--r--ldap/servers/plugins/syntaxes/dn.c98
-rw-r--r--ldap/servers/plugins/syntaxes/int.c188
-rw-r--r--ldap/servers/plugins/syntaxes/libsyntax.def24
-rw-r--r--ldap/servers/plugins/syntaxes/phonetic.c461
-rw-r--r--ldap/servers/plugins/syntaxes/sicis.c139
-rw-r--r--ldap/servers/plugins/syntaxes/string.c612
-rw-r--r--ldap/servers/plugins/syntaxes/syntax.h42
-rw-r--r--ldap/servers/plugins/syntaxes/tel.c135
-rw-r--r--ldap/servers/plugins/syntaxes/value.c209
15 files changed, 2815 insertions, 0 deletions
diff --git a/ldap/servers/plugins/syntaxes/Makefile b/ldap/servers/plugins/syntaxes/Makefile
new file mode 100644
index 00000000..edc9bd9c
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/Makefile
@@ -0,0 +1,87 @@
+#
+# BEGIN COPYRIGHT BLOCK
+# Copyright 2001 Sun Microsystems, Inc.
+# Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+# All rights reserved.
+# END COPYRIGHT BLOCK
+#
+#
+# GNU Makefile for Directory Server syntax-plugin.so syntax plugins
+#
+
+LDAP_SRC = ../../..
+MCOM_ROOT = ../../../../..
+
+NOSTDCLEAN=true # don't let nsconfig.mk define target clean
+NOSTDSTRIP=true # don't let nsconfig.mk define target strip
+NSPR20=true # probably should be defined somewhere else (not sure where)
+
+OBJDEST = $(OBJDIR)/lib/libsyntax
+LIBDIR = $(LIB_RELDIR)
+
+include $(MCOM_ROOT)/ldapserver/nsconfig.mk
+include $(LDAP_SRC)/nsldap.mk
+
+ifeq ($(ARCH), WINNT)
+DEF_FILE:=./libsyntax.def
+endif
+
+CFLAGS+=$(SLCFLAGS)
+
+INCLUDES += -I$(LDAP_SRC)/servers/slapd
+
+SYNTAX_OBJS= phonetic.o string.o cis.o sicis.o ces.o bin.o tel.o dn.o int.o \
+ value.o debug.o
+
+OBJS = $(addprefix $(OBJDEST)/, $(SYNTAX_OBJS))
+
+ifeq ($(ARCH), WINNT)
+LIBSYNTAX_DLL_OBJ = $(addprefix $(OBJDEST)/, dllmain.o)
+endif
+
+LIBSYNTAX= $(addprefix $(LIBDIR)/, $(SYNTAX_DLL).$(DLL_SUFFIX))
+
+ifeq ($(ARCH), WINNT)
+EXTRA_LIBS_DEP += $(LIBSLAPD_DEP) $(LDAP_LIBUTIL_DEP)
+EXTRA_LIBS_DEP += $(LDAPSDK_DEP)
+EXTRA_LIBS += $(LIBSLAPD) $(LDAP_SDK_LIBLDAP_DLL)
+endif
+ifeq ($(ARCH), AIX)
+EXTRA_LIBS_DEP += $(LIBSLAPD_DEP) $(LDAP_LIBUTIL_DEP)
+EXTRA_LIBS_DEP += $(LDAPSDK_DEP)
+EXTRA_LIBS += $(LIBSLAPD) $(LDAP_SDK_LIBLDAP_DLL)
+endif
+
+ifeq ($(ARCH), WINNT)
+DLL_LDFLAGS += -def:"./libsyntax.def"
+CFLAGS+= /WX
+endif # WINNT
+
+ifeq ($(ARCH), HPUX)
+EXTRA_LIBS_DEP += $(LIBSLAPD_DEP) $(LDAPSDK_DEP) $(NSPR_DEP) $(SECURITY_DEP)
+EXTRA_LIBS += $(DYN_NSHTTPD) $(ADMINUTIL_LINK) $(LDAPLINK) $(SECURITYLINK) $(NSPRLINK) $(ICULINK)
+endif
+
+ifeq ($(ARCH), AIX)
+EXTRA_LIBS += $(DLL_EXTRA_LIBS)
+LD=ld
+endif
+
+clientSDK:
+
+all: $(OBJDEST) $(LIBDIR) $(LIBSYNTAX)
+
+$(LIBSYNTAX): $(OBJS) $(LIBSYNTAX_DLL_OBJ) $(DEF_FILE)
+ $(LINK_DLL) $(LIBSYNTAX_DLL_OBJ) $(EXTRA_LIBS)
+
+veryclean: clean
+
+clean:
+ $(RM) $(OBJS)
+ifeq ($(ARCH), WINNT)
+ $(RM) $(LIBSYNTAX_DLL_OBJ)
+endif
+ $(RM) $(LIBSYNTAX)
+
+$(OBJDEST):
+ $(MKDIR) $(OBJDEST)
diff --git a/ldap/servers/plugins/syntaxes/bin.c b/ldap/servers/plugins/syntaxes/bin.c
new file mode 100644
index 00000000..da06e55e
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/bin.c
@@ -0,0 +1,201 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/* bin.c - bin syntax routines */
+
+/*
+ * This file actually implements two syntax plugins: OctetString and Binary.
+ * We treat them identically for now. XXXmcs: check if that is correct.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "syntax.h"
+
+static int bin_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
+ Slapi_Value **bvals, int ftype, Slapi_Value **retVal );
+static int bin_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
+ Slapi_Value ***ivals, int ftype );
+static int bin_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *bval,
+ Slapi_Value ***ivals, int ftype );
+
+/*
+ * Attribute syntaxes. We treat all of these the same for now, even though
+ * the specifications (e.g., RFC 2252) impose various constraints on the
+ * the format for each of these.
+ *
+ * Note: the first name is the official one from RFC 2252.
+ */
+static char *bin_names[] = { "Binary", "bin", BINARY_SYNTAX_OID, 0 };
+
+static char *octetstring_names[] = { "OctetString", OCTETSTRING_SYNTAX_OID, 0 };
+
+static char *jpeg_names[] = { "JPEG", JPEG_SYNTAX_OID, 0 };
+
+
+static Slapi_PluginDesc bin_pdesc = {
+ "bin-syntax", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT,
+ "binary attribute syntax plugin"
+};
+
+static Slapi_PluginDesc octetstring_pdesc = {
+ "octetstring-syntax", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT,
+ "octet string attribute syntax plugin"
+};
+
+static Slapi_PluginDesc jpeg_pdesc = {
+ "jpeg-syntax", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT,
+ "JPEG attribute syntax plugin"
+};
+
+
+/*
+ * register_bin_like_plugin(): register all items for a bin-like plugin.
+ */
+static int
+register_bin_like_plugin( Slapi_PBlock *pb, Slapi_PluginDesc *pdescp,
+ char **names, char *oid )
+{
+ int rc;
+
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_01 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *)pdescp );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_AVA,
+ (void *) bin_filter_ava );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALUES2KEYS,
+ (void *) bin_values2keys );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA,
+ (void *) bin_assertion2keys_ava );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_NAMES,
+ (void *) names );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_OID,
+ (void *) oid );
+
+ return( rc );
+}
+
+
+int
+bin_init( Slapi_PBlock *pb )
+{
+ int rc;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> bin_init\n", 0, 0, 0 );
+ rc = register_bin_like_plugin( pb, &bin_pdesc, bin_names,
+ BINARY_SYNTAX_OID );
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= bin_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+
+int
+octetstring_init( Slapi_PBlock *pb )
+{
+ int rc;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> octetstring_init\n", 0, 0, 0 );
+ rc = register_bin_like_plugin( pb, &octetstring_pdesc, octetstring_names,
+ OCTETSTRING_SYNTAX_OID );
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= octetstring_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+
+int
+jpeg_init( Slapi_PBlock *pb )
+{
+ int rc;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> jpeg_init\n", 0, 0, 0 );
+ rc = register_bin_like_plugin( pb, &jpeg_pdesc, jpeg_names,
+ JPEG_SYNTAX_OID );
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= jpeg_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+
+static int
+bin_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
+ Slapi_Value **bvals, int ftype, Slapi_Value **retVal )
+{
+ int i;
+
+ for ( i = 0; bvals[i] != NULL; i++ ) {
+ if ( slapi_value_get_length(bvals[i]) == bvfilter->bv_len &&
+ 0 == memcmp( slapi_value_get_string(bvals[i]), bvfilter->bv_val, bvfilter->bv_len ))
+ {
+ if(retVal!=NULL)
+ {
+ *retVal= bvals[i];
+ }
+ return( 0 );
+ }
+ }
+ if(retVal!=NULL)
+ {
+ *retVal= NULL;
+ }
+ return( -1 );
+}
+
+static int
+bin_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
+ Slapi_Value ***ivals, int ftype )
+{
+ int i;
+
+ if ( ftype != LDAP_FILTER_EQUALITY ) {
+ return( LDAP_PROTOCOL_ERROR );
+ }
+
+ for ( i = 0; bvals[i] != NULL; i++ ) {
+ /* NULL */
+ }
+ (*ivals) = (Slapi_Value **) slapi_ch_malloc(( i + 1 ) *
+ sizeof(Slapi_Value *) );
+
+ for ( i = 0; bvals[i] != NULL; i++ )
+ {
+ (*ivals)[i] = slapi_value_dup(bvals[i]);
+ }
+ (*ivals)[i] = NULL;
+
+ return( 0 );
+}
+
+static int
+bin_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *bval,
+ Slapi_Value ***ivals, int ftype )
+{
+ Slapi_Value *tmpval=NULL;
+ size_t len;
+
+ if (( ftype != LDAP_FILTER_EQUALITY ) &&
+ ( ftype != LDAP_FILTER_EQUALITY_FAST))
+ {
+ return( LDAP_PROTOCOL_ERROR );
+ }
+ if(ftype == LDAP_FILTER_EQUALITY_FAST) {
+ /* With the fast option, we are trying to avoid creating and freeing
+ * a bunch of structures - we just do one malloc here - see
+ * ava_candidates in filterentry.c
+ */
+ len=slapi_value_get_length(bval);
+ tmpval=(*ivals)[0];
+ if (len > tmpval->bv.bv_len) {
+ tmpval->bv.bv_val=(char *)slapi_ch_malloc(len);
+ }
+ tmpval->bv.bv_len=len;
+ memcpy(tmpval->bv.bv_val,slapi_value_get_string(bval),len);
+ } else {
+ (*ivals) = (Slapi_Value **) slapi_ch_malloc( 2 * sizeof(Slapi_Value *) );
+ (*ivals)[0] = slapi_value_dup( bval );
+ (*ivals)[1] = NULL;
+ }
+ return( 0 );
+}
diff --git a/ldap/servers/plugins/syntaxes/ces.c b/ldap/servers/plugins/syntaxes/ces.c
new file mode 100644
index 00000000..075da03b
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/ces.c
@@ -0,0 +1,168 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/* ces.c - caseexactstring syntax routines */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "syntax.h"
+
+static int ces_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
+ Slapi_Value **bvals, int ftype, Slapi_Value **retVal );
+static int ces_filter_sub( Slapi_PBlock *pb, char *initial, char **any,
+ char *final, Slapi_Value **bvals );
+static int ces_values2keys( Slapi_PBlock *pb, Slapi_Value **val,
+ Slapi_Value ***ivals, int ftype );
+static int ces_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *val,
+ Slapi_Value ***ivals, int ftype );
+static int ces_assertion2keys_sub( Slapi_PBlock *pb, char *initial, char **any,
+ char *final, Slapi_Value ***ivals );
+static int ces_compare(struct berval *v1, struct berval *v2);
+
+/* the first name is the official one from RFC 2252 */
+static char *ia5_names[] = { "IA5String", "ces", "caseexactstring",
+ IA5STRING_SYNTAX_OID, 0 };
+
+/* the first name is the official one from RFC 2252 */
+static char *uri_names[] = { "URI", "1.3.6.1.4.1.4401.1.1.1",0};
+
+static Slapi_PluginDesc ia5_pdesc = { "ces-syntax", PLUGIN_MAGIC_VENDOR_STR,
+ PRODUCTTEXT, "caseExactString attribute syntax plugin" };
+
+static Slapi_PluginDesc uri_pdesc = { "uri-syntax", PLUGIN_MAGIC_VENDOR_STR,
+ PRODUCTTEXT, "uri attribute syntax plugin" };
+
+
+/*
+ * register_ces_like_plugin(): register all items for a cis-like plugin.
+ */
+static int
+register_ces_like_plugin( Slapi_PBlock *pb, Slapi_PluginDesc *pdescp,
+ char **names, char *oid )
+{
+ int rc, flags;
+
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_01 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *) pdescp );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_AVA,
+ (void *) ces_filter_ava );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_SUB,
+ (void *) ces_filter_sub );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALUES2KEYS,
+ (void *) ces_values2keys );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA,
+ (void *) ces_assertion2keys_ava );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_SUB,
+ (void *) ces_assertion2keys_sub );
+ flags = SLAPI_PLUGIN_SYNTAX_FLAG_ORDERING;
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FLAGS,
+ (void *) &flags );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_NAMES,
+ (void *) names );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_OID,
+ (void *) oid );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_COMPARE,
+ (void *) ces_compare );
+
+ return( rc );
+}
+
+int
+ces_init( Slapi_PBlock *pb )
+{
+ int rc;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> ces_init\n", 0, 0, 0 );
+
+ rc = register_ces_like_plugin(pb,&ia5_pdesc,ia5_names,IA5STRING_SYNTAX_OID);
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= ces_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+int
+uri_init( Slapi_PBlock *pb )
+{
+ int rc;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> uri_init\n", 0, 0, 0 );
+
+ rc = register_ces_like_plugin(pb,&uri_pdesc,uri_names,
+ "1.3.6.1.4.1.4401.1.1.1");
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= uri_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+static int
+ces_filter_ava(
+ Slapi_PBlock *pb,
+ struct berval *bvfilter,
+ Slapi_Value **bvals,
+ int ftype,
+ Slapi_Value **retVal
+)
+{
+ return( string_filter_ava( bvfilter, bvals, SYNTAX_CES, ftype,
+ retVal) );
+}
+
+static int
+ces_filter_sub(
+ Slapi_PBlock *pb,
+ char *initial,
+ char **any,
+ char *final,
+ Slapi_Value **bvals
+)
+{
+ return( string_filter_sub( pb, initial, any, final, bvals, SYNTAX_CES ) );
+}
+
+static int
+ces_values2keys(
+ Slapi_PBlock *pb,
+ Slapi_Value **vals,
+ Slapi_Value ***ivals,
+ int ftype
+)
+{
+ return( string_values2keys( pb, vals, ivals, SYNTAX_CES, ftype ) );
+}
+
+static int
+ces_assertion2keys_ava(
+ Slapi_PBlock *pb,
+ Slapi_Value *val,
+ Slapi_Value ***ivals,
+ int ftype
+)
+{
+ return(string_assertion2keys_ava( pb, val, ivals, SYNTAX_CES, ftype ));
+}
+
+static int
+ces_assertion2keys_sub(
+ Slapi_PBlock *pb,
+ char *initial,
+ char **any,
+ char *final,
+ Slapi_Value ***ivals
+)
+{
+ return( string_assertion2keys_sub( pb, initial, any, final, ivals,
+ SYNTAX_CES ) );
+}
+
+static int ces_compare(
+ struct berval *v1,
+ struct berval *v2
+)
+{
+ return value_cmp(v1,v2,SYNTAX_CES,3 /* Normalise both values */);
+}
diff --git a/ldap/servers/plugins/syntaxes/cis.c b/ldap/servers/plugins/syntaxes/cis.c
new file mode 100644
index 00000000..e2047fbc
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/cis.c
@@ -0,0 +1,298 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/* cis.c - caseignorestring syntax routines */
+
+/*
+ * This file actually implements three syntax plugins:
+ * DirectoryString
+ * Boolean
+ * GeneralizedTime
+ *
+ * We treat them identically for now. XXXmcs: we could do some validation on
+ * Boolean and GeneralizedTime values (someday, maybe).
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "syntax.h"
+
+static int cis_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
+ Slapi_Value **bvals, int ftype, Slapi_Value **retVal );
+static int cis_filter_sub( Slapi_PBlock *pb, char *initial, char **any,
+ char *final, Slapi_Value **bvals );
+static int cis_values2keys( Slapi_PBlock *pb, Slapi_Value **val,
+ Slapi_Value ***ivals, int ftype );
+static int cis_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *val,
+ Slapi_Value ***ivals, int ftype );
+static int cis_assertion2keys_sub( Slapi_PBlock *pb, char *initial, char **any,
+ char *final, Slapi_Value ***ivals );
+static int cis_compare(struct berval *v1, struct berval *v2);
+
+/*
+ * Attribute syntaxes. We treat all of these the same for now, even though
+ * the specifications (e.g., RFC 2252) impose various constraints on the
+ * the format for each of these.
+ *
+ * Note: the first name is the official one from RFC 2252.
+ */
+static char *dirstring_names[] = { "DirectoryString", "cis",
+ "caseignorestring", DIRSTRING_SYNTAX_OID, 0 };
+
+static char *boolean_names[] = { "Boolean", BOOLEAN_SYNTAX_OID, 0 };
+
+static char *time_names[] = { "GeneralizedTime", "time",
+ GENERALIZEDTIME_SYNTAX_OID, 0 };
+
+static char *country_names[] = { "Country String",
+ COUNTRYSTRING_SYNTAX_OID, 0};
+
+static char *postal_names[] = { "Postal Address",
+ POSTALADDRESS_SYNTAX_OID, 0};
+
+static char *oid_names[] = { "OID",
+ OID_SYNTAX_OID, 0};
+
+
+/*
+ TBD (XXX)
+
+ "1.3.6.1.4.1.1466.115.121.1.16 \"DIT Content Rule Description
+\" "
+ "1.3.6.1.4.1.1466.115.121.1.17 \"DIT Structure Rule Descripti
+on\" "
+ "1.3.6.1.4.1.1466.115.121.1.20 \"DSE Type\" "
+ "1.3.6.1.4.1.1466.115.121.1.30 \"Matching Rule Description\"
+"
+ "1.3.6.1.4.1.1466.115.121.1.31 \"Matching Rule Use Descriptio
+n\" "
+ "1.3.6.1.4.1.1466.115.121.1.35 \"Name Form Description\" "
+
+ "1.3.6.1.4.1.1466.115.121.1.44 \"Printable String\" "
+ "1.3.6.1.4.1.1466.115.121.1.45 \"Subtree Specification\" "
+ "1.3.6.1.4.1.1466.115.121.1.54 \"LDAP Syntax Description\" "
+ "1.3.6.1.4.1.1466.115.121.1.55 \"Modify Rights\" "
+ "1.3.6.1.4.1.1466.115.121.1.56 \"LDAP Schema Description\" "
+ "1.3.6.1.4.1.1466.115.121.1.25 \"Guide\" "
+ "1.3.6.1.4.1.1466.115.121.1.52 \"Telex Number\" "
+ "1.3.6.1.4.1.1466.115.121.1.51 \"Teletex Terminal Identifier\
+" "
+ "1.3.6.1.4.1.1466.115.121.1.14 \"Delivery Method\" "
+ "1.3.6.1.4.1.1466.115.121.1.43 \"Presentation Address\" "
+ "1.3.6.1.4.1.1466.115.121.1.21 \"Enhanced Guide\" "
+ "1.3.6.1.4.1.1466.115.121.1.34 \"Name and Optional UID\" "
+ "1.2.840.113556.1.4.905 \"CaseIgnoreString\" "
+ "1.3.6.1.1.1.0.0 \"nisNetgroupTripleSyntax\" "
+ "1.3.6.1.1.1.0.1 \"bootParameterSyntax\" ");
+ */
+
+
+static Slapi_PluginDesc dirstring_pdesc = { "directorystring-syntax",
+ PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT,
+ "DirectoryString attribute syntax plugin" };
+
+static Slapi_PluginDesc boolean_pdesc = { "boolean-syntax",
+ PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT,
+ "Boolean attribute syntax plugin" };
+
+static Slapi_PluginDesc time_pdesc = { "time-syntax",
+ PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT,
+ "GeneralizedTime attribute syntax plugin" };
+
+static Slapi_PluginDesc country_pdesc = { "countrystring-syntax",
+ PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT,
+ "Country String attribute syntax plugin" };
+
+static Slapi_PluginDesc postal_pdesc = { "postaladdress-syntax",
+ PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT,
+ "Postal Address attribute syntax plugin" };
+
+static Slapi_PluginDesc oid_pdesc = { "oid-syntax",
+ PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT,
+ "OID attribute syntax plugin" };
+
+
+/*
+ * register_cis_like_plugin(): register all items for a cis-like plugin.
+ */
+static int
+register_cis_like_plugin( Slapi_PBlock *pb, Slapi_PluginDesc *pdescp,
+ char **names, char *oid )
+{
+ int rc, flags;
+
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_01 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *) pdescp );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_AVA,
+ (void *) cis_filter_ava );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_SUB,
+ (void *) cis_filter_sub );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALUES2KEYS,
+ (void *) cis_values2keys );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA,
+ (void *) cis_assertion2keys_ava );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_SUB,
+ (void *) cis_assertion2keys_sub );
+ flags = SLAPI_PLUGIN_SYNTAX_FLAG_ORDERING;
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FLAGS,
+ (void *) &flags );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_NAMES,
+ (void *) names );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_OID,
+ (void *) oid );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_COMPARE,
+ (void *) cis_compare );
+
+ return( rc );
+}
+
+
+int
+cis_init( Slapi_PBlock *pb )
+{
+ int rc;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> cis_init\n", 0, 0, 0 );
+ rc = register_cis_like_plugin( pb, &dirstring_pdesc, dirstring_names,
+ DIRSTRING_SYNTAX_OID );
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= cis_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+
+int
+boolean_init( Slapi_PBlock *pb )
+{
+ int rc;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> boolean_init\n", 0, 0, 0 );
+ rc = register_cis_like_plugin( pb, &boolean_pdesc, boolean_names,
+ BOOLEAN_SYNTAX_OID );
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= boolean_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+
+int
+time_init( Slapi_PBlock *pb )
+{
+ int rc;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> time_init\n", 0, 0, 0 );
+ rc = register_cis_like_plugin( pb, &time_pdesc, time_names,
+ GENERALIZEDTIME_SYNTAX_OID );
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= time_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+int
+country_init( Slapi_PBlock *pb )
+{
+ int rc;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> country_init\n", 0, 0, 0 );
+ rc = register_cis_like_plugin( pb, &country_pdesc, country_names,
+ COUNTRYSTRING_SYNTAX_OID );
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= country_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+int
+postal_init( Slapi_PBlock *pb )
+{
+ int rc;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> postal_init\n", 0, 0, 0 );
+ rc = register_cis_like_plugin( pb, &postal_pdesc, postal_names,
+ POSTALADDRESS_SYNTAX_OID );
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= postal_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+
+int
+oid_init( Slapi_PBlock *pb )
+{
+ int rc;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> oid_init\n", 0, 0, 0 );
+ rc = register_cis_like_plugin( pb, &oid_pdesc, oid_names, OID_SYNTAX_OID );
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= oid_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+
+
+static int
+cis_filter_ava(
+ Slapi_PBlock *pb,
+ struct berval *bvfilter,
+ Slapi_Value **bvals,
+ int ftype,
+ Slapi_Value **retVal
+)
+{
+ return( string_filter_ava( bvfilter, bvals, SYNTAX_CIS, ftype,
+ retVal ) );
+}
+
+
+static int
+cis_filter_sub(
+ Slapi_PBlock *pb,
+ char *initial,
+ char **any,
+ char *final,
+ Slapi_Value **bvals
+)
+{
+ return( string_filter_sub( pb, initial, any, final, bvals, SYNTAX_CIS ) );
+}
+
+static int
+cis_values2keys(
+ Slapi_PBlock *pb,
+ Slapi_Value **vals,
+ Slapi_Value ***ivals,
+ int ftype
+)
+{
+ return( string_values2keys( pb, vals, ivals, SYNTAX_CIS, ftype ) );
+}
+
+static int
+cis_assertion2keys_ava(
+ Slapi_PBlock *pb,
+ Slapi_Value *val,
+ Slapi_Value ***ivals,
+ int ftype
+)
+{
+ return(string_assertion2keys_ava( pb, val, ivals, SYNTAX_CIS, ftype ));
+}
+
+static int
+cis_assertion2keys_sub(
+ Slapi_PBlock *pb,
+ char *initial,
+ char **any,
+ char *final,
+ Slapi_Value ***ivals
+)
+{
+ return( string_assertion2keys_sub( pb, initial, any, final, ivals,
+ SYNTAX_CIS ) );
+}
+
+static int cis_compare(
+ struct berval *v1,
+ struct berval *v2
+)
+{
+ return value_cmp(v1,v2,SYNTAX_CIS,3 /* Normalise both values */);
+}
diff --git a/ldap/servers/plugins/syntaxes/debug.c b/ldap/servers/plugins/syntaxes/debug.c
new file mode 100644
index 00000000..e4d69202
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/debug.c
@@ -0,0 +1,20 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/* debug.c - syntax debug stuff */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "syntax.h"
+
+#ifdef _WIN32
+int *module_ldap_debug = 0;
+
+void plugin_init_debug_level(int *level_ptr)
+{
+ module_ldap_debug = level_ptr;
+}
+#endif
diff --git a/ldap/servers/plugins/syntaxes/dllmain.c b/ldap/servers/plugins/syntaxes/dllmain.c
new file mode 100644
index 00000000..1f7aa331
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/dllmain.c
@@ -0,0 +1,133 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/*
+ * Microsoft Windows specifics for syntax-plugin DLL
+ */
+#include "ldap.h"
+#include "syntax.h"
+
+
+#ifdef _WIN32
+/* Lifted from Q125688
+ * How to Port a 16-bit DLL to a Win32 DLL
+ * on the MSVC 4.0 CD
+ */
+BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
+{
+ WSADATA wsadata;
+
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ /* Code from LibMain inserted here. Return TRUE to keep the
+ DLL loaded or return FALSE to fail loading the DLL.
+
+ You may have to modify the code in your original LibMain to
+ account for the fact that it may be called more than once.
+ You will get one DLL_PROCESS_ATTACH for each process that
+ loads the DLL. This is different from LibMain which gets
+ called only once when the DLL is loaded. The only time this
+ is critical is when you are using shared data sections.
+ If you are using shared data sections for statically
+ allocated data, you will need to be careful to initialize it
+ only once. Check your code carefully.
+
+ Certain one-time initializations may now need to be done for
+ each process that attaches. You may also not need code from
+ your original LibMain because the operating system may now
+ be doing it for you.
+ */
+ /*
+ * 16 bit code calls UnlockData()
+ * which is mapped to UnlockSegment in windows.h
+ * in 32 bit world UnlockData is not defined anywhere
+ * UnlockSegment is mapped to GlobalUnfix in winbase.h
+ * and the docs for both UnlockSegment and GlobalUnfix say
+ * ".. function is oboslete. Segments have no meaning
+ * in the 32-bit environment". So we do nothing here.
+ */
+
+ if( errno = WSAStartup(0x0101, &wsadata ) != 0 )
+ return FALSE;
+
+ break;
+
+ case DLL_THREAD_ATTACH:
+ /* Called each time a thread is created in a process that has
+ already loaded (attached to) this DLL. Does not get called
+ for each thread that exists in the process before it loaded
+ the DLL.
+
+ Do thread-specific initialization here.
+ */
+ break;
+
+ case DLL_THREAD_DETACH:
+ /* Same as above, but called when a thread in the process
+ exits.
+
+ Do thread-specific cleanup here.
+ */
+ break;
+
+ case DLL_PROCESS_DETACH:
+ /* Code from _WEP inserted here. This code may (like the
+ LibMain) not be necessary. Check to make certain that the
+ operating system is not doing it for you.
+ */
+ WSACleanup();
+
+ break;
+ }
+ /* The return value is only used for DLL_PROCESS_ATTACH; all other
+ conditions are ignored. */
+ return TRUE; // successful DLL_PROCESS_ATTACH
+}
+#else
+int CALLBACK
+LibMain( HINSTANCE hinst, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine )
+{
+ /*UnlockData( 0 );*/
+ return( 1 );
+}
+#endif
+
+#ifdef LDAP_DEBUG
+#ifndef _WIN32
+#include <stdarg.h>
+#include <stdio.h>
+
+void LDAPDebug( int level, char* fmt, ... )
+{
+ static char debugBuf[1024];
+
+ if (module_ldap_debug && (*module_ldap_debug & level))
+ {
+ va_list ap;
+ va_start (ap, fmt);
+ _snprintf (debugBuf, sizeof(debugBuf), fmt, ap);
+ va_end (ap);
+
+ OutputDebugString (debugBuf);
+ }
+}
+#endif
+#endif
+
+#ifndef _WIN32
+
+/* The 16-bit version of the RTL does not implement perror() */
+
+#include <stdio.h>
+
+void perror( const char *msg )
+{
+ char buf[128];
+ wsprintf( buf, "%s: error %d\n", msg, WSAGetLastError()) ;
+ OutputDebugString( buf );
+}
+
+#endif
diff --git a/ldap/servers/plugins/syntaxes/dn.c b/ldap/servers/plugins/syntaxes/dn.c
new file mode 100644
index 00000000..e6a90df0
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/dn.c
@@ -0,0 +1,98 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/* dn.c - dn syntax routines */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "syntax.h"
+
+static int dn_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
+ Slapi_Value **bvals, int ftype, Slapi_Value **retVal );
+static int dn_filter_sub( Slapi_PBlock *pb, char *initial, char **any,
+ char *final, Slapi_Value **bvals );
+static int dn_values2keys( Slapi_PBlock *pb, Slapi_Value **vals,
+ Slapi_Value ***ivals, int ftype );
+static int dn_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *val,
+ Slapi_Value ***ivals, int ftype );
+static int dn_assertion2keys_sub( Slapi_PBlock *pb, char *initial, char **any,
+ char *final, Slapi_Value ***ivals );
+
+/* the first name is the official one from RFC 2252 */
+static char *names[] = { "DN", DN_SYNTAX_OID, 0 };
+
+static Slapi_PluginDesc pdesc = { "dn-syntax", PLUGIN_MAGIC_VENDOR_STR,
+ PRODUCTTEXT, "distinguished name attribute syntax plugin" };
+
+int
+dn_init( Slapi_PBlock *pb )
+{
+ int rc;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> dn_init\n", 0, 0, 0 );
+
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_01 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *)&pdesc );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_AVA,
+ (void *) dn_filter_ava );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_SUB,
+ (void *) dn_filter_sub );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALUES2KEYS,
+ (void *) dn_values2keys );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA,
+ (void *) dn_assertion2keys_ava );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_SUB,
+ (void *) dn_assertion2keys_sub );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_NAMES,
+ (void *) names );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_OID,
+ (void *) DN_SYNTAX_OID );
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= dn_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+static int
+dn_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
+ Slapi_Value **bvals, int ftype, Slapi_Value **retVal )
+{
+ return( string_filter_ava( bvfilter, bvals, SYNTAX_CIS | SYNTAX_DN,
+ ftype, retVal ) );
+}
+
+static int
+dn_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
+ Slapi_Value **bvals )
+{
+ return( string_filter_sub( pb, initial, any, final, bvals,
+ SYNTAX_CIS | SYNTAX_DN ) );
+}
+
+static int
+dn_values2keys( Slapi_PBlock *pb, Slapi_Value **vals, Slapi_Value ***ivals,
+ int ftype )
+{
+ return( string_values2keys( pb, vals, ivals, SYNTAX_CIS | SYNTAX_DN,
+ ftype ) );
+}
+
+static int
+dn_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *val,
+ Slapi_Value ***ivals, int ftype )
+{
+ return( string_assertion2keys_ava( pb, val, ivals,
+ SYNTAX_CIS | SYNTAX_DN, ftype ) );
+}
+
+static int
+dn_assertion2keys_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
+ Slapi_Value ***ivals )
+{
+ return( string_assertion2keys_sub( pb, initial, any, final, ivals,
+ SYNTAX_CIS | SYNTAX_DN ) );
+}
diff --git a/ldap/servers/plugins/syntaxes/int.c b/ldap/servers/plugins/syntaxes/int.c
new file mode 100644
index 00000000..f81167f2
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/int.c
@@ -0,0 +1,188 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/* int.c - integer syntax routines */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "syntax.h"
+
+static int int_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
+ Slapi_Value **bvals, int ftype, Slapi_Value **retVal );
+static int int_values2keys( Slapi_PBlock *pb, Slapi_Value **val,
+ Slapi_Value ***ivals );
+static int int_assertion2keys( Slapi_PBlock *pb, Slapi_Value *val,
+ Slapi_Value ***ivals, int ftype );
+static int int_compare(struct berval *v1, struct berval *v2);
+static long int_to_canonical( long num );
+
+/* the first name is the official one from RFC 2252 */
+static char *names[] = { "INTEGER", "int", INTEGER_SYNTAX_OID, 0 };
+
+static Slapi_PluginDesc pdesc = { "int-syntax", PLUGIN_MAGIC_VENDOR_STR,
+ PRODUCTTEXT, "integer attribute syntax plugin" };
+
+int
+int_init( Slapi_PBlock *pb )
+{
+ int rc, flags;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> int_init\n", 0, 0, 0 );
+
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_01 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *)&pdesc );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_AVA,
+ (void *) int_filter_ava );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALUES2KEYS,
+ (void *) int_values2keys );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA,
+ (void *) int_assertion2keys );
+ flags = SLAPI_PLUGIN_SYNTAX_FLAG_ORDERING;
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FLAGS,
+ (void *) &flags );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_NAMES,
+ (void *) names );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_OID,
+ (void *) INTEGER_SYNTAX_OID );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_COMPARE,
+ (void *) int_compare );
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= int_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+static int
+int_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
+ Slapi_Value **bvals, int ftype, Slapi_Value **retVal )
+{
+ int i, rc;
+ long flong, elong;
+
+ if ( ftype == LDAP_FILTER_APPROX ) {
+ return( LDAP_PROTOCOL_ERROR );
+ }
+ if(retVal) {
+ *retVal=NULL;
+ }
+ flong = atol( bvfilter->bv_val );
+ for ( i = 0; bvals[i] != NULL; i++ ) {
+ elong = atol ( slapi_value_get_string(bvals[i]) );
+ rc = elong - flong;
+ switch ( ftype ) {
+ case LDAP_FILTER_GE:
+ if ( rc >= 0 ) {
+ if(retVal) {
+ *retVal = bvals[i];
+ }
+ return( 0 );
+ }
+ break;
+ case LDAP_FILTER_LE:
+ if ( rc <= 0 ) {
+ if(retVal) {
+ *retVal = bvals[i];
+ }
+ return( 0 );
+ }
+ break;
+ case LDAP_FILTER_EQUALITY:
+ if ( rc == 0 ) {
+ if(retVal) {
+ *retVal = bvals[i];
+ }
+ return( 0 );
+ }
+ break;
+ }
+ }
+
+ return( -1 );
+}
+
+static int
+int_values2keys( Slapi_PBlock *pb, Slapi_Value **vals, Slapi_Value ***ivals )
+{
+ long num;
+ int i;
+
+ for ( i = 0; vals[i] != NULL; i++ ) {
+ /* NULL */
+ }
+
+ *ivals = (Slapi_Value **) slapi_ch_malloc(( i + 1 ) * sizeof(Slapi_Value *) );
+
+ for ( i = 0; vals[i] != NULL; i++ )
+ {
+ num = atol( slapi_value_get_string(vals[i]) );
+ num = int_to_canonical( num );
+ (*ivals)[i] = slapi_value_new();
+ slapi_value_set((*ivals)[i],&num,sizeof(long));
+ }
+ (*ivals)[i] = NULL;
+
+ return( 0 );
+}
+
+static int
+int_assertion2keys( Slapi_PBlock *pb, Slapi_Value *val, Slapi_Value ***ivals, int ftype )
+{
+ long num;
+ size_t len;
+ unsigned char *b;
+ Slapi_Value *tmpval=NULL;
+
+ num = atol( slapi_value_get_string(val) );
+ num = int_to_canonical( num );
+ /* similar to string.c to optimize equality path: avoid malloc/free */
+ if(ftype == LDAP_FILTER_EQUALITY_FAST) {
+ len=sizeof(long);
+ tmpval=(*ivals)[0];
+ if ( len > tmpval->bv.bv_len) {
+ tmpval->bv.bv_val=(char *)slapi_ch_malloc(len);
+ }
+ tmpval->bv.bv_len=len;
+ b = (unsigned char *)&num;
+ memcpy(tmpval->bv.bv_val,b,len);
+ } else {
+ *ivals = (Slapi_Value **) slapi_ch_malloc( 2 * sizeof(Slapi_Value *) );
+ (*ivals)[0] = (Slapi_Value *) slapi_ch_malloc( sizeof(Slapi_Value) );
+ /* XXXSD initialize memory */
+ memset((*ivals)[0],0,sizeof(Slapi_Value));
+ slapi_value_set((*ivals)[0],&num,sizeof(long));
+ (*ivals)[1] = NULL;
+ }
+ return( 0 );
+}
+
+static int int_compare(
+ struct berval *v1,
+ struct berval *v2
+)
+{
+ long value1 = atol(v1->bv_val);
+ long value2 = atol(v2->bv_val);
+
+ if (value1 == value2) {
+ return 0;
+ }
+ return ( ((value1 - value2) > 0) ? 1 : -1);
+}
+
+static long
+int_to_canonical( long num )
+{
+ long ret = 0L;
+ unsigned char *b = (unsigned char *)&ret;
+
+ b[0] = (unsigned char)(num >> 24);
+ b[1] = (unsigned char)(num >> 16);
+ b[2] = (unsigned char)(num >> 8);
+ b[3] = (unsigned char)num;
+
+ return ret;
+}
diff --git a/ldap/servers/plugins/syntaxes/libsyntax.def b/ldap/servers/plugins/syntaxes/libsyntax.def
new file mode 100644
index 00000000..30cb6b40
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/libsyntax.def
@@ -0,0 +1,24 @@
+; BEGIN COPYRIGHT BLOCK
+; Copyright 2001 Sun Microsystems, Inc.
+; Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+; All rights reserved.
+; END COPYRIGHT BLOCK
+;
+DESCRIPTION 'Directory Server 7 syntaxes Plugin'
+EXPORTS
+ cis_init @2
+ ces_init @3
+ tel_init @4
+ dn_init @5
+ bin_init @6
+ int_init @7
+ plugin_init_debug_level @8
+ octetstring_init @9
+ boolean_init @10
+ time_init @11
+ uri_init @12
+ country_init @13
+ postal_init @14
+ jpeg_init @15
+ oid_init @16
+ sicis_init @17
diff --git a/ldap/servers/plugins/syntaxes/phonetic.c b/ldap/servers/plugins/syntaxes/phonetic.c
new file mode 100644
index 00000000..1c1c8ba5
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/phonetic.c
@@ -0,0 +1,461 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/* phonetic.c - routines to do phonetic matching */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include "syntax.h"
+#include "portable.h"
+
+#if !defined(METAPHONE) && !defined(SOUNDEX)
+#define METAPHONE
+#endif
+
+#define iswordbreak(s) \
+(isascii(*(s)) \
+? (isspace(*(s)) || \
+ ispunct(*(s)) || \
+ isdigit(*(s)) || \
+ *(s) == '\0') \
+: utf8iswordbreak(s))
+
+static int
+utf8iswordbreak( const char* s )
+{
+ switch( LDAP_UTF8GETCC( s )) {
+ case 0x00A0: /* non-breaking space */
+ case 0x3000: /* ideographic space */
+ case 0xFEFF: /* zero-width non-breaking space */
+ return 1;
+ default: break;
+ }
+ return 0;
+}
+
+char *
+first_word( char *s )
+{
+ if ( s == NULL ) {
+ return( NULL );
+ }
+
+ while ( iswordbreak( s ) ) {
+ if ( *s == '\0' ) {
+ return( NULL );
+ } else {
+ LDAP_UTF8INC( s );
+ }
+ }
+
+ return( s );
+}
+
+char *
+next_word( char *s )
+{
+ if ( s == NULL ) {
+ return( NULL );
+ }
+
+ while ( ! iswordbreak( s ) ) {
+ LDAP_UTF8INC( s );
+ }
+
+ while ( iswordbreak( s ) ) {
+ if ( *s == '\0' ) {
+ return( NULL );
+ } else {
+ LDAP_UTF8INC( s );
+ }
+ }
+
+ return( s );
+}
+
+char *
+word_dup( char *w )
+{
+ char *s, *ret;
+ char save;
+
+ for ( s = w; !iswordbreak( s ); LDAP_UTF8INC( s ))
+ ; /* NULL */
+ save = *s;
+ *s = '\0';
+ ret = slapi_ch_strdup( w );
+ *s = save;
+
+ return( ret );
+}
+
+#ifndef MAXPHONEMELEN
+#define MAXPHONEMELEN 4
+#endif
+
+#if defined(SOUNDEX)
+
+/* lifted from isode-8.0 */
+char *
+phonetic( char *s )
+{
+ char code, adjacent, ch;
+ char *p;
+ char **c;
+ int i, cmax;
+ char phoneme[MAXPHONEMELEN + 1];
+
+ p = s;
+ if ( p == NULL || *p == '\0' ) {
+ return( NULL );
+ }
+
+ adjacent = '0';
+ phoneme[0] = TOUPPER(*p);
+
+ phoneme[1] = '\0';
+ for ( i = 0; i < 99 && (! iswordbreak(p)); LDAP_UTF8INC( p )) {
+ ch = TOUPPER (*p);
+
+ code = '0';
+
+ switch (ch) {
+ case 'B':
+ case 'F':
+ case 'P':
+ case 'V':
+ code = (adjacent != '1') ? '1' : '0';
+ break;
+ case 'S':
+ case 'C':
+ case 'G':
+ case 'J':
+ case 'K':
+ case 'Q':
+ case 'X':
+ case 'Z':
+ code = (adjacent != '2') ? '2' : '0';
+ break;
+ case 'D':
+ case 'T':
+ code = (adjacent != '3') ? '3' : '0';
+ break;
+ case 'L':
+ code = (adjacent != '4') ? '4' : '0';
+ break;
+ case 'M':
+ case 'N':
+ code = (adjacent != '5') ? '5' : '0';
+ break;
+ case 'R':
+ code = (adjacent != '6') ? '6' : '0';
+ break;
+ default:
+ adjacent = '0';
+ }
+
+ if ( i == 0 ) {
+ adjacent = code;
+ i++;
+ } else if ( code != '0' ) {
+ if ( i == MAXPHONEMELEN )
+ break;
+ adjacent = phoneme[i] = code;
+ i++;
+ }
+ }
+
+ if ( i > 0 )
+ phoneme[i] = '\0';
+
+ return( slapi_ch_strdup( phoneme ) );
+}
+
+#else
+#if defined(METAPHONE)
+
+/*
+ * Metaphone copied from C Gazette, June/July 1991, pp 56-57,
+ * author Gary A. Parker, with changes by Bernard Tiffany of the
+ * University of Michigan, and more changes by Tim Howes of the
+ * University of Michigan.
+ */
+
+/* Character coding array */
+static char vsvfn[26] = {
+ 1, 16, 4, 16, 9, 2, 4, 16, 9, 2, 0, 2, 2,
+ /* A B C D E F G H I J K L M */
+ 2, 1, 4, 0, 2, 4, 4, 1, 0, 0, 0, 8, 0};
+ /* N O P Q R S T U V W X Y Z */
+
+/* Macros to access character coding array */
+#define vowel(x) ((x) != '\0' && vsvfn[(x) - 'A'] & 1) /* AEIOU */
+#define same(x) ((x) != '\0' && vsvfn[(x) - 'A'] & 2) /* FJLMNR */
+#define varson(x) ((x) != '\0' && vsvfn[(x) - 'A'] & 4) /* CGPST */
+#define frontv(x) ((x) != '\0' && vsvfn[(x) - 'A'] & 8) /* EIY */
+#define noghf(x) ((x) != '\0' && vsvfn[(x) - 'A'] & 16) /* BDH */
+
+char *
+phonetic( char *Word )
+{
+ char *n, *n_start, *n_end; /* pointers to string */
+ char *metaph_end; /* pointers to metaph */
+ char ntrans[42]; /* word with uppercase letters */
+ int KSflag; /* state flag for X -> KS */
+ char buf[MAXPHONEMELEN + 2];
+ char *Metaph;
+
+ /*
+ * Copy Word to internal buffer, dropping non-alphabetic characters
+ * and converting to upper case
+ */
+ n = ntrans + 4; n_end = ntrans + 35;
+ while (!iswordbreak( Word ) && n < n_end) {
+ if (isascii(*Word)) {
+ if (isalpha(*Word)) {
+ *n++ = TOUPPER(*Word);
+ }
+ ++Word;
+ } else {
+ auto const size_t len = LDAP_UTF8COPY(n, Word);
+ n += len; Word += len;
+ }
+ }
+ Metaph = buf;
+ *Metaph = '\0';
+ if (n == ntrans + 4) {
+ return( slapi_ch_strdup( buf ) ); /* Return if null */
+ }
+ n_end = n; /* Set n_end to end of string */
+
+ /* ntrans[0] will always be == 0 */
+ ntrans[0] = '\0';
+ ntrans[1] = '\0';
+ ntrans[2] = '\0';
+ ntrans[3] = '\0';
+ *n++ = 0;
+ *n++ = 0;
+ *n++ = 0;
+ *n = 0; /* Pad with nulls */
+ n = ntrans + 4; /* Assign pointer to start */
+
+ /* Check for PN, KN, GN, AE, WR, WH, and X at start */
+ switch (*n) {
+ case 'P':
+ case 'K':
+ case 'G':
+ /* 'PN', 'KN', 'GN' becomes 'N' */
+ if (*(n + 1) == 'N')
+ *n++ = 0;
+ break;
+ case 'A':
+ /* 'AE' becomes 'E' */
+ if (*(n + 1) == 'E')
+ *n++ = 0;
+ break;
+ case 'W':
+ /* 'WR' becomes 'R', and 'WH' to 'H' */
+ if (*(n + 1) == 'R')
+ *n++ = 0;
+ else if (*(n + 1) == 'H') {
+ *(n + 1) = *n;
+ *n++ = 0;
+ }
+ break;
+ case 'X':
+ /* 'X' becomes 'S' */
+ *n = 'S';
+ break;
+ }
+
+ /*
+ * Now, loop step through string, stopping at end of string or when
+ * the computed 'metaph' is MAXPHONEMELEN characters long
+ */
+
+ KSflag = 0; /* state flag for KS translation */
+ for (metaph_end = Metaph + MAXPHONEMELEN, n_start = n;
+ n <= n_end && Metaph < metaph_end; n++) {
+ if (KSflag) {
+ KSflag = 0;
+ *Metaph++ = 'S';
+ } else if (!isascii(*n)) {
+ *Metaph++ = *n;
+ } else {
+ /* Drop duplicates except for CC */
+ if (*(n - 1) == *n && *n != 'C')
+ continue;
+ /* Check for F J L M N R or first letter vowel */
+ if (same(*n) || (n == n_start && vowel(*n))) {
+ *Metaph++ = *n;
+ } else {
+ switch (*n) {
+ case 'B':
+
+ /*
+ * B unless in -MB
+ */
+ if (n < (n_end - 1) && *(n - 1) != 'M') {
+ *Metaph++ = *n;
+ }
+ break;
+ case 'C':
+
+ /*
+ * X if in -CIA-, -CH- else S if in
+ * -CI-, -CE-, -CY- else dropped if
+ * in -SCI-, -SCE-, -SCY- else K
+ */
+ if (*(n - 1) != 'S' || !frontv(*(n + 1))) {
+ if (*(n + 1) == 'I' && *(n + 2) == 'A') {
+ *Metaph++ = 'X';
+ } else if (frontv(*(n + 1))) {
+ *Metaph++ = 'S';
+ } else if (*(n + 1) == 'H') {
+ *Metaph++ = ((n == n_start && !vowel(*(n + 2)))
+ || *(n - 1) == 'S')
+ ? (char) 'K' : (char) 'X';
+ } else {
+ *Metaph++ = 'K';
+ }
+ }
+ break;
+ case 'D':
+
+ /*
+ * J if in DGE or DGI or DGY else T
+ */
+ *Metaph++ = (*(n + 1) == 'G' && frontv(*(n + 2)))
+ ? (char) 'J' : (char) 'T';
+ break;
+ case 'G':
+
+ /*
+ * F if in -GH and not B--GH, D--GH,
+ * -H--GH, -H---GH else dropped if
+ * -GNED, -GN, -DGE-, -DGI-, -DGY-
+ * else J if in -GE-, -GI-, -GY- and
+ * not GG else K
+ */
+ if ((*(n + 1) != 'J' || vowel(*(n + 2))) &&
+ (*(n + 1) != 'N' || ((n + 1) < n_end &&
+ (*(n + 2) != 'E' || *(n + 3) != 'D'))) &&
+ (*(n - 1) != 'D' || !frontv(*(n + 1))))
+ *Metaph++ = (frontv(*(n + 1)) &&
+ *(n + 2) != 'G') ? (char) 'G' : (char) 'K';
+ else if (*(n + 1) == 'H' && !noghf(*(n - 3)) &&
+ *(n - 4) != 'H')
+ *Metaph++ = 'F';
+ break;
+ case 'H':
+
+ /*
+ * H if before a vowel and not after
+ * C, G, P, S, T else dropped
+ */
+ if (!varson(*(n - 1)) && (!vowel(*(n - 1)) ||
+ vowel(*(n + 1))))
+ *Metaph++ = 'H';
+ break;
+ case 'K':
+
+ /*
+ * dropped if after C else K
+ */
+ if (*(n - 1) != 'C')
+ *Metaph++ = 'K';
+ break;
+ case 'P':
+
+ /*
+ * F if before H, else P
+ */
+ *Metaph++ = *(n + 1) == 'H' ?
+ (char) 'F' : (char) 'P';
+ break;
+ case 'Q':
+
+ /*
+ * K
+ */
+ *Metaph++ = 'K';
+ break;
+ case 'S':
+
+ /*
+ * X in -SH-, -SIO- or -SIA- else S
+ */
+ *Metaph++ = (*(n + 1) == 'H' ||
+ (*(n + 1) == 'I' && (*(n + 2) == 'O' ||
+ *(n + 2) == 'A')))
+ ? (char) 'X' : (char) 'S';
+ break;
+ case 'T':
+
+ /*
+ * X in -TIA- or -TIO- else 0 (zero)
+ * before H else dropped if in -TCH-
+ * else T
+ */
+ if (*(n + 1) == 'I' && (*(n + 2) == 'O' ||
+ *(n + 2) == 'A'))
+ *Metaph++ = 'X';
+ else if (*(n + 1) == 'H')
+ *Metaph++ = '0';
+ else if (*(n + 1) != 'C' || *(n + 2) != 'H')
+ *Metaph++ = 'T';
+ break;
+ case 'V':
+
+ /*
+ * F
+ */
+ *Metaph++ = 'F';
+ break;
+ case 'W':
+
+ /*
+ * W after a vowel, else dropped
+ */
+ case 'Y':
+
+ /*
+ * Y unless followed by a vowel
+ */
+ if (vowel(*(n + 1)))
+ *Metaph++ = *n;
+ break;
+ case 'X':
+
+ /*
+ * KS
+ */
+ if (n == n_start)
+ *Metaph++ = 'S';
+ else {
+ *Metaph++ = 'K'; /* Insert K, then S */
+ KSflag = 1;
+ }
+ break;
+ case 'Z':
+
+ /*
+ * S
+ */
+ *Metaph++ = 'S';
+ break;
+ }
+ }
+ }
+ }
+
+ *Metaph = 0; /* Null terminate */
+ return( slapi_ch_strdup( buf ) );
+}
+
+#endif /* METAPHONE */
+#endif /* !SOUNDEX */
diff --git a/ldap/servers/plugins/syntaxes/sicis.c b/ldap/servers/plugins/syntaxes/sicis.c
new file mode 100644
index 00000000..4bd6623d
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/sicis.c
@@ -0,0 +1,139 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2002 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+/*
+ * sicis.c - space insensitive string syntax routines.
+ * these strings are also case insensitive.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "syntax.h"
+
+static int sicis_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
+ Slapi_Value **bvals, int ftype, Slapi_Value **retVal );
+static int sicis_filter_sub( Slapi_PBlock *pb, char *initial, char **any,
+ char *final, Slapi_Value **bvals );
+static int sicis_values2keys( Slapi_PBlock *pb, Slapi_Value **val,
+ Slapi_Value ***ivals, int ftype );
+static int sicis_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *val,
+ Slapi_Value ***ivals, int ftype );
+static int sicis_assertion2keys_sub( Slapi_PBlock *pb, char *initial,
+ char **any, char *final, Slapi_Value ***ivals );
+static int sicis_compare(struct berval *v1, struct berval *v2);
+
+/* the first name is the official one from RFC 2252 */
+static char *names[] = { "SpaceInsensitiveString",
+ SPACE_INSENSITIVE_STRING_SYNTAX_OID, 0 };
+
+static Slapi_PluginDesc pdesc = { "spaceinsensitivestring-syntax",
+ PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT,
+ "space insensitive string attribute syntax plugin" };
+
+int
+sicis_init( Slapi_PBlock *pb )
+{
+ int rc, flags;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> sicis_init\n", 0, 0, 0 );
+
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_01 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *)&pdesc );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_AVA,
+ (void *) sicis_filter_ava );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_SUB,
+ (void *) sicis_filter_sub );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALUES2KEYS,
+ (void *) sicis_values2keys );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA,
+ (void *) sicis_assertion2keys_ava );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_SUB,
+ (void *) sicis_assertion2keys_sub );
+ flags = SLAPI_PLUGIN_SYNTAX_FLAG_ORDERING;
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FLAGS,
+ (void *) &flags );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_NAMES,
+ (void *) names );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_OID,
+ (void *) SPACE_INSENSITIVE_STRING_SYNTAX_OID );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_COMPARE,
+ (void *) sicis_compare );
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= sicis_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+static int
+sicis_filter_ava(
+ Slapi_PBlock *pb,
+ struct berval *bvfilter,
+ Slapi_Value **bvals,
+ int ftype,
+ Slapi_Value **retVal
+)
+{
+ return( string_filter_ava( bvfilter, bvals, SYNTAX_SI | SYNTAX_CIS,
+ ftype, retVal ) );
+}
+
+
+static int
+sicis_filter_sub(
+ Slapi_PBlock *pb,
+ char *initial,
+ char **any,
+ char *final,
+ Slapi_Value **bvals
+)
+{
+ return( string_filter_sub( pb, initial, any, final, bvals, SYNTAX_SI | SYNTAX_CIS ) );
+}
+
+static int
+sicis_values2keys(
+ Slapi_PBlock *pb,
+ Slapi_Value **vals,
+ Slapi_Value ***ivals,
+ int ftype
+)
+{
+ return( string_values2keys( pb, vals, ivals, SYNTAX_SI | SYNTAX_CIS,
+ ftype ) );
+}
+
+static int
+sicis_assertion2keys_ava(
+ Slapi_PBlock *pb,
+ Slapi_Value *val,
+ Slapi_Value ***ivals,
+ int ftype
+)
+{
+ return(string_assertion2keys_ava( pb, val, ivals,
+ SYNTAX_SI | SYNTAX_CIS, ftype ));
+}
+
+static int
+sicis_assertion2keys_sub(
+ Slapi_PBlock *pb,
+ char *initial,
+ char **any,
+ char *final,
+ Slapi_Value ***ivals
+)
+{
+ return( string_assertion2keys_sub( pb, initial, any, final, ivals,
+ SYNTAX_SI | SYNTAX_CIS ) );
+}
+
+static int sicis_compare(
+ struct berval *v1,
+ struct berval *v2
+)
+{
+ return value_cmp(v1, v2, SYNTAX_SI|SYNTAX_CIS, 3 /* Normalise both values */);
+}
diff --git a/ldap/servers/plugins/syntaxes/string.c b/ldap/servers/plugins/syntaxes/string.c
new file mode 100644
index 00000000..d06a15f5
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/string.c
@@ -0,0 +1,612 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/* string.c - common string syntax routines */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "syntax.h"
+#if defined(IRIX)
+#include <unistd.h>
+#endif
+#if defined( MACOS ) || defined( DOS ) || defined( _WIN32 ) || defined( NEED_BSDREGEX )
+#include "regex.h"
+#endif
+
+static int string_filter_approx( struct berval *bvfilter,
+ Slapi_Value **bvals, Slapi_Value **retVal );
+static void substring_comp_keys( Slapi_Value ***ivals, int *nsubs, char *str,
+ int prepost, int syntax );
+
+int
+string_filter_ava( struct berval *bvfilter, Slapi_Value **bvals, int syntax,
+ int ftype, Slapi_Value **retVal )
+{
+ int i, rc;
+ struct berval bvfilter_norm;
+
+ if(retVal) {
+ *retVal = NULL;
+ }
+ if ( ftype == LDAP_FILTER_APPROX ) {
+ return( string_filter_approx( bvfilter, bvals, retVal ) );
+ }
+
+ bvfilter_norm.bv_val = slapi_ch_malloc( bvfilter->bv_len + 1 );
+ SAFEMEMCPY( bvfilter_norm.bv_val, bvfilter->bv_val, bvfilter->bv_len );
+ bvfilter_norm.bv_val[bvfilter->bv_len] = '\0';
+ value_normalize( bvfilter_norm.bv_val, syntax, 1 /* trim leading blanks */ );
+
+ for ( i = 0; bvals[i] != NULL; i++ ) {
+ rc = value_cmp( (struct berval*)slapi_value_get_berval(bvals[i]), &bvfilter_norm, syntax, 1/* Normalise the first value only */ );
+ switch ( ftype ) {
+ case LDAP_FILTER_GE:
+ if ( rc >= 0 ) {
+ if(retVal) {
+ *retVal = bvals[i];
+ }
+ slapi_ch_free ((void**)&bvfilter_norm.bv_val);
+ return( 0 );
+ }
+ break;
+ case LDAP_FILTER_LE:
+ if ( rc <= 0 ) {
+ if(retVal) {
+ *retVal = bvals[i];
+ }
+ slapi_ch_free ((void**)&bvfilter_norm.bv_val);
+ return( 0 );
+ }
+ break;
+ case LDAP_FILTER_EQUALITY:
+ if ( rc == 0 ) {
+ if(retVal) {
+ *retVal = bvals[i];
+ }
+ slapi_ch_free ((void**)&bvfilter_norm.bv_val);
+ return( 0 );
+ }
+ break;
+ }
+ }
+
+ slapi_ch_free ((void**)&bvfilter_norm.bv_val);
+ return( -1 );
+}
+
+static int
+string_filter_approx( struct berval *bvfilter, Slapi_Value **bvals,
+ Slapi_Value **retVal)
+{
+ int i, rc;
+ int ava_wordcount;
+ char *w1, *w2, *c1, *c2;
+
+ /*
+ * try to match words in each filter value in order
+ * in the attribute value.
+ * XXX should do this once for the filter and save it XXX
+ */
+ rc = -1;
+ if(retVal) {
+ *retVal = NULL;
+ }
+ for ( i = 0; bvals[i] != NULL; i++ ) {
+ w2 = (char*)slapi_value_get_string(bvals[i]); /* JCM cast */
+ ava_wordcount = 0;
+ /* for each word in the filter value */
+ for ( w1 = first_word( bvfilter->bv_val ); w1 != NULL;
+ w1 = next_word( w1 ) ) {
+ ++ava_wordcount;
+ if ( (c1 = phonetic( w1 )) == NULL ) {
+ break;
+ }
+
+ /*
+ * for each word in the attribute value from
+ * where we left off...
+ */
+ for ( w2 = first_word( w2 ); w2 != NULL;
+ w2 = next_word( w2 ) ) {
+ c2 = phonetic( w2 );
+ rc = strcmp( c1, c2 );
+ slapi_ch_free((void**)&c2 );
+ if ( rc == 0 ) {
+ if(retVal) {
+ *retVal = bvals[i];
+ }
+ break;
+ }
+ }
+ slapi_ch_free((void**)&c1 );
+
+ /*
+ * if we stopped because we ran out of words
+ * before making a match, go on to the next
+ * value. otherwise try to keep matching
+ * words in this value from where we left off.
+ */
+ if ( w2 == NULL ) {
+ break;
+ } else {
+ w2 = next_word( w2 );
+ }
+ }
+ /*
+ * if we stopped because we ran out of words and
+ * we found at leasy one word, we have a match.
+ */
+ if ( w1 == NULL && ava_wordcount > 0 ) {
+ rc = 0;
+ break;
+ }
+ }
+ LDAPDebug( LDAP_DEBUG_TRACE, "<= string_filter_approx %d\n",
+ rc, 0, 0 );
+
+ return( rc );
+}
+
+int
+string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
+ Slapi_Value **bvals, int syntax )
+{
+ int i, j, rc;
+ char *p, *end, *realval, *tmpbuf;
+ size_t tmpbufsize;
+ char pat[BUFSIZ];
+ char buf[BUFSIZ];
+ char ebuf[BUFSIZ];
+
+ LDAPDebug( LDAP_DEBUG_FILTER, "=> string_filter_sub\n",
+ 0, 0, 0 );
+
+ /*
+ * construct a regular expression corresponding to the
+ * filter and let regex do the work for each value
+ * XXX should do this once and save it somewhere XXX
+ */
+ pat[0] = '\0';
+ p = pat;
+ end = pat + sizeof(pat) - 2; /* leave room for null */
+ if ( initial != NULL ) {
+ value_normalize( initial, syntax, 1 /* trim leading blanks */ );
+ strcpy( p, "^" );
+ p = strchr( p, '\0' );
+ /* 2 * in case every char is special */
+ if ( p + 2 * strlen( initial ) > end ) {
+ LDAPDebug( LDAP_DEBUG_ANY, "not enough pattern space\n",
+ 0, 0, 0 );
+ return( -1 );
+ }
+ filter_strcpy_special( p, initial );
+ p = strchr( p, '\0' );
+ }
+ if ( any != NULL ) {
+ for ( i = 0; any[i] != NULL; i++ ) {
+ value_normalize( any[i], syntax, 0 /* DO NOT trim leading blanks */ );
+ /* ".*" + value */
+ if ( p + 2 * strlen( any[i] ) + 2 > end ) {
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "not enough pattern space\n", 0, 0, 0 );
+ return( -1 );
+ }
+ strcpy( p, ".*" );
+ p = strchr( p, '\0' );
+ filter_strcpy_special( p, any[i] );
+ p = strchr( p, '\0' );
+ }
+ }
+ if ( final != NULL ) {
+ value_normalize( final, syntax, 0 /* DO NOT trim leading blanks */ );
+ /* ".*" + value */
+ if ( p + 2 * strlen( final ) + 2 > end ) {
+ LDAPDebug( LDAP_DEBUG_ANY, "not enough pattern space\n",
+ 0, 0, 0 );
+ return( -1 );
+ }
+ strcpy( p, ".*" );
+ p = strchr( p, '\0' );
+ filter_strcpy_special( p, final );
+ p = strchr( p, '\0' );
+ strcpy( p, "$" );
+ }
+
+ /* compile the regex */
+ slapd_re_lock();
+ if ( (p = slapd_re_comp( pat )) != 0 ) {
+ LDAPDebug( LDAP_DEBUG_ANY, "re_comp (%s) failed (%s)\n",
+ pat, p, 0 );
+ slapd_re_unlock();
+ return( -1 );
+ } else {
+ LDAPDebug( LDAP_DEBUG_TRACE, "re_comp (%s)\n",
+ escape_string( pat, ebuf ), 0, 0 );
+ }
+
+ /*
+ * test the regex against each value
+ */
+ rc = -1;
+ tmpbuf = NULL;
+ tmpbufsize = 0;
+ for ( j = 0; bvals[j] != NULL; j++ ) {
+ int tmprc;
+ size_t len;
+ const struct berval *bvp = slapi_value_get_berval(bvals[j]);
+
+ len = bvp->bv_len;
+ if ( len < sizeof(buf) ) {
+ strcpy( buf, bvp->bv_val );
+ realval = buf;
+ } else if ( len < tmpbufsize ) {
+ strcpy( buf, bvp->bv_val );
+ realval = tmpbuf;
+ } else {
+ tmpbuf = (char *) slapi_ch_realloc( tmpbuf, len + 1 );
+ strcpy( tmpbuf, bvp->bv_val );
+ realval = tmpbuf;
+ }
+ value_normalize( realval, syntax, 1 /* trim leading blanks */ );
+
+ tmprc = slapd_re_exec( realval );
+
+ LDAPDebug( LDAP_DEBUG_TRACE, "re_exec (%s) %i\n",
+ escape_string( realval, ebuf ), tmprc, 0 );
+ if ( tmprc != 0 ) {
+ rc = 0;
+ break;
+ }
+ }
+ slapd_re_unlock();
+ if ( tmpbuf != NULL ) {
+ slapi_ch_free((void**)&tmpbuf );
+ }
+
+ LDAPDebug( LDAP_DEBUG_FILTER, "<= string_filter_sub %d\n",
+ rc, 0, 0 );
+ return( rc );
+}
+
+int
+string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
+ Slapi_Value ***ivals, int syntax, int ftype )
+{
+ int nsubs, numbvals, i, n, j;
+ Slapi_Value **nbvals;
+ char *w, *c, *p;
+ char buf[SUBLEN+1];
+
+ switch ( ftype ) {
+ case LDAP_FILTER_EQUALITY:
+ /* allocate a new array for the normalized values */
+ for ( numbvals = 0; bvals[numbvals] != NULL; numbvals++ ) {
+ /* NULL */
+ }
+ nbvals = (Slapi_Value **) slapi_ch_malloc( (numbvals+1) * sizeof(Slapi_Value *));
+
+ for ( i = 0; i < numbvals; i++ )
+ {
+ c = slapi_ch_strdup(slapi_value_get_string(bvals[i]));
+ value_normalize( c, syntax, 1 /* trim leading blanks */ );
+ nbvals[i] = slapi_value_new_string_passin(c);
+ }
+ nbvals[i] = NULL;
+ *ivals = nbvals;
+ break;
+
+ case LDAP_FILTER_APPROX:
+ /* XXX should not do this twice! XXX */
+ /* get an upper bound on the number of ivals */
+ numbvals = 0;
+ for ( i = 0; bvals[i] != NULL; i++ ) {
+ for ( w = first_word( (char*)slapi_value_get_string(bvals[i]) ); w != NULL;
+ w = next_word( w ) ) {
+ numbvals++;
+ }
+ }
+ nbvals = (Slapi_Value **) slapi_ch_malloc( (numbvals + 1) * sizeof(Slapi_Value *) );
+
+ n = 0;
+ for ( i = 0; bvals[i] != NULL; i++ ) {
+ for ( w = first_word( (char*)slapi_value_get_string(bvals[i]) ); w != NULL;
+ w = next_word( w ) ) {
+ if ( (c = phonetic( w )) != NULL ) {
+ nbvals[n] = slapi_value_new_string_passin(c);
+ n++;
+ }
+ }
+ }
+ nbvals[n] = NULL;
+
+ if ( n == 0 ) {
+ slapi_ch_free((void**)ivals );
+ return( 0 );
+ }
+ *ivals = nbvals;
+ break;
+
+ case LDAP_FILTER_SUBSTRINGS:
+ {
+ /* XXX should remove duplicates! XXX */
+ Slapi_Value *bvdup;
+ const struct berval *bvp;
+ nsubs = 0;
+ for ( i = 0; bvals[i] != NULL; i++ ) {
+ /*
+ * Note: this calculation may err on the high side,
+ * because value_normalize(), which is called below
+ * before we actually create the substring keys, may
+ * reduce the length of the value in some cases. For
+ * example, spaces are removed when space insensitive
+ * strings are normalized. But it's okay for nsubs to
+ * be too big. Since the ivals array is NULL terminated,
+ * the only downside is that we allocate more space than
+ * we really need.
+ */
+ nsubs += slapi_value_get_length(bvals[i]) - SUBLEN + 3;
+ }
+ *ivals = (Slapi_Value **) slapi_ch_malloc( (nsubs + 1) * sizeof(Slapi_Value *) );
+
+ buf[SUBLEN] = '\0';
+ n = 0;
+
+ bvdup= slapi_value_new();
+ for ( i = 0; bvals[i] != NULL; i++ )
+ {
+ c = slapi_ch_strdup(slapi_value_get_string(bvals[i]));
+ value_normalize( c, syntax, 1 /* trim leading blanks */ );
+ slapi_value_set_string_passin(bvdup, c);
+
+ bvp = slapi_value_get_berval(bvdup);
+
+ /* leading */
+ if ( bvp->bv_len > SUBLEN - 2 ) {
+ buf[0] = '^';
+ for ( j = 0; j < SUBLEN - 1; j++ ) {
+ buf[j + 1] = bvp->bv_val[j];
+ }
+ (*ivals)[n] = slapi_value_new_string(buf);
+ n++;
+ }
+
+ /* any */
+ for ( p = bvp->bv_val;
+ p < (bvp->bv_val + bvp->bv_len - SUBLEN + 1);
+ p++ ) {
+ for ( j = 0; j < SUBLEN; j++ ) {
+ buf[j] = p[j];
+ }
+ buf[SUBLEN] = '\0';
+ (*ivals)[n] = slapi_value_new_string(buf);
+ n++;
+ }
+
+ /* trailing */
+ if ( bvp->bv_len > SUBLEN - 2 ) {
+ p = bvp->bv_val + bvp->bv_len - SUBLEN + 1;
+ for ( j = 0; j < SUBLEN - 1; j++ ) {
+ buf[j] = p[j];
+ }
+ buf[SUBLEN - 1] = '$';
+ (*ivals)[n] = slapi_value_new_string(buf);
+ n++;
+ }
+ }
+ slapi_value_free(&bvdup);
+ (*ivals)[n] = NULL;
+ }
+ break;
+ }
+
+ return( 0 );
+}
+
+
+/* we've added code to make our equality filter processing faster */
+
+int
+string_assertion2keys_ava(
+ Slapi_PBlock *pb,
+ Slapi_Value *val,
+ Slapi_Value ***ivals,
+ int syntax,
+ int ftype
+)
+{
+ int i, numbvals;
+ size_t len;
+ char *w, *c;
+ Slapi_Value *tmpval=NULL;
+
+ switch ( ftype ) {
+ case LDAP_FILTER_EQUALITY_FAST:
+ /* this code is trying to avoid multiple malloc/frees */
+ len=slapi_value_get_length(val);
+ tmpval=(*ivals)[0];
+ if (len >= tmpval->bv.bv_len) {
+ tmpval->bv.bv_val=(char *)slapi_ch_malloc(len+1);
+ }
+ memcpy(tmpval->bv.bv_val,slapi_value_get_string(val),len);
+ tmpval->bv.bv_val[len]='\0';
+ value_normalize(tmpval->bv.bv_val, syntax, 1 /* trim leading blanks */ );
+ tmpval->bv.bv_len=strlen(tmpval->bv.bv_val);
+ break;
+ case LDAP_FILTER_EQUALITY:
+ (*ivals) = (Slapi_Value **) slapi_ch_malloc( 2 * sizeof(Slapi_Value *) );
+ (*ivals)[0] = slapi_value_dup( val );
+ value_normalize( (*ivals)[0]->bv.bv_val, syntax, 1 /* trim leading blanks */ );
+ (*ivals)[0]->bv.bv_len = strlen( (*ivals)[0]->bv.bv_val );
+ (*ivals)[1] = NULL;
+ break;
+
+ case LDAP_FILTER_APPROX:
+ /* XXX should not do this twice! XXX */
+ /* get an upper bound on the number of ivals */
+ numbvals = 0;
+ for ( w = first_word( (char*)slapi_value_get_string(val) ); w != NULL;
+ w = next_word( w ) ) {
+ numbvals++;
+ }
+ (*ivals) = (Slapi_Value **) slapi_ch_malloc( (numbvals + 1) *
+ sizeof(Slapi_Value *) );
+
+ i = 0;
+ for ( w = first_word( (char*)slapi_value_get_string(val) ); w != NULL;
+ w = next_word( w ) ) {
+ if ( (c = phonetic( w )) != NULL ) {
+ (*ivals)[i] = slapi_value_new_string_passin(c);
+ i++;
+ }
+ }
+ (*ivals)[i] = NULL;
+
+ if ( i == 0 ) {
+ slapi_ch_free((void**)ivals );
+ return( 0 );
+ }
+ break;
+ default:
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "string_assertion2keys_ava: unknown ftype 0x%x\n",
+ ftype, 0, 0 );
+ break;
+ }
+
+ return( 0 );
+}
+
+int
+string_assertion2keys_sub(
+ Slapi_PBlock *pb,
+ char *initial,
+ char **any,
+ char *final,
+ Slapi_Value ***ivals,
+ int syntax
+)
+{
+ int nsubs, i, len;
+
+ *ivals = NULL;
+
+ /*
+ * First figure out how many keys we will return. The answer is based
+ * on the length of each assertion value. Since normalization may
+ * reduce the length (such as when spaces are removed from space
+ * insensitive strings), we call value_normalize() before checking
+ * the length.
+ */
+ nsubs = 0;
+ if ( initial != NULL ) {
+ value_normalize( initial, syntax, 0 /* do not trim leading blanks */ );
+ if ( strlen( initial ) > SUBLEN - 2 ) {
+ nsubs += strlen( initial ) - SUBLEN + 2;
+ } else {
+ initial = NULL; /* save some work later */
+ }
+ }
+ for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
+ value_normalize( any[i], syntax, 0 /* do not trim leading blanks */ );
+ len = strlen( any[i] );
+ if ( len >= SUBLEN ) {
+ nsubs += len - SUBLEN + 1;
+ }
+ }
+ if ( final != NULL ) {
+ value_normalize( final, syntax, 0 /* do not trim leading blanks */ );
+ if ( strlen( final ) > SUBLEN - 2 ) {
+ nsubs += strlen( final ) - SUBLEN + 2;
+ } else {
+ final = NULL; /* save some work later */
+ }
+ }
+ if ( nsubs == 0 ) { /* no keys to return */
+ return( 0 );
+ }
+
+ /*
+ * Next, allocated the ivals array and fill it in with the actual
+ * keys. *ivals is a NULL terminated array of Slapi_Value pointers.
+ */
+
+ *ivals = (Slapi_Value **) slapi_ch_malloc( (nsubs + 1) * sizeof(Slapi_Value *) );
+
+ nsubs = 0;
+ if ( initial != NULL ) {
+ substring_comp_keys( ivals, &nsubs, initial, '^', syntax );
+ }
+ for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
+ if ( strlen( any[i] ) < SUBLEN ) {
+ continue;
+ }
+ substring_comp_keys( ivals, &nsubs, any[i], 0, syntax );
+ }
+ if ( final != NULL ) {
+ substring_comp_keys( ivals, &nsubs, final, '$', syntax );
+ }
+ (*ivals)[nsubs] = NULL;
+
+ return( 0 );
+}
+
+static void
+substring_comp_keys(
+ Slapi_Value ***ivals,
+ int *nsubs,
+ char *str,
+ int prepost,
+ int syntax
+)
+{
+ int i, len;
+ char *p;
+ char buf[SUBLEN + 1];
+
+ LDAPDebug( LDAP_DEBUG_TRACE, "=> substring_comp_keys (%s) %d\n",
+ str, prepost, 0 );
+
+ len = strlen( str );
+
+ /* prepend ^ for initial substring */
+ if ( prepost == '^' )
+ {
+ buf[0] = '^';
+ for ( i = 0; i < SUBLEN - 1; i++ )
+ {
+ buf[i + 1] = str[i];
+ }
+ buf[SUBLEN] = '\0';
+ (*ivals)[*nsubs] = slapi_value_new_string(buf);
+ (*nsubs)++;
+ }
+
+ for ( p = str; p < (str + len - SUBLEN + 1); p++ )
+ {
+ for ( i = 0; i < SUBLEN; i++ )
+ {
+ buf[i] = p[i];
+ }
+ buf[SUBLEN] = '\0';
+ (*ivals)[*nsubs] = slapi_value_new_string(buf);
+ (*nsubs)++;
+ }
+
+ if ( prepost == '$' )
+ {
+ p = str + len - SUBLEN + 1;
+ for ( i = 0; i < SUBLEN - 1; i++ )
+ {
+ buf[i] = p[i];
+ }
+ buf[SUBLEN - 1] = '$';
+ buf[SUBLEN] = '\0';
+ (*ivals)[*nsubs] = slapi_value_new_string(buf);
+ (*nsubs)++;
+ }
+
+ LDAPDebug( LDAP_DEBUG_TRACE, "<= substring_comp_keys\n", 0, 0, 0 );
+}
diff --git a/ldap/servers/plugins/syntaxes/syntax.h b/ldap/servers/plugins/syntaxes/syntax.h
new file mode 100644
index 00000000..d6d883c9
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/syntax.h
@@ -0,0 +1,42 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/* syntax.h - string syntax definitions */
+
+#ifndef _LIBSYNTAX_H_
+#define _LIBSYNTAX_H_
+
+#define SLAPD_LOGGING 1
+
+#include "slap.h"
+#include "slapi-plugin.h"
+#include <dirlite_strings.h> /* PLUGIN_MAGIC_VENDOR_STR */
+
+#define SYNTAX_CIS 1
+#define SYNTAX_CES 2
+#define SYNTAX_TEL 4 /* telephone number: used with SYNTAX_CIS */
+#define SYNTAX_DN 8 /* distinguished name: used with SYNTAX_CIS */
+#define SYNTAX_SI 16 /* space insensitive: used with SYNTAX_CIS */
+
+#define SUBLEN 3
+
+#ifndef MIN
+#define MIN( a, b ) (a < b ? a : b )
+#endif
+
+int string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,Slapi_Value **bvals, int syntax );
+int string_filter_ava( struct berval *bvfilter, Slapi_Value **bvals, int syntax,int ftype, Slapi_Value **retVal );
+int string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,Slapi_Value ***ivals, int syntax, int ftype );
+int string_assertion2keys_ava(Slapi_PBlock *pb,Slapi_Value *val,Slapi_Value ***ivals,int syntax,int ftype );
+int string_assertion2keys_sub(Slapi_PBlock *pb,char *initial,char **any,char *final,Slapi_Value ***ivals,int syntax);
+int value_cmp(struct berval *v1,struct berval *v2,int syntax,int normalize);
+void value_normalize(char *s,int syntax,int trim_leading_blanks);
+
+char *first_word( char *s );
+char *next_word( char *s );
+char *phonetic( char *s );
+
+
+#endif
diff --git a/ldap/servers/plugins/syntaxes/tel.c b/ldap/servers/plugins/syntaxes/tel.c
new file mode 100644
index 00000000..c2c80d1a
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/tel.c
@@ -0,0 +1,135 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/* tel.c - telephonenumber syntax routines */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "syntax.h"
+
+static int tel_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
+ Slapi_Value **bvals, int ftype, Slapi_Value **retVal );
+static int tel_filter_sub( Slapi_PBlock *pb, char *initial, char **any,
+ char *final, Slapi_Value **bvals );
+static int tel_values2keys( Slapi_PBlock *pb, Slapi_Value **val,
+ Slapi_Value ***ivals, int ftype );
+static int tel_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *val,
+ Slapi_Value ***ivals, int ftype );
+static int tel_assertion2keys_sub( Slapi_PBlock *pb, char *initial, char **any,
+ char *final, Slapi_Value ***ivals );
+static int tel_compare(struct berval *v1, struct berval *v2);
+
+/* the first name is the official one from RFC 2252 */
+static char *names[] = { "TelephoneNumber", "tel", TELEPHONE_SYNTAX_OID, 0 };
+
+static Slapi_PluginDesc pdesc = { "tele-syntax", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT,
+ "telephoneNumber attribute syntax plugin" };
+
+int
+tel_init( Slapi_PBlock *pb )
+{
+ int rc, flags;
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "=> tel_init\n", 0, 0, 0 );
+
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ (void *) SLAPI_PLUGIN_VERSION_01 );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *)&pdesc );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_AVA,
+ (void *) tel_filter_ava );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FILTER_SUB,
+ (void *) tel_filter_sub );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALUES2KEYS,
+ (void *) tel_values2keys );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA,
+ (void *) tel_assertion2keys_ava );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_SUB,
+ (void *) tel_assertion2keys_sub );
+ flags = SLAPI_PLUGIN_SYNTAX_FLAG_ORDERING;
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_FLAGS,
+ (void *) &flags );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_NAMES,
+ (void *) names );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_OID,
+ (void *) TELEPHONE_SYNTAX_OID );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_COMPARE,
+ (void *) tel_compare );
+
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "<= tel_init %d\n", rc, 0, 0 );
+ return( rc );
+}
+
+static int
+tel_filter_ava(
+ Slapi_PBlock *pb,
+ struct berval *bvfilter,
+ Slapi_Value **bvals,
+ int ftype,
+ Slapi_Value **retVal
+)
+{
+ return( string_filter_ava( bvfilter, bvals, SYNTAX_TEL | SYNTAX_CIS,
+ ftype, retVal ) );
+}
+
+
+static int
+tel_filter_sub(
+ Slapi_PBlock *pb,
+ char *initial,
+ char **any,
+ char *final,
+ Slapi_Value **bvals
+)
+{
+ return( string_filter_sub( pb, initial, any, final, bvals, SYNTAX_TEL | SYNTAX_CIS ) );
+}
+
+static int
+tel_values2keys(
+ Slapi_PBlock *pb,
+ Slapi_Value **vals,
+ Slapi_Value ***ivals,
+ int ftype
+)
+{
+ return( string_values2keys( pb, vals, ivals, SYNTAX_TEL | SYNTAX_CIS,
+ ftype ) );
+}
+
+static int
+tel_assertion2keys_ava(
+ Slapi_PBlock *pb,
+ Slapi_Value *val,
+ Slapi_Value ***ivals,
+ int ftype
+)
+{
+ return(string_assertion2keys_ava( pb, val, ivals,
+ SYNTAX_TEL | SYNTAX_CIS, ftype ));
+}
+
+static int
+tel_assertion2keys_sub(
+ Slapi_PBlock *pb,
+ char *initial,
+ char **any,
+ char *final,
+ Slapi_Value ***ivals
+)
+{
+ return( string_assertion2keys_sub( pb, initial, any, final, ivals,
+ SYNTAX_TEL | SYNTAX_CIS ) );
+}
+
+static int tel_compare(
+ struct berval *v1,
+ struct berval *v2
+)
+{
+ return value_cmp(v1, v2, SYNTAX_TEL|SYNTAX_CIS, 3 /* Normalise both values */);
+}
diff --git a/ldap/servers/plugins/syntaxes/value.c b/ldap/servers/plugins/syntaxes/value.c
new file mode 100644
index 00000000..be496091
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/value.c
@@ -0,0 +1,209 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/* value.c - routines for dealing with values */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "syntax.h"
+
+/*
+ * Do not use the SDK ldap_utf8isspace directly until it is faster
+ * than this one.
+ */
+static int
+utf8isspace_fast( char* s )
+{
+ register unsigned char c = *(unsigned char*)s;
+ if (0x80 & c) return(ldap_utf8isspace(s));
+ switch (c) {
+ case 0x09:
+ case 0x0A:
+ case 0x0B:
+ case 0x0C:
+ case 0x0D:
+ case 0x20:
+ return 1;
+ default: break;
+ }
+ return 0;
+}
+
+/*
+** This function is used to normalizes search filter components,
+** and attribute values.
+**
+** jcm: I added the trim_spaces flag since this function
+** was incorrectly modifying search filter components. A search
+** of the form "cn=a* b*" (note the space) would be wrongly
+** normalized into "cn=a*b*", because this function is called
+** once for "a" and once for " b".
+*/
+void
+value_normalize(
+ char *s,
+ int syntax,
+ int trim_spaces
+)
+{
+ char *d;
+ int prevspace, curspace;
+
+ if ( ! (syntax & SYNTAX_CIS) && ! (syntax & SYNTAX_CES) ) {
+ return;
+ }
+
+ if ( syntax & SYNTAX_DN ) {
+ (void) slapi_dn_normalize_case( s );
+ return;
+ }
+
+ d = s;
+ if (trim_spaces) {
+ /* strip leading blanks */
+ while (utf8isspace_fast(s)) {
+ LDAP_UTF8INC(s);
+ }
+ }
+ /* handle value of all spaces - turn into single space */
+ /* unless space insensitive syntax - turn into zero length string */
+ if ( *s == '\0' && s != d ) {
+ if ( ! (syntax & SYNTAX_SI)) {
+ *d++ = ' ';
+ }
+ *d = '\0';
+ return;
+ }
+ prevspace = 0;
+ while ( *s ) {
+ curspace = utf8isspace_fast(s);
+
+ /* ignore spaces and '-' in telephone numbers */
+ if ( (syntax & SYNTAX_TEL) && (curspace || *s == '-') ) {
+ LDAP_UTF8INC(s);
+ continue;
+ }
+
+ /* ignore all spaces if this is a space insensitive value */
+ if ( (syntax & SYNTAX_SI) && curspace ) {
+ LDAP_UTF8INC(s);
+ continue;
+ }
+
+ /* compress multiple blanks */
+ if ( prevspace && curspace ) {
+ LDAP_UTF8INC(s);
+ continue;
+ }
+ prevspace = curspace;
+ if ( syntax & SYNTAX_CIS ) {
+ int ssz, dsz;
+ slapi_utf8ToLower((unsigned char*)s, (unsigned char *)d, &ssz, &dsz);
+ s += ssz;
+ d += dsz;
+ } else {
+ char *np;
+ int sz;
+
+ np = ldap_utf8next(s);
+ if (np == NULL || np == s) break;
+ sz = np - s;
+ memcpy(d,s,sz);
+ d += sz;
+ s += sz;
+ }
+ }
+ *d = '\0';
+ /* strip trailing blanks */
+ if (prevspace && trim_spaces) {
+ char *nd;
+
+ nd = ldap_utf8prev(d);
+ while (nd && utf8isspace_fast(nd)) {
+ d = nd;
+ nd = ldap_utf8prev(d);
+ *d = '\0';
+ }
+ }
+}
+
+int
+value_cmp(
+ struct berval *v1,
+ struct berval *v2,
+ int syntax,
+ int normalize
+)
+{
+ int rc;
+ struct berval bvcopy1;
+ struct berval bvcopy2;
+ char little_buffer[64];
+ size_t buffer_space = sizeof(little_buffer);
+ int buffer_offset = 0;
+ int free_v1 = 0;
+ int free_v2 = 0;
+
+ /* This code used to call malloc up to four times in the copying
+ * of attributes to be normalized. Now we attempt to keep everything
+ * on the stack and only malloc if the data is big
+ */
+ if ( normalize & 1 ) {
+ /* Do we have space in the little buffer ? */
+ if (v1->bv_len < buffer_space) {
+ bvcopy1.bv_len = v1->bv_len;
+ SAFEMEMCPY(&little_buffer[buffer_offset],v1->bv_val,v1->bv_len);
+ bvcopy1.bv_val = &little_buffer[buffer_offset];
+ bvcopy1.bv_val[v1->bv_len] = '\0';
+ v1 = &bvcopy1;
+ buffer_space-= v1->bv_len+1;
+ buffer_offset+= v1->bv_len+1;
+ } else {
+ v1 = ber_bvdup( v1 );
+ free_v1 = 1;
+ }
+ value_normalize( v1->bv_val, syntax, 1 /* trim leading blanks */ );
+ }
+ if ( normalize & 2 ) {
+ /* Do we have space in the little buffer ? */
+ if (v2->bv_len < buffer_space) {
+ bvcopy2.bv_len = v2->bv_len;
+ SAFEMEMCPY(&little_buffer[buffer_offset],v2->bv_val,v2->bv_len);
+ bvcopy2.bv_val = &little_buffer[buffer_offset];
+ bvcopy2.bv_val[v2->bv_len] = '\0';
+ v2 = &bvcopy2;
+ buffer_space-= v2->bv_len+1;
+ buffer_offset+= v2->bv_len+1;
+ } else {
+ v2 = ber_bvdup( v2 );
+ free_v2 = 1;
+ }
+ value_normalize( v2->bv_val, syntax, 1 /* trim leading blanks */ );
+ }
+
+ switch ( syntax ) {
+ case SYNTAX_CIS:
+ case (SYNTAX_CIS | SYNTAX_TEL):
+ case (SYNTAX_CIS | SYNTAX_DN):
+ case (SYNTAX_CIS | SYNTAX_SI):
+ rc = slapi_utf8casecmp( (unsigned char *)v1->bv_val,
+ (unsigned char *)v2->bv_val );
+ break;
+
+ case SYNTAX_CES:
+ rc = strcmp( v1->bv_val, v2->bv_val );
+ break;
+ }
+
+ if ( (normalize & 1) && free_v1) {
+ ber_bvfree( v1 );
+ }
+ if ( (normalize & 2) && free_v2) {
+ ber_bvfree( v2 );
+ }
+
+ return( rc );
+}