--enable-ipv6 enable IPv6 support [auto]"
ac_help="$ac_help
--enable-local enable AF_LOCAL (AF_UNIX) socket support [auto]"
-ac_help="$ac_help
- --enable-rewrite enable rewrite [no]"
ac_help="$ac_help
--enable-x-compile enable cross compiling [no]"
ac_help="$ac_help
--with-cyrus-sasl with Cyrus SASL support [auto]"
ac_help="$ac_help
- --with-fetch with fetch URL support [auto]"
+ --with-fetch with freeBSD fetch URL support [auto]"
ac_help="$ac_help
--with-kerberos with Kerberos support [auto]"
ac_help="$ac_help
ac_help="$ac_help
--enable-phonetic enable phonetic/soundex [no]"
ac_help="$ac_help
- --enable-rlookups enable reverse lookups [no]"
+ --enable-rewrite enable DN rewriting in back-ldap and back-meta [no]"
+ac_help="$ac_help
+ --enable-rlookups enable reverse lookups of client hostnames [no]"
ac_help="$ac_help
--enable-slp enable SLPv2 support [no]"
ac_help="$ac_help
ac_help="$ac_help
--enable-bdb enable Berkeley DB backend [yes]"
ac_help="$ac_help
- --with-bdb-module module type [static]"
+ --with-bdb-module module type static|dynamic [static]"
ac_help="$ac_help
--enable-dnssrv enable dnssrv backend [no]"
ac_help="$ac_help
- --with-dnssrv-module module type [static]"
+ --with-dnssrv-module module type static|dynamic [static]"
ac_help="$ac_help
--enable-ldap enable ldap backend [no]"
ac_help="$ac_help
- --with-ldap-module module type [static]"
+ --with-ldap-module module type static|dynamic [static]"
ac_help="$ac_help
--enable-ldbm enable ldbm backend [no]"
ac_help="$ac_help
- --with-ldbm-api with LDBM API [auto]"
+ --with-ldbm-api with LDBM API auto|berkeley|bcompat|mdbm|gdbm [auto]"
ac_help="$ac_help
- --with-ldbm-module module type [static]"
+ --with-ldbm-module module type static|dynamic [static]"
ac_help="$ac_help
- --with-ldbm-type use LDBM type [auto]"
+ --with-ldbm-type use LDBM type auto|btree|hash [auto]"
ac_help="$ac_help
--enable-meta enable metadirectory backend [no]"
ac_help="$ac_help
- --with-meta-module module type [static]"
+ --with-meta-module module type static|dynamic [static]"
ac_help="$ac_help
--enable-monitor enable monitor backend [no]"
ac_help="$ac_help
- --with-monitor-module module type [static]"
+ --with-monitor-module module type static|dynamic [static]"
ac_help="$ac_help
--enable-null enable null backend [no]"
ac_help="$ac_help
- --with-null-module module type [static]"
+ --with-null-module module type static|dynamic [static]"
ac_help="$ac_help
--enable-passwd enable passwd backend [no]"
ac_help="$ac_help
- --with-passwd-module module type [static]"
+ --with-passwd-module module type static|dynamic [static]"
ac_help="$ac_help
--enable-perl enable perl backend [no]"
ac_help="$ac_help
- --with-perl-module module type [static]"
+ --with-perl-module module type static|dynamic [static]"
ac_help="$ac_help
--enable-shell enable shell backend [no]"
ac_help="$ac_help
- --with-shell-module module type [static]"
+ --with-shell-module module type static|dynamic [static]"
ac_help="$ac_help
--enable-sql enable sql backend [no]"
ac_help="$ac_help
- --with-sql-module module type [static]"
+ --with-sql-module module type static|dynamic [static]"
ac_help="$ac_help
SLURPD (Replication Daemon) Options:"
ol_enable_local="auto"
fi
# end --enable-local
-# OpenLDAP --enable-rewrite
- # Check whether --enable-rewrite or --disable-rewrite was given.
-if test "${enable_rewrite+set}" = set; then
- enableval="$enable_rewrite"
-
- ol_arg=invalid
- for ol_val in auto yes no ; do
- if test "$enableval" = "$ol_val" ; then
- ol_arg="$ol_val"
- fi
- done
- if test "$ol_arg" = "invalid" ; then
- { echo "configure: error: bad value $enableval for --enable-rewrite" 1>&2; exit 1; }
- fi
- ol_enable_rewrite="$ol_arg"
-
-else
- ol_enable_rewrite="no"
-fi
-# end --enable-rewrite
# OpenLDAP --enable-x_compile
# Check whether --enable-x_compile or --disable-x_compile was given.
if test "${enable_x_compile+set}" = set; then
ol_enable_phonetic="no"
fi
# end --enable-phonetic
+# OpenLDAP --enable-rewrite
+ # Check whether --enable-rewrite or --disable-rewrite was given.
+if test "${enable_rewrite+set}" = set; then
+ enableval="$enable_rewrite"
+
+ ol_arg=invalid
+ for ol_val in auto yes no ; do
+ if test "$enableval" = "$ol_val" ; then
+ ol_arg="$ol_val"
+ fi
+ done
+ if test "$ol_arg" = "invalid" ; then
+ { echo "configure: error: bad value $enableval for --enable-rewrite" 1>&2; exit 1; }
+ fi
+ ol_enable_rewrite="$ol_arg"
+
+else
+ ol_enable_rewrite="no"
+fi
+# end --enable-rewrite
# OpenLDAP --enable-rlookups
# Check whether --enable-rlookups or --disable-rlookups was given.
if test "${enable_rlookups+set}" = set; then
OL_ARG_ENABLE(kbind,[ --enable-kbind enable LDAPv2+ Kerberos IV bind (deprecated)], no)dnl
OL_ARG_ENABLE(ipv6,[ --enable-ipv6 enable IPv6 support], auto)dnl
OL_ARG_ENABLE(local,[ --enable-local enable AF_LOCAL (AF_UNIX) socket support], auto)dnl
-OL_ARG_ENABLE(rewrite,[ --enable-rewrite enable rewrite], no)dnl
OL_ARG_ENABLE(x_compile,[ --enable-x-compile enable cross compiling],
no, [yes no])dnl
OL_ARG_WITH(cyrus_sasl,[ --with-cyrus-sasl with Cyrus SASL support],
auto, [auto yes no] )
-OL_ARG_WITH(fetch,[ --with-fetch with fetch URL support],
+OL_ARG_WITH(fetch,[ --with-fetch with freeBSD fetch URL support],
auto, [auto yes no] )
OL_ARG_WITH(kerberos,[ --with-kerberos with Kerberos support],
auto, [auto k5 k5only k425 kth k4 afs yes no])
OL_ARG_ENABLE(modules,[ --enable-modules enable dynamic module support], no)dnl
dnl OL_ARG_ENABLE(multimaster,[ --enable-multimaster enable multimaster replication], no)dnl
OL_ARG_ENABLE(phonetic,[ --enable-phonetic enable phonetic/soundex], no)dnl
-OL_ARG_ENABLE(rlookups,[ --enable-rlookups enable reverse lookups], no)dnl
+OL_ARG_ENABLE(rewrite,[ --enable-rewrite enable DN rewriting in back-ldap and back-meta], no)dnl
+OL_ARG_ENABLE(rlookups,[ --enable-rlookups enable reverse lookups of client hostnames], no)dnl
OL_ARG_ENABLE(slp, [ --enable-slp enable SLPv2 support], no)dnl
OL_ARG_ENABLE(wrappers,[ --enable-wrappers enable tcp wrapper support], no)dnl
dnl SLAPD Backend options
OL_ARG_ENABLE(bdb,[ --enable-bdb enable Berkeley DB backend], yes)dnl
-OL_ARG_WITH(bdb_module,[ --with-bdb-module module type], static,
+OL_ARG_WITH(bdb_module,[ --with-bdb-module module type static|dynamic], static,
[static dynamic])
OL_ARG_ENABLE(dnssrv,[ --enable-dnssrv enable dnssrv backend], no)dnl
-OL_ARG_WITH(dnssrv_module,[ --with-dnssrv-module module type], static,
+OL_ARG_WITH(dnssrv_module,[ --with-dnssrv-module module type static|dynamic], static,
[static dynamic])
OL_ARG_ENABLE(ldap,[ --enable-ldap enable ldap backend], no)dnl
-OL_ARG_WITH(ldap_module,[ --with-ldap-module module type], static,
+OL_ARG_WITH(ldap_module,[ --with-ldap-module module type static|dynamic], static,
[static dynamic])
OL_ARG_ENABLE(ldbm,[ --enable-ldbm enable ldbm backend], no)dnl
-OL_ARG_WITH(ldbm_api,[ --with-ldbm-api with LDBM API], auto,
+OL_ARG_WITH(ldbm_api,[ --with-ldbm-api with LDBM API auto|berkeley|bcompat|mdbm|gdbm], auto,
[auto berkeley bcompat mdbm gdbm])
-OL_ARG_WITH(ldbm_module,[ --with-ldbm-module module type], static,
+OL_ARG_WITH(ldbm_module,[ --with-ldbm-module module type static|dynamic], static,
[static dynamic])
-OL_ARG_WITH(ldbm_type,[ --with-ldbm-type use LDBM type], auto,
+OL_ARG_WITH(ldbm_type,[ --with-ldbm-type use LDBM type auto|btree|hash], auto,
[auto btree hash])
OL_ARG_ENABLE(meta,[ --enable-meta enable metadirectory backend], no)dnl
-OL_ARG_WITH(meta_module,[ --with-meta-module module type], static,
+OL_ARG_WITH(meta_module,[ --with-meta-module module type static|dynamic], static,
[static dynamic])
OL_ARG_ENABLE(monitor,[ --enable-monitor enable monitor backend], no)dnl
-OL_ARG_WITH(monitor_module,[ --with-monitor-module module type], static,
+OL_ARG_WITH(monitor_module,[ --with-monitor-module module type static|dynamic], static,
[static dynamic])
OL_ARG_ENABLE(null,[ --enable-null enable null backend], no)dnl
-OL_ARG_WITH(null_module,[ --with-null-module module type], static,
+OL_ARG_WITH(null_module,[ --with-null-module module type static|dynamic], static,
[static dynamic])
OL_ARG_ENABLE(passwd,[ --enable-passwd enable passwd backend], no)dnl
-OL_ARG_WITH(passwd_module,[ --with-passwd-module module type], static,
+OL_ARG_WITH(passwd_module,[ --with-passwd-module module type static|dynamic], static,
[static dynamic])
OL_ARG_ENABLE(perl,[ --enable-perl enable perl backend], no)dnl
-OL_ARG_WITH(perl_module,[ --with-perl-module module type], static,
+OL_ARG_WITH(perl_module,[ --with-perl-module module type static|dynamic], static,
[static dynamic])
OL_ARG_ENABLE(shell,[ --enable-shell enable shell backend], no)dnl
-OL_ARG_WITH(shell_module,[ --with-shell-module module type], static,
+OL_ARG_WITH(shell_module,[ --with-shell-module module type static|dynamic], static,
[static dynamic])
OL_ARG_ENABLE(sql,[ --enable-sql enable sql backend], no)dnl
-OL_ARG_WITH(sql_module,[ --with-sql-module module type], static,
+OL_ARG_WITH(sql_module,[ --with-sql-module module type static|dynamic], static,
[static dynamic])
dnl ----------------------------------------------------------------
.B concurrency <integer>
Specify a desired level of concurrency. Provided to the underlying
thread system as a hint. The default is not to provide any hint.
+.\".TP
+.\".B debug <subsys> <level>
+.\"Specify a logging level for a particular subsystem. The subsystems include
+.\".B global
+.\"a global level for all subsystems,
+.\".B acl
+.\"the ACL engine,
+.\".B backend
+.\"the backend databases,
+.\".B cache
+.\"the entry cache manager,
+.\".B config
+.\"the config file reader,
+.\".B connection
+.\"the connection manager,
+.\".B cyrus
+.\"the Cyrus SASL library interface,
+.\".B filter
+.\"the search filter processor,
+.\".B getdn
+.\"the DN normalization library,
+.\".B index
+.\"the database indexer,
+.\".B liblber
+.\"the ASN.1 BER library,
+.\".B module
+.\"the dynamic module loader,
+.\".B operation
+.\"the LDAP operation processors,
+.\".B sasl
+.\"the SASL authentication subsystem,
+.\".B schema
+.\"the schema processor, and
+.\".B tls
+.\"the TLS library interface. This is not an exhaustive list; there are many
+.\"other subsystems and more are added over time.
+.\"
+.\"The levels are, in order of decreasing priority:
+.\".B emergency, alert, critical, error, warning, notice, information, entry,
+.\".B args, results, detail1, detail2
+.\"An integer may be used instead, with 0 corresponding to
+.\".B emergency
+.\"up to 11 for
+.\".BR detail2 .
+.\"The
+.\".B entry
+.\"level logs function entry points,
+.\".B args
+.\"adds function call parameters, and
+.\".B results
+.\"adds the function results to the logs.
+.\"The
+.\".B detail1
+.\"and
+.\".B detail2
+.\"levels add even more low level detail from individual functions.
.TP
.B defaultsearchbase <dn>
Specify a default search base to use when client submits a
no limit is set on
.BR unchecked .
.RE
+.\".TP
+.\".B logfile <filename>
+.\"Specify a file for recording debug log messages. By default these messages
+.\"only go to stderr and are not recorded anywhere else. Specifying a logfile
+.\"copies messages to both stderr and the logfile.
.TP
.B loglevel <integer>
Specify the level at which debugging statements and operation
.PD
.RE
.RE
+.TP
+.B moduleload <filename>
+Specify the name of a dynamically loadable module to load. The filename
+may be an absolute path name or a simple filename. Non-absolute names
+are searched for in the directories specified by the
+.B modulepath
+option. This option and the
+.B modulepath
+option are only usable if slapd was compiled with --enable-modules.
+.TP
+.B modulepath <pathspec>
+Specify a list of directories to search for loadable modules. Typically
+the path is colon-separated but this depends on the operating system.
.HP
.B objectclass ( <oid> [NAME <name>] [DESC <description] [OBSOLETE]\
[SUP <oids>] [{ ABSTRACT | STRUCTURAL | AUXILIARY }] [MUST <oids>]\
.RS
.RS
.TP
-.B uid=<UID>[,cn=<REALM>][,cn=<MECH>],cn=AUTHZ
+.B uid=<username>[,cn=<realm>],cn=<mechanism>,cn=auth
.RE
This SASL name is then compared against the
.RS
.RS
.TP
-.B uid=(.*)\\\\+realm=.*
+.B uid=(.*),cn=.*
.RE
.RE
and replacement patterns. The matching patterns are checked in the order they
appear in the file, stopping at the first successful match.
-.B Caution:
-Because the plus sign + is a character recognized by the regular expression engine,
-and it will appear in SASL names that include a REALM, be careful to escape the
-plus sign with a backslash \\+ to remove the character's special meaning.
+.\".B Caution:
+.\"Because the plus sign + is a character recognized by the regular expression engine,
+.\"and it will appear in SASL names that include a REALM, be careful to escape the
+.\"plus sign with a backslash \\+ to remove the character's special meaning.
.RE
.TP
.B sasl-secprops <properties>
See
.BR limits
for an explanation of the different flags.
+.TP
+.B ucdata-path <path>
+Specify the path to the directory containing the Unicode character
+tables. The default path is LOCALSTATEDIR/ucdata.
.SH TLS OPTIONS
If
.B slapd
.B slapd
will recognize.
.TP
+.B TLSCACertificatePath <path>
+Specifies the path of a directory that contains Certificate Authority
+certificates in separate individual files. Usually only one of this
+or the TLSCACertificateFile is used.
+.TP
.B TLSCertificateFile <filename>
Specifies the file that contains the
.B slapd
modifiersName, modifyTimestamp, creatorsName, and
createTimestamp attributes for entries. By default, lastmod is on.
.TP
+.B maxderefdepth <depth>
+Specifies the maximum number of aliases to dereference when trying to
+resolve an entry, used to avoid inifinite alias loops. The default is 1.
+.TP
.B readonly on | off
This option puts the database into "read-only" mode. Any attempts to
modify the database will return an "unwilling to perform" error. By
backend database. Multiple suffix lines can be given and at least one is
required for each database definition.
.TP
+.B suffixalias <alias> <aliased suffix>
+Specify an alternate suffix that may be used to reference an already defined
+database suffix. Operations specifying DNs residing under the alias
+will execute as if they had specified the aliased suffix.
+.TP
.B subordinate
Specify that the current backend database is a subordinate of another
backend database. A subordinate database may have only one suffix. This
Options in this category only apply to the BDB databases. That is,
they must follow "database bdb" line and come before any subsequent
"backend" or "database" lines.
+.TP
+.B cachesize <integer>
+Specify the size in entries of the in-memory cache maintained
+by the BDB backend database instance. The default is 1000 entries.
+.TP
+.B checkpoint <kbyte> <min>
+Specify the frequency for checkpointing the database transaction log.
+A checkpoint operation flushes the database buffers to disk and writes
+a checkpoint record in the log. The checkpoint will occur if either
+<kbyte> data has been written or <min> minutes have passed since the
+last checkpoint. Both arguments default to zero, in which case they are ignored.
+See the Berkeley DB reference guide for more details.
+.TP
+.B dbnosync
+Specify that on-disk database contents should not be immediately
+synchronized with in memory changes. Enabling this option may improve
+performance at the expense of data security.
+.TP
+.B directory <directory>
+Specify the directory where the BDB files containing this database and
+associated indexes live. A separate directory must be specified for
+each database. The default is
+.BR LOCALSTATEDIR/openldap-data .
+.TP
+.B dirtyread
+Allow reads of modified but not yet committed data. Usually transactions
+are isolated to prevent other operations from accessing uncommitted data.
+This option may improve performance, but may also return inconsistent
+results if the data comes from a transaction that is later aborted. In
+this case, the modified data is discarded and a subsequent search will
+return a different result.
+.TP
+.B
+index {<attrlist>|default} [pres,eq,approx,sub,<special>]
+See the description for LDBM.
+.TP
+.B lockdetect {oldest|youngest|fewest|random|default}
+Specify which transaction to abort when a deadlock is detected. The
+default is the same as
+.BR random .
+.TP
+.B mode <integer>
+Specify the file protection mode that newly created database
+index files should have. The default is 0600.
+
.SH LDBM DATABASE-SPECIFIC OPTIONS
Options in this category only apply to the LDBM databases. That is,
they must follow "database ldbm" line and come before any subsequent
* set SASL properties to TLS ssf and authid
*/
{
- const char *authid;
+ char *authid;
ber_len_t ssf;
/* we need to let SASL know */
--- /dev/null
+# $OpenLDAP$
+## Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+##
+## Makefile.in for LDAP -lldap
+##
+LIBRARY = liblunicode.a
+
+XXDIR = $(srcdir)/*/
+XXHEADERS = ucdata.h ure.h
+
+XXSRCS = ucdata.c ucgendat.c ure.c urestubs.c
+SRCS = ucstr.c
+OBJS = ucdata.o ure.o urestubs.o ucstr.o
+
+XLIB = $(LIBRARY)
+PROGRAMS = ucgendat
+
+LDAP_INCDIR= ../../include
+LDAP_LIBDIR= ../../libraries
+
+ucgendat: $(XLIBS) ucgendat.o
+ $(LTLINK) -o $@ ucgendat.o $(LIBS)
+ ./ucgendat $(srcdir)/UnicodeData.txt -x $(srcdir)/CompositionExclusions.txt
+
+DATFILES = case.dat cmbcl.dat comp.dat ctype.dat decomp.dat num.dat kdecomp.dat
+
+install-local: $(PROGRAMS) FORCE
+ -$(MKDIR) $(DESTDIR)$(datadir)/ucdata
+ @for i in $(DATFILES); do \
+ echo $(INSTALL) $(INSTALLFLAGS) -m 644 $$i $(DESTDIR)$(datadir)/ucdata; \
+ $(INSTALL) $(INSTALLFLAGS) -m 644 $$i $(DESTDIR)$(datadir)/ucdata; \
+ done
+
+.links :
+ @for i in $(XXSRCS) $(XXHEADERS); do \
+ $(RM) $$i ; \
+ $(LN_S) $(XXDIR)$$i . ; \
+ done
+ touch .links
+
+$(XXSRCS) : .links
+
+clean-local: FORCE
+ @$(RM) *.dat .links
+
+depend-common: .links
static unsigned long *_ucdcmp_nodes;
static unsigned long *_ucdcmp_decomp;
+static unsigned long _uckdcmp_size;
+static unsigned long *_uckdcmp_nodes;
+static unsigned long *_uckdcmp_decomp;
+
/*
* Return -1 on error, 0 if okay
*/
return 0;
}
+/*
+ * Return -1 on error, 0 if okay
+ */
+static int
+_uckdcmp_load(char *paths, int reload)
+{
+ FILE *in;
+ unsigned long size, i;
+ _ucheader_t hdr;
+
+ if (_uckdcmp_size > 0) {
+ if (!reload)
+ /*
+ * The decompositions have already been loaded.
+ */
+ return 0;
+
+ free((char *) _uckdcmp_nodes);
+ _uckdcmp_size = 0;
+ }
+
+ if ((in = _ucopenfile(paths, "kdecomp.dat", "rb")) == 0)
+ return -1;
+
+ /*
+ * Load the header.
+ */
+ fread((char *) &hdr, sizeof(_ucheader_t), 1, in);
+
+ if (hdr.bom == 0xfffe) {
+ hdr.cnt = endian_short(hdr.cnt);
+ hdr.size.bytes = endian_long(hdr.size.bytes);
+ }
+
+ _uckdcmp_size = hdr.cnt << 1;
+ _uckdcmp_nodes = (unsigned long *) malloc(hdr.size.bytes);
+ _uckdcmp_decomp = _uckdcmp_nodes + (_uckdcmp_size + 1);
+
+ /*
+ * Read the decomposition data in.
+ */
+ size = hdr.size.bytes / sizeof(unsigned long);
+ fread((char *) _uckdcmp_nodes, sizeof(unsigned long), size, in);
+
+ /*
+ * Do an endian swap if necessary.
+ */
+ if (hdr.bom == 0xfffe) {
+ for (i = 0; i < size; i++)
+ _uckdcmp_nodes[i] = endian_long(_uckdcmp_nodes[i]);
+ }
+ fclose(in);
+ return 0;
+}
+
static void
_ucdcmp_unload(void)
{
_ucdcmp_size = 0;
}
+static void
+_uckdcmp_unload(void)
+{
+ if (_uckdcmp_size == 0)
+ return;
+
+ /*
+ * Only need to free the offsets because the memory is allocated as a
+ * single block.
+ */
+ free((char *) _uckdcmp_nodes);
+ _uckdcmp_size = 0;
+}
+
int
ucdecomp(unsigned long code, unsigned long *num, unsigned long **decomp)
{
long l, r, m;
+ if (code < _ucdcmp_nodes[0]) {
+ return 0;
+ }
+
l = 0;
r = _ucdcmp_nodes[_ucdcmp_size] - 1;
return 0;
}
+int
+uckdecomp(unsigned long code, unsigned long *num, unsigned long **decomp)
+{
+ long l, r, m;
+
+ if (code < _uckdcmp_nodes[0]) {
+ return 0;
+ }
+
+ l = 0;
+ r = _uckdcmp_nodes[_uckdcmp_size] - 1;
+
+ while (l <= r) {
+ /*
+ * Determine a "mid" point and adjust to make sure the mid point is at
+ * the beginning of a code+offset pair.
+ */
+ m = (l + r) >> 1;
+ m -= (m & 1);
+ if (code > _uckdcmp_nodes[m])
+ l = m + 2;
+ else if (code < _uckdcmp_nodes[m])
+ r = m - 2;
+ else if (code == _uckdcmp_nodes[m]) {
+ *num = _uckdcmp_nodes[m + 3] - _uckdcmp_nodes[m + 1];
+ *decomp = &_uckdcmp_decomp[_uckdcmp_nodes[m + 1]];
+ return 1;
+ }
+ }
+ return 0;
+}
+
int
ucdecomp_hangul(unsigned long code, unsigned long *num, unsigned long decomp[])
{
return 1;
}
-int
-uccanondecomp(const unsigned long *in, int inlen,
- unsigned long **out, int *outlen)
+/* mode == 0 for canonical, mode == 1 for compatibility */
+static int
+uccanoncompatdecomp(const unsigned long *in, int inlen,
+ unsigned long **out, int *outlen, short mode)
{
int l, size;
unsigned i, j, k;
i = 0;
for (j = 0; j < (unsigned) inlen; j++) {
- if (ucdecomp(in[j], &num, &decomp)) {
+ if (mode ? uckdecomp(in[j], &num, &decomp) : ucdecomp(in[j], &num, &decomp)) {
if ( size - i < num) {
size = inlen + i - j + num - 1;
*out = (unsigned long *) realloc(*out, size * sizeof(**out));
return *outlen = i;
}
+int
+uccanondecomp(const unsigned long *in, int inlen,
+ unsigned long **out, int *outlen)
+{
+ return uccanoncompatdecomp(in, inlen, out, outlen, 0);
+}
+
+int
+uccompatdecomp(const unsigned long *in, int inlen,
+ unsigned long **out, int *outlen)
+{
+ return uccanoncompatdecomp(in, inlen, out, outlen, 1);
+}
+
/**************************************************************************
*
* Support for combining classes.
error |= _ucnumb_load(paths, 0) < 0 ? UCDATA_NUM : 0;
if (masks & UCDATA_COMP)
error |= _uccomp_load(paths, 0) < 0 ? UCDATA_COMP : 0;
+ if (masks & UCDATA_KDECOMP)
+ error |= _uckdcmp_load(paths, 0) < 0 ? UCDATA_KDECOMP : 0;
return -error;
}
_ucnumb_unload();
if (masks & UCDATA_COMP)
_uccomp_unload();
+ if (masks & UCDATA_KDECOMP)
+ _uckdcmp_unload();
}
/*
error |= _ucnumb_load(paths, 1) < 0 ? UCDATA_NUM : 0;
if (masks & UCDATA_COMP)
error |= _uccomp_load(paths, 1) < 0 ? UCDATA_COMP : 0;
+ if (masks & UCDATA_KDECOMP)
+ error |= _uckdcmp_load(paths, 1) < 0 ? UCDATA_KDECOMP : 0;
return -error;
}
--- /dev/null
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/*
+ * Copyright 2001 Computing Research Labs, New Mexico State University
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+ * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _h_ucdata
+#define _h_ucdata
+
+/*
+ * $Id: ucdata.h,v 1.6 2001/01/02 18:46:20 mleisher Exp $
+ */
+
+LDAP_BEGIN_DECL
+
+#define UCDATA_VERSION "2.4"
+
+/**************************************************************************
+ *
+ * Masks and macros for character properties.
+ *
+ **************************************************************************/
+
+/*
+ * Values that can appear in the `mask1' parameter of the ucisprop()
+ * function.
+ */
+#define UC_MN 0x00000001 /* Mark, Non-Spacing */
+#define UC_MC 0x00000002 /* Mark, Spacing Combining */
+#define UC_ME 0x00000004 /* Mark, Enclosing */
+#define UC_ND 0x00000008 /* Number, Decimal Digit */
+#define UC_NL 0x00000010 /* Number, Letter */
+#define UC_NO 0x00000020 /* Number, Other */
+#define UC_ZS 0x00000040 /* Separator, Space */
+#define UC_ZL 0x00000080 /* Separator, Line */
+#define UC_ZP 0x00000100 /* Separator, Paragraph */
+#define UC_CC 0x00000200 /* Other, Control */
+#define UC_CF 0x00000400 /* Other, Format */
+#define UC_OS 0x00000800 /* Other, Surrogate */
+#define UC_CO 0x00001000 /* Other, Private Use */
+#define UC_CN 0x00002000 /* Other, Not Assigned */
+#define UC_LU 0x00004000 /* Letter, Uppercase */
+#define UC_LL 0x00008000 /* Letter, Lowercase */
+#define UC_LT 0x00010000 /* Letter, Titlecase */
+#define UC_LM 0x00020000 /* Letter, Modifier */
+#define UC_LO 0x00040000 /* Letter, Other */
+#define UC_PC 0x00080000 /* Punctuation, Connector */
+#define UC_PD 0x00100000 /* Punctuation, Dash */
+#define UC_PS 0x00200000 /* Punctuation, Open */
+#define UC_PE 0x00400000 /* Punctuation, Close */
+#define UC_PO 0x00800000 /* Punctuation, Other */
+#define UC_SM 0x01000000 /* Symbol, Math */
+#define UC_SC 0x02000000 /* Symbol, Currency */
+#define UC_SK 0x04000000 /* Symbol, Modifier */
+#define UC_SO 0x08000000 /* Symbol, Other */
+#define UC_L 0x10000000 /* Left-To-Right */
+#define UC_R 0x20000000 /* Right-To-Left */
+#define UC_EN 0x40000000 /* European Number */
+#define UC_ES 0x80000000 /* European Number Separator */
+
+/*
+ * Values that can appear in the `mask2' parameter of the ucisprop()
+ * function.
+ */
+#define UC_ET 0x00000001 /* European Number Terminator */
+#define UC_AN 0x00000002 /* Arabic Number */
+#define UC_CS 0x00000004 /* Common Number Separator */
+#define UC_B 0x00000008 /* Block Separator */
+#define UC_S 0x00000010 /* Segment Separator */
+#define UC_WS 0x00000020 /* Whitespace */
+#define UC_ON 0x00000040 /* Other Neutrals */
+/*
+ * Implementation specific character properties.
+ */
+#define UC_CM 0x00000080 /* Composite */
+#define UC_NB 0x00000100 /* Non-Breaking */
+#define UC_SY 0x00000200 /* Symmetric */
+#define UC_HD 0x00000400 /* Hex Digit */
+#define UC_QM 0x00000800 /* Quote Mark */
+#define UC_MR 0x00001000 /* Mirroring */
+#define UC_SS 0x00002000 /* Space, other */
+
+#define UC_CP 0x00004000 /* Defined */
+
+/*
+ * Added for UnicodeData-2.1.3.
+ */
+#define UC_PI 0x00008000 /* Punctuation, Initial */
+#define UC_PF 0x00010000 /* Punctuation, Final */
+
+/*
+ * This is the primary function for testing to see if a character has some set
+ * of properties. The macros that test for various character properties all
+ * call this function with some set of masks.
+ */
+LDAP_LUNICODE_F (int)
+ucisprop LDAP_P((unsigned long code, unsigned long mask1,
+ unsigned long mask2));
+
+#define ucisalpha(cc) ucisprop(cc, UC_LU|UC_LL|UC_LM|UC_LO|UC_LT, 0)
+#define ucisdigit(cc) ucisprop(cc, UC_ND, 0)
+#define ucisalnum(cc) ucisprop(cc, UC_LU|UC_LL|UC_LM|UC_LO|UC_LT|UC_ND, 0)
+#define uciscntrl(cc) ucisprop(cc, UC_CC|UC_CF, 0)
+#define ucisspace(cc) ucisprop(cc, UC_ZS|UC_SS, 0)
+#define ucisblank(cc) ucisprop(cc, UC_ZS, 0)
+#define ucispunct(cc) ucisprop(cc, UC_PD|UC_PS|UC_PE|UC_PO, UC_PI|UC_PF)
+#define ucisgraph(cc) ucisprop(cc, UC_MN|UC_MC|UC_ME|UC_ND|UC_NL|UC_NO|\
+ UC_LU|UC_LL|UC_LT|UC_LM|UC_LO|UC_PC|UC_PD|\
+ UC_PS|UC_PE|UC_PO|UC_SM|UC_SM|UC_SC|UC_SK|\
+ UC_SO, UC_PI|UC_PF)
+#define ucisprint(cc) ucisprop(cc, UC_MN|UC_MC|UC_ME|UC_ND|UC_NL|UC_NO|\
+ UC_LU|UC_LL|UC_LT|UC_LM|UC_LO|UC_PC|UC_PD|\
+ UC_PS|UC_PE|UC_PO|UC_SM|UC_SM|UC_SC|UC_SK|\
+ UC_SO|UC_ZS, UC_PI|UC_PF)
+#define ucisupper(cc) ucisprop(cc, UC_LU, 0)
+#define ucislower(cc) ucisprop(cc, UC_LL, 0)
+#define ucistitle(cc) ucisprop(cc, UC_LT, 0)
+#define ucisxdigit(cc) ucisprop(cc, 0, UC_HD)
+
+#define ucisisocntrl(cc) ucisprop(cc, UC_CC, 0)
+#define ucisfmtcntrl(cc) ucisprop(cc, UC_CF, 0)
+
+#define ucissymbol(cc) ucisprop(cc, UC_SM|UC_SC|UC_SO|UC_SK, 0)
+#define ucisnumber(cc) ucisprop(cc, UC_ND|UC_NO|UC_NL, 0)
+#define ucisnonspacing(cc) ucisprop(cc, UC_MN, 0)
+#define ucisopenpunct(cc) ucisprop(cc, UC_PS, 0)
+#define ucisclosepunct(cc) ucisprop(cc, UC_PE, 0)
+#define ucisinitialpunct(cc) ucisprop(cc, 0, UC_PI)
+#define ucisfinalpunct(cc) ucisprop(cc, 0, UC_PF)
+
+#define uciscomposite(cc) ucisprop(cc, 0, UC_CM)
+#define ucishex(cc) ucisprop(cc, 0, UC_HD)
+#define ucisquote(cc) ucisprop(cc, 0, UC_QM)
+#define ucissymmetric(cc) ucisprop(cc, 0, UC_SY)
+#define ucismirroring(cc) ucisprop(cc, 0, UC_MR)
+#define ucisnonbreaking(cc) ucisprop(cc, 0, UC_NB)
+
+/*
+ * Directionality macros.
+ */
+#define ucisrtl(cc) ucisprop(cc, UC_R, 0)
+#define ucisltr(cc) ucisprop(cc, UC_L, 0)
+#define ucisstrong(cc) ucisprop(cc, UC_L|UC_R, 0)
+#define ucisweak(cc) ucisprop(cc, UC_EN|UC_ES, UC_ET|UC_AN|UC_CS)
+#define ucisneutral(cc) ucisprop(cc, 0, UC_B|UC_S|UC_WS|UC_ON)
+#define ucisseparator(cc) ucisprop(cc, 0, UC_B|UC_S)
+
+/*
+ * Other macros inspired by John Cowan.
+ */
+#define ucismark(cc) ucisprop(cc, UC_MN|UC_MC|UC_ME, 0)
+#define ucismodif(cc) ucisprop(cc, UC_LM, 0)
+#define ucisletnum(cc) ucisprop(cc, UC_NL, 0)
+#define ucisconnect(cc) ucisprop(cc, UC_PC, 0)
+#define ucisdash(cc) ucisprop(cc, UC_PD, 0)
+#define ucismath(cc) ucisprop(cc, UC_SM, 0)
+#define uciscurrency(cc) ucisprop(cc, UC_SC, 0)
+#define ucismodifsymbol(cc) ucisprop(cc, UC_SK, 0)
+#define ucisnsmark(cc) ucisprop(cc, UC_MN, 0)
+#define ucisspmark(cc) ucisprop(cc, UC_MC, 0)
+#define ucisenclosing(cc) ucisprop(cc, UC_ME, 0)
+#define ucisprivate(cc) ucisprop(cc, UC_CO, 0)
+#define ucissurrogate(cc) ucisprop(cc, UC_OS, 0)
+#define ucislsep(cc) ucisprop(cc, UC_ZL, 0)
+#define ucispsep(cc) ucisprop(cc, UC_ZP, 0)
+
+#define ucisidentstart(cc) ucisprop(cc, UC_LU|UC_LL|UC_LT|UC_LO|UC_NL, 0)
+#define ucisidentpart(cc) ucisprop(cc, UC_LU|UC_LL|UC_LT|UC_LO|UC_NL|\
+ UC_MN|UC_MC|UC_ND|UC_PC|UC_CF, 0)
+
+#define ucisdefined(cc) ucisprop(cc, 0, UC_CP)
+#define ucisundefined(cc) !ucisprop(cc, 0, UC_CP)
+
+/*
+ * Other miscellaneous character property macros.
+ */
+#define ucishan(cc) (((cc) >= 0x4e00 && (cc) <= 0x9fff) ||\
+ ((cc) >= 0xf900 && (cc) <= 0xfaff))
+#define ucishangul(cc) ((cc) >= 0xac00 && (cc) <= 0xd7ff)
+
+/**************************************************************************
+ *
+ * Functions for case conversion.
+ *
+ **************************************************************************/
+
+LDAP_LUNICODE_F (unsigned long) uctoupper LDAP_P((unsigned long code));
+LDAP_LUNICODE_F (unsigned long) uctolower LDAP_P((unsigned long code));
+LDAP_LUNICODE_F (unsigned long) uctotitle LDAP_P((unsigned long code));
+
+/**************************************************************************
+ *
+ * Functions for getting compositions.
+ *
+ **************************************************************************/
+
+/*
+ * This routine determines if there exists a composition of node1 and node2.
+ * If it returns 0, there is no composition. Any other value indicates a
+ * composition was returned in comp.
+ */
+LDAP_LUNICODE_F (int) uccomp LDAP_P((unsigned long node1, unsigned long node2,
+ unsigned long *comp));
+
+/*
+ * Does Hangul composition on the string str with length len, and returns
+ * the length of the composed string.
+ */
+LDAP_LUNICODE_F (int) uccomp_hangul LDAP_P((unsigned long *str, int len));
+
+/*
+ * Does canonical composition on the string str with length len, and returns
+ * the length of the composed string.
+ */
+LDAP_LUNICODE_F (int) uccanoncomp LDAP_P((unsigned long *str, int len));
+
+/**************************************************************************
+ *
+ * Functions for getting decompositions.
+ *
+ **************************************************************************/
+
+/*
+ * This routine determines if the code has a decomposition. If it returns 0,
+ * there is no decomposition. Any other value indicates a decomposition was
+ * returned.
+ */
+LDAP_LUNICODE_F (int)
+ucdecomp LDAP_P((unsigned long code, unsigned long *num,
+ unsigned long **decomp));
+
+/*
+ * Equivalent to ucdecomp() except that it includes compatibility
+ * decompositions.
+ */
+LDAP_LUNICODE_F (int)
+uckdecomp LDAP_P((unsigned long code, unsigned long *num,
+ unsigned long **decomp));
+
+/*
+ * If the code is a Hangul syllable, this routine decomposes it into the array
+ * passed. The array size should be at least 3.
+ */
+LDAP_LUNICODE_F (int)
+ucdecomp_hangul LDAP_P((unsigned long code, unsigned long *num,
+ unsigned long decomp[]));
+
+/*
+ * This routine does canonical decomposition of the string in of length
+ * inlen, and returns the decomposed string in out with length outlen.
+ * The memory for out is allocated by this routine. It returns the length
+ * of the decomposed string if okay, and -1 on error.
+ */
+LDAP_LUNICODE_F (int)
+uccanondecomp LDAP_P((const unsigned long *in, int inlen,
+ unsigned long **out, int *outlen));
+
+/*
+ * Equivalent to uccanondecomp() except that it includes compatibility
+ * decompositions.
+ */
+LDAP_LUNICODE_F (int)
+uccompatdecomp LDAP_P((const unsigned long *in, int inlen,
+ unsigned long **out, int *outlen));
+
+/**************************************************************************
+ *
+ * Functions for getting combining classes.
+ *
+ **************************************************************************/
+
+/*
+ * This will return the combining class for a character to be used with the
+ * Canonical Ordering algorithm.
+ */
+LDAP_LUNICODE_F (unsigned long) uccombining_class LDAP_P((unsigned long code));
+
+/**************************************************************************
+ *
+ * Functions for getting numbers and digits.
+ *
+ **************************************************************************/
+
+struct ucnumber {
+ int numerator;
+ int denominator;
+};
+
+LDAP_LUNICODE_F (int)
+ucnumber_lookup LDAP_P((unsigned long code, struct ucnumber *num));
+
+LDAP_LUNICODE_F (int)
+ucdigit_lookup LDAP_P((unsigned long code, int *digit));
+
+/*
+ * For compatibility with John Cowan's "uctype" package.
+ */
+LDAP_LUNICODE_F (struct ucnumber) ucgetnumber LDAP_P((unsigned long code));
+LDAP_LUNICODE_F (int) ucgetdigit LDAP_P((unsigned long code));
+
+/**************************************************************************
+ *
+ * Functions library initialization and cleanup.
+ *
+ **************************************************************************/
+
+/*
+ * Macros for specifying the data tables to be loaded, unloaded, or reloaded
+ * by the ucdata_load(), ucdata_unload(), and ucdata_reload() routines.
+ */
+#define UCDATA_CASE 0x01
+#define UCDATA_CTYPE 0x02
+#define UCDATA_DECOMP 0x04
+#define UCDATA_CMBCL 0x08
+#define UCDATA_NUM 0x10
+#define UCDATA_COMP 0x20
+#define UCDATA_KDECOMP 0x40
+
+#define UCDATA_ALL (UCDATA_CASE|UCDATA_CTYPE|UCDATA_DECOMP|\
+ UCDATA_CMBCL|UCDATA_NUM|UCDATA_COMP|UCDATA_KDECOMP)
+
+/*
+ * Functions to load, unload, and reload specific data files.
+ */
+LDAP_LUNICODE_F (int) ucdata_load LDAP_P((char *paths, int mask));
+LDAP_LUNICODE_F (void) ucdata_unload LDAP_P((int mask));
+LDAP_LUNICODE_F (int) ucdata_reload LDAP_P((char *paths, int mask));
+
+#ifdef UCDATA_DEPRECATED
+/*
+ * Deprecated functions, now just compatibility macros.
+ */
+#define ucdata_setup(p) ucdata_load(p, UCDATA_ALL)
+#define ucdata_cleanup() ucdata_unload(UCDATA_ALL)
+#endif
+
+LDAP_END_DECL
+
+#endif /* _h_ucdata */
/*
* List of decomposition. Created and expanded in order as the characters are
- * encountered.
+ * encountered. First list contains canonical mappings, second also includes
+ * compatibility mappings.
*/
static _decomp_t *decomps;
static unsigned long decomps_used;
static unsigned long decomps_size;
+static _decomp_t *kdecomps;
+static unsigned long kdecomps_used;
+static unsigned long kdecomps_size;
+
/*
* Composition exclusion table stuff.
*/
}
static void
-add_decomp(unsigned long code)
+add_decomp(unsigned long code, short compat)
{
unsigned long i, j, size;
-
+ _decomp_t **pdecomps;
+ unsigned long *pdecomps_used;
+ unsigned long *pdecomps_size;
+
+ if (compat) {
+ pdecomps = &kdecomps;
+ pdecomps_used = &kdecomps_used;
+ pdecomps_size = &kdecomps_size;
+ } else {
+ pdecomps = &decomps;
+ pdecomps_used = &decomps_used;
+ pdecomps_size = &decomps_size;
+ }
+
/*
* Add the code to the composite property.
*/
- ordered_range_insert(code, "Cm", 2);
+ if (!compat) {
+ ordered_range_insert(code, "Cm", 2);
+ }
/*
* Locate the insertion point for the code.
*/
- for (i = 0; i < decomps_used && code > decomps[i].code; i++) ;
+ for (i = 0; i < *pdecomps_used && code > (*pdecomps)[i].code; i++) ;
/*
* Allocate space for a new decomposition.
*/
- if (decomps_used == decomps_size) {
- if (decomps_size == 0)
- decomps = (_decomp_t *) malloc(sizeof(_decomp_t) << 3);
+ if (*pdecomps_used == *pdecomps_size) {
+ if (*pdecomps_size == 0)
+ *pdecomps = (_decomp_t *) malloc(sizeof(_decomp_t) << 3);
else
- decomps = (_decomp_t *)
- realloc((char *) decomps,
- sizeof(_decomp_t) * (decomps_size + 8));
- (void) memset((char *) (decomps + decomps_size), '\0',
+ *pdecomps = (_decomp_t *)
+ realloc((char *) *pdecomps,
+ sizeof(_decomp_t) * (*pdecomps_size + 8));
+ (void) memset((char *) (*pdecomps + *pdecomps_size), '\0',
sizeof(_decomp_t) << 3);
- decomps_size += 8;
+ *pdecomps_size += 8;
}
- if (i < decomps_used && code != decomps[i].code) {
+ if (i < *pdecomps_used && code != (*pdecomps)[i].code) {
/*
* Shift the decomps up by one if the codes don't match.
*/
- for (j = decomps_used; j > i; j--)
- (void) AC_MEMCPY((char *) &decomps[j], (char *) &decomps[j - 1],
+ for (j = *pdecomps_used; j > i; j--)
+ (void) AC_MEMCPY((char *) &(*pdecomps)[j], (char *) &(*pdecomps)[j - 1],
sizeof(_decomp_t));
}
* Insert or replace a decomposition.
*/
size = dectmp_size + (4 - (dectmp_size & 3));
- if (decomps[i].size < size) {
- if (decomps[i].size == 0)
- decomps[i].decomp = (unsigned long *)
+ if ((*pdecomps)[i].size < size) {
+ if ((*pdecomps)[i].size == 0)
+ (*pdecomps)[i].decomp = (unsigned long *)
malloc(sizeof(unsigned long) * size);
else
- decomps[i].decomp = (unsigned long *)
- realloc((char *) decomps[i].decomp,
+ (*pdecomps)[i].decomp = (unsigned long *)
+ realloc((char *) (*pdecomps)[i].decomp,
sizeof(unsigned long) * size);
- decomps[i].size = size;
+ (*pdecomps)[i].size = size;
}
- if (decomps[i].code != code)
- decomps_used++;
+ if ((*pdecomps)[i].code != code)
+ (*pdecomps_used)++;
- decomps[i].code = code;
- decomps[i].used = dectmp_size;
- (void) AC_MEMCPY((char *) decomps[i].decomp, (char *) dectmp,
+ (*pdecomps)[i].code = code;
+ (*pdecomps)[i].used = dectmp_size;
+ (void) AC_MEMCPY((char *) (*pdecomps)[i].decomp, (char *) dectmp,
sizeof(unsigned long) * dectmp_size);
/*
* NOTICE: This needs changing later so it is more general than simply
* pairs. This calculation is done here to simplify allocation elsewhere.
*/
- if (dectmp_size == 2)
+ if (!compat && dectmp_size == 2)
comps_used++;
}
read_cdata(FILE *in)
{
unsigned long i, lineno, skip, code, ccl_code;
- short wnum, neg, number[2];
+ short wnum, neg, number[2], compat;
char line[512], *s, *e;
lineno = skip = 0;
* Check for a decomposition.
*/
s = ++e;
- if (*s != ';' && *s != '<') {
+ if (*s != ';') {
+ compat = *s == '<';
+ if (compat) {
+ /*
+ * Skip compatibility formatting tag.
+ */
+ while (*s++ != '>');
+ }
/*
* Collect the codes of the decomposition.
*/
* Skip all leading non-hex digits.
*/
while (!ishdigit(*s))
- s++;
+ s++;
for (dectmp[dectmp_size] = 0; ishdigit(*s); s++) {
dectmp[dectmp_size] <<= 4;
* If there are any codes in the temporary decomposition array,
* then add the character with its decomposition.
*/
- if (dectmp_size > 0)
- add_decomp(code);
+ if (dectmp_size > 0) {
+ if (!compat) {
+ add_decomp(code, 0);
+ }
+ add_decomp(code, 1);
+ }
}
/*
}
static _decomp_t *
-find_decomp(unsigned long code)
+find_decomp(unsigned long code, short compat)
{
long l, r, m;
-
+ _decomp_t *decs;
+
l = 0;
- r = decomps_used - 1;
+ r = (compat ? kdecomps_used : decomps_used) - 1;
+ decs = compat ? kdecomps : decomps;
while (l <= r) {
m = (l + r) >> 1;
- if (code > decomps[m].code)
+ if (code > decs[m].code)
l = m + 1;
- else if (code < decomps[m].code)
+ else if (code < decs[m].code)
r = m - 1;
else
- return &decomps[m];
+ return &decs[m];
}
return 0;
}
static void
-decomp_it(_decomp_t *d)
+decomp_it(_decomp_t *d, short compat)
{
unsigned long i;
_decomp_t *dp;
for (i = 0; i < d->used; i++) {
- if ((dp = find_decomp(d->decomp[i])) != 0)
- decomp_it(dp);
+ if ((dp = find_decomp(d->decomp[i], compat)) != 0)
+ decomp_it(dp, compat);
else
dectmp[dectmp_size++] = d->decomp[i];
}
for (i = 0; i < decomps_used; i++) {
dectmp_size = 0;
- decomp_it(&decomps[i]);
+ decomp_it(&decomps[i], 0);
if (dectmp_size > 0)
- add_decomp(decomps[i].code);
+ add_decomp(decomps[i].code, 0);
+ }
+
+ for (i = 0; i < kdecomps_used; i++) {
+ dectmp_size = 0;
+ decomp_it(&kdecomps[i], 1);
+ if (dectmp_size > 0)
+ add_decomp(kdecomps[i].code, 1);
}
}
fclose(out);
}
+ /*
+ * Open the kdecomp.dat file.
+ */
+ sprintf(path, "%s%skdecomp.dat", opath, LDAP_DIRSEP);
+ if ((out = fopen(path, "wb")) == 0)
+ return;
+
+ hdr[1] = kdecomps_used;
+
+ /*
+ * Write the header.
+ */
+ fwrite((char *) hdr, sizeof(unsigned short), 2, out);
+
+ /*
+ * Write a temporary byte count which will be calculated as the
+ * decompositions are written out.
+ */
+ bytes = 0;
+ fwrite((char *) &bytes, sizeof(unsigned long), 1, out);
+
+ if (kdecomps_used) {
+ /*
+ * Write the list of kdecomp nodes.
+ */
+ for (i = idx = 0; i < kdecomps_used; i++) {
+ fwrite((char *) &kdecomps[i].code, sizeof(unsigned long), 1, out);
+ fwrite((char *) &idx, sizeof(unsigned long), 1, out);
+ idx += kdecomps[i].used;
+ }
+
+ /*
+ * Write the sentinel index as the last decomp node.
+ */
+ fwrite((char *) &idx, sizeof(unsigned long), 1, out);
+
+ /*
+ * Write the decompositions themselves.
+ */
+ for (i = 0; i < kdecomps_used; i++)
+ fwrite((char *) kdecomps[i].decomp, sizeof(unsigned long),
+ kdecomps[i].used, out);
+
+ /*
+ * Seek back to the beginning and write the byte count.
+ */
+ bytes = (sizeof(unsigned long) * idx) +
+ (sizeof(unsigned long) * ((hdr[1] << 1) + 1));
+ fseek(out, sizeof(unsigned short) << 1, 0L);
+ fwrite((char *) &bytes, sizeof(unsigned long), 1, out);
+
+ fclose(out);
+ }
+
/*****************************************************************
*
* Generate the combining class data.
p++;
}
/* normalize ucs of length p - ucs */
- uccanondecomp( ucs, p - ucs, &ucsout, &ucsoutlen );
+ uccompatdecomp( ucs, p - ucs, &ucsout, &ucsoutlen );
if ( approx ) {
for ( j = 0; j < ucsoutlen; j++ ) {
if ( ucsout[j] < 0x80 ) {
return l1 > l2 ? 1 : -1; /* what to do??? */
}
} else {
- uccanondecomp( ucs, ulen, &ucsout1, &l1 );
+ uccompatdecomp( ucs, ulen, &ucsout1, &l1 );
l1 = uccanoncomp( ucsout1, l1 );
}
ucsout2 = ucs;
l2 = ulen;
} else {
- uccanondecomp( ucs, ulen, &ucsout2, &l2 );
+ uccompatdecomp( ucs, ulen, &ucsout2, &l2 );
l2 = uccanoncomp( ucsout2, l2 );
free( ucs );
}
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
if( txn != NULL ) {
boi->boi_err = rc;
}
- return LDAP_OTHER;
+ return (rc != LDAP_BUSY) ? LDAP_OTHER : LDAP_BUSY;
}
if (e == NULL) {
#ifdef NEW_LOGGING
#define bv2DBT(bv,t) ((t)->data = (bv)->bv_val, \
(t)->size = (bv)->bv_len )
-#define BDB_TXN_RETRIES 16
+#define BDB_TXN_RETRIES 16
+
+#define BDB_MAX_ADD_LOOP 30
#ifdef BDB_SUBDIRS
#define BDB_TMP_SUBDIR LDAP_DIRSEP "tmp"
case DB_NOTFOUND:
case 0:
break;
+ case LDAP_BUSY:
+ send_ldap_result( conn, op, LDAP_BUSY,
+ NULL, "ldap server busy", NULL, NULL );
+ return LDAP_BUSY;
default:
send_ldap_result( conn, op, rc=LDAP_OTHER,
NULL, "internal error", NULL, NULL );
case DB_NOTFOUND:
case 0:
break;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
--- /dev/null
+/* id2entry.c - routines to deal with the id2entry database */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/string.h>
+
+#include "back-bdb.h"
+
+int bdb_id2entry_put(
+ BackendDB *be,
+ DB_TXN *tid,
+ Entry *e,
+ int flag )
+{
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+ DB *db = bdb->bi_id2entry->bdi_db;
+ DBT key, data;
+ struct berval bv;
+ int rc;
+#ifdef BDB_HIER
+ char *odn, *ondn;
+
+ /* We only store rdns, and they go in the id2parent database. */
+
+ odn = e->e_dn; ondn = e->e_ndn;
+
+ e->e_dn = ""; e->e_ndn = "";
+#endif
+ DBTzero( &key );
+ key.data = (char *) &e->e_id;
+ key.size = sizeof(ID);
+
+ rc = entry_encode( e, &bv );
+#ifdef BDB_HIER
+ e->e_dn = odn; e->e_ndn = ondn;
+#endif
+ if( rc != LDAP_SUCCESS ) {
+ return -1;
+ }
+
+ DBTzero( &data );
+ bv2DBT( &bv, &data );
+
+ rc = db->put( db, tid, &key, &data, flag );
+
+ free( bv.bv_val );
+ return rc;
+}
+
+/*
+ * This routine adds (or updates) an entry on disk.
+ * The cache should be already be updated.
+ */
+
+
+int bdb_id2entry_add(
+ BackendDB *be,
+ DB_TXN *tid,
+ Entry *e )
+{
+ return bdb_id2entry_put(be, tid, e, DB_NOOVERWRITE);
+}
+
+int bdb_id2entry_update(
+ BackendDB *be,
+ DB_TXN *tid,
+ Entry *e )
+{
+ return bdb_id2entry_put(be, tid, e, 0);
+}
+
+int bdb_id2entry_rw(
+ BackendDB *be,
+ DB_TXN *tid,
+ ID id,
+ Entry **e,
+ int rw )
+{
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+ DB *db = bdb->bi_id2entry->bdi_db;
+ DBT key, data;
+ struct berval bv;
+ int rc = 0;
+
+ *e = NULL;
+
+ DBTzero( &key );
+ key.data = (char *) &id;
+ key.size = sizeof(ID);
+
+ DBTzero( &data );
+ data.flags = DB_DBT_MALLOC;
+
+ if ((*e = bdb_cache_find_entry_id(&bdb->bi_cache, id, rw)) != NULL) {
+ return 0;
+ }
+
+ /* fetch it */
+ rc = db->get( db, tid, &key, &data, bdb->bi_db_opflags );
+
+ if( rc != 0 ) {
+ return rc;
+ }
+
+ DBT2bv( &data, &bv );
+
+ rc = entry_decode( &bv, e );
+
+ if( rc == 0 ) {
+ (*e)->e_id = id;
+ } else {
+ /* only free on error. On success, the entry was
+ * decoded in place.
+ */
+ ch_free( data.data );
+ }
+
+ while (rc == 0 && bdb_cache_add_entry_rw(&bdb->bi_cache, *e, rw) != 0) {
+ Entry *ee;
+ int add_loop_cnt = 0;
+ if ( (*e)->e_private != NULL ) {
+ free ((*e)->e_private);
+ }
+ (*e)->e_private = NULL;
+ if ( (ee = bdb_cache_find_entry_id
+ (&bdb->bi_cache, id, rw) ) != NULL) {
+ bdb_entry_return ( *e );
+ *e = ee;
+ return 0;
+ }
+ if ( ++add_loop_cnt == BDB_MAX_ADD_LOOP ) {
+ bdb_entry_return ( *e );
+ *e = NULL;
+ return LDAP_BUSY;
+ }
+ }
+
+#ifdef BDB_HIER
+ bdb_fix_dn(be, id, *e);
+#endif
+
+ if (rc == 0) {
+ bdb_cache_entry_commit(*e);
+ }
+
+ return rc;
+}
+
+int bdb_id2entry_delete(
+ BackendDB *be,
+ DB_TXN *tid,
+ Entry *e )
+{
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+ DB *db = bdb->bi_id2entry->bdi_db;
+ DBT key;
+ int rc;
+
+ bdb_cache_delete_entry(&bdb->bi_cache, e);
+
+ DBTzero( &key );
+ key.data = (char *) &e->e_id;
+ key.size = sizeof(ID);
+
+ /* delete from database */
+ rc = db->del( db, tid, &key, 0 );
+
+ return rc;
+}
+
+int bdb_entry_return(
+ Entry *e )
+{
+ /* Our entries are allocated in two blocks; the data comes from
+ * the db itself and the Entry structure and associated pointers
+ * are allocated in entry_decode. The db data pointer is saved
+ * in e_bv. Since the Entry structure is allocated as a single
+ * block, e_attrs is always a fixed offset from e. The exception
+ * is when an entry has been modified, in which case we also need
+ * to free e_attrs.
+ */
+ if( !e->e_bv.bv_val ) { /* A regular entry, from do_add */
+ entry_free( e );
+ return 0;
+ }
+ if( (void *) e->e_attrs != (void *) (e+1)) {
+ attrs_free( e->e_attrs );
+ }
+
+ /* See if the DNs were changed by modrdn */
+ if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val >
+ e->e_bv.bv_val + e->e_bv.bv_len ) {
+ ch_free(e->e_name.bv_val);
+ ch_free(e->e_nname.bv_val);
+ e->e_name.bv_val = NULL;
+ e->e_nname.bv_val = NULL;
+ }
+#ifdef BDB_HIER
+ /* We had to construct the dn and ndn as well, in a single block */
+ if( e->e_name.bv_val ) {
+ free( e->e_name.bv_val );
+ }
+#endif
+ /* In tool mode the e_bv buffer is realloc'd, leave it alone */
+ if( !(slapMode & SLAP_TOOL_MODE) ) {
+ free( e->e_bv.bv_val );
+ }
+
+ free( e );
+
+ return 0;
+}
+
+int bdb_entry_release(
+ BackendDB *be,
+ Connection *c,
+ Operation *o,
+ Entry *e,
+ int rw )
+{
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+
+ /* slapMode : SLAP_SERVER_MODE, SLAP_TOOL_MODE,
+ SLAP_TRUNCATE_MODE, SLAP_UNDEFINED_MODE */
+
+ if ( slapMode == SLAP_SERVER_MODE ) {
+ /* free entry and reader or writer lock */
+ bdb_cache_return_entry_rw( &bdb->bi_cache, e, rw );
+ } else {
+ if (e->e_private != NULL)
+ free (e->e_private);
+ e->e_private = NULL;
+ bdb_entry_return ( e );
+ }
+
+ return 0;
+}
goto retry;
case DB_NOTFOUND:
break;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
}
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
case DB_NOTFOUND:
case 0:
break;
+ case LDAP_BUSY:
+ *text = "ldap server busy";
+ goto done;
default:
rc = LDAP_OTHER;
*text = "internal error";
rc = 0;
case 0:
break;
+ case LDAP_BUSY:
+ if (e != NULL) {
+ bdb_cache_return_entry_r(&bdb->bi_cache, e);
+ }
+ if (matched != NULL) {
+ bdb_cache_return_entry_r(&bdb->bi_cache, matched);
+ }
+ send_ldap_result( conn, op, LDAP_BUSY,
+ NULL, "ldap server busy", NULL, NULL );
+ return LDAP_BUSY;
default:
#ifdef NEW_LOGGING
LDAP_LOG (( "referral", LDAP_LEVEL_ERR,
case DB_NOTFOUND:
case 0:
break;
+ case LDAP_BUSY:
+ if (e != NULL) {
+ bdb_cache_return_entry_r(&bdb->bi_cache, e);
+ }
+ if (matched != NULL) {
+ bdb_cache_return_entry_r(&bdb->bi_cache, matched);
+ }
+ send_ldap_result( conn, op, LDAP_BUSY,
+ NULL, "ldap server busy", NULL, NULL );
+ return LDAP_BUSY;
default:
if (e != NULL) {
bdb_cache_return_entry_r(&bdb->bi_cache, e);
/* get the entry with reader lock */
rc = bdb_id2entry_r( be, NULL, id, &e );
+ if (rc == LDAP_BUSY) {
+ send_ldap_result( conn, op, rc=LDAP_BUSY,
+ NULL, "ldap server busy", NULL, NULL );
+ goto done;
+ }
+
if ( e == NULL ) {
if( !BDB_IDL_IS_RANGE(candidates) ) {
/* only complain for non-range IDLs */
char *slapd_pid_file = NULL;
char *slapd_args_file = NULL;
+char *strtok_quote_ptr;
+
int nSaslRegexp = 0;
SaslRegexp_t *SaslRegexp = NULL;
{
char * token;
char * logline;
+ char logbuf[sizeof("pseudorootpw ***")];
*argcp = 0;
token = strtok_quote( line, " \t" );
- logline = (!token || strcasecmp(token, "rootpw") ? line : "rootpw *");
+ logline = line;
+ if ( token &&
+ (strcasecmp( token, "rootpw" ) == 0 ||
+ strcasecmp( token, "replica" ) == 0 || /* contains "credentials" */
+ strcasecmp( token, "bindpw" ) == 0 || /* used in back-ldap */
+ strcasecmp( token, "pseudorootpw" ) == 0 || /* used in back-meta */
+ strcasecmp( token, "dbpasswd" ) == 0 ) ) /* used in back-sql */
+ sprintf( logline = logbuf, "%s ***", token );
+ if ( strtok_quote_ptr )
+ *strtok_quote_ptr = ' ';
#ifdef NEW_LOGGING
LDAP_LOG(( "config", LDAP_LEVEL_DETAIL1,
"line %d (%s)\n", lineno, logline ));
#else
Debug( LDAP_DEBUG_CONFIG, "line %d (%s)\n", lineno, logline, 0 );
#endif
+ if ( strtok_quote_ptr )
+ *strtok_quote_ptr = '\0';
for ( ; token != NULL; token = strtok_quote( NULL, " \t" ) ) {
if ( *argcp == MAXARGS ) {
char *tmp;
static char *next;
+ strtok_quote_ptr = NULL;
if ( line != NULL ) {
next = line;
}
default:
if ( ! inquote ) {
if ( strchr( sep, *next ) != NULL ) {
+ strtok_quote_ptr = next;
*next++ = '\0';
return( tmp );
}
return( strcmp( dn->bv_val + d, suffix->bv_val ) == 0 );
}
+#ifdef HAVE_TLS
/*
* Convert an X.509 DN into a normalized LDAP DN
*/
{
return ldap_pvt_tls_get_peer_dn( ssl, (LDAPDN_rewrite_dummy *)LDAPDN_rewrite, 0 );
}
+#endif