Browse Source

591336 - Implementing upgrade DN format tool

Change description:
. adding upgradednformat utility to each server instance.
. adding 91upgradednformat.pl for in-place-upgrade.
. implementing ldbm_back_upgradednformat sharing the import/
  reincexing codes.
. adding a new DBVERSION ID "dn-4514" for the upgraded db.
. fixing access logs (delete.c and modify.c)
. fixing compiler warnings.
. fixing memory leaks.
. fixing a bug in syntax plugin to free strings.
. adding templates for plugin id, version, vendor, and description,
  which are needed for the online upgrade.
. dbversion_write takes an additional bit flags, which indicates
  which extra DBVERSION strings are written to the DBVERSION file.
  It was introduced for the upgrade tools not to intervene each
  other's tasks (e.g., dn2rdn for converting entrydn to entryrdn
  and upgradednformat for upgrading the DN format).
. fixing a bug in entryrdn index code which was missing to normalize
  RDN.

See also:
https://bugzilla.redhat.com/show_bug.cgi?id=591336
http://directory.fedoraproject.org/wiki/Upgrade_to_New_DN_Format#Migration.2FUpgrade
Noriko Hosoi 15 years ago
parent
commit
c12c48f47a
40 changed files with 4601 additions and 8073 deletions
  1. 6 1
      Makefile.am
  2. 258 169
      Makefile.in
  3. 10 6401
      aclocal.m4
  4. 11 10
      compile
  5. 170 132
      config.guess
  6. 5 1
      config.h.in
  7. 179 53
      config.sub
  8. 578 257
      configure
  9. 136 36
      depcomp
  10. 357 160
      install-sh
  11. 5 0
      ldap/admin/src/scripts/50smd5pwdstorageplugin.ldif
  12. 145 0
      ldap/admin/src/scripts/91upgradednformat.pl
  13. 7 0
      ldap/admin/src/scripts/setup-ds.res.in
  14. 56 0
      ldap/admin/src/scripts/template-upgradednformat.in
  15. 5 1
      ldap/ldif/template-bitwise.ldif.in
  16. 21 16
      ldap/servers/plugins/syntaxes/string.c
  17. 8 1
      ldap/servers/slapd/back-ldbm/back-ldbm.h
  18. 38 34
      ldap/servers/slapd/back-ldbm/dblayer.c
  19. 21 26
      ldap/servers/slapd/back-ldbm/dbversion.c
  20. 747 33
      ldap/servers/slapd/back-ldbm/import-threads.c
  21. 220 118
      ldap/servers/slapd/back-ldbm/import.c
  22. 11 7
      ldap/servers/slapd/back-ldbm/import.h
  23. 2 0
      ldap/servers/slapd/back-ldbm/init.c
  24. 28 4
      ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
  25. 229 8
      ldap/servers/slapd/back-ldbm/ldif2ldbm.c
  26. 96 0
      ldap/servers/slapd/back-ldbm/misc.c
  27. 4 2
      ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
  28. 1 1
      ldap/servers/slapd/back-ldbm/start.c
  29. 1 1
      ldap/servers/slapd/delete.c
  30. 11 1
      ldap/servers/slapd/dn.c
  31. 113 4
      ldap/servers/slapd/main.c
  32. 14 0
      ldap/servers/slapd/mapping_tree.c
  33. 1 1
      ldap/servers/slapd/modify.c
  34. 12 0
      ldap/servers/slapd/pblock.c
  35. 9 0
      ldap/servers/slapd/protect_db.c
  36. 2 0
      ldap/servers/slapd/protect_db.h
  37. 4 0
      ldap/servers/slapd/slap.h
  38. 10 5
      ldap/servers/slapd/slapi-private.h
  39. 1010 546
      ltmain.sh
  40. 60 44
      missing

+ 6 - 1
Makefile.am

@@ -93,7 +93,10 @@ CLEANFILES =  dberrstrs.h ns-slapd.properties \
 	ldap/admin/src/scripts/template-restart-slapd ldap/admin/src/scripts/template-restoreconfig \
 	ldap/admin/src/scripts/template-saveconfig ldap/admin/src/scripts/template-start-slapd \
 	ldap/admin/src/scripts/template-stop-slapd ldap/admin/src/scripts/template-suffix2instance \
-	ldap/admin/src/scripts/template-upgradedb ldap/admin/src/scripts/template-verify-db.pl \
+	ldap/admin/src/scripts/template-upgradedb \
+	ldap/admin/src/scripts/template-upgradednformat \
+	ldap/admin/src/scripts/template-usn-tombstone-cleanup.pl \
+	ldap/admin/src/scripts/template-verify-db.pl \
 	ldap/admin/src/scripts/template-vlvindex ldap/admin/src/scripts/DSUtil.pm \
 	ldap/ldif/template-baseacis.ldif ldap/ldif/template-bitwise.ldif ldap/ldif/template-country.ldif \
 	ldap/ldif/template-dnaplugin.ldif ldap/ldif/template-domain.ldif ldap/ldif/template-dse.ldif \
@@ -336,6 +339,7 @@ task_SCRIPTS = ldap/admin/src/scripts/template-bak2db \
 	ldap/admin/src/scripts/template-start-slapd \
 	ldap/admin/src/scripts/template-stop-slapd \
 	ldap/admin/src/scripts/template-suffix2instance \
+	ldap/admin/src/scripts/template-upgradednformat \
 	ldap/admin/src/scripts/template-vlvindex \
 	ldap/admin/src/scripts/template-bak2db.pl \
 	ldap/admin/src/scripts/template-db2bak.pl \
@@ -435,6 +439,7 @@ update_DATA = ldap/admin/src/scripts/exampleupdate.pl \
 	ldap/admin/src/scripts/50retroclprecedence.ldif \
 	ldap/admin/src/scripts/60upgradeschemafiles.pl \
 	ldap/admin/src/scripts/90subtreerename.pl \
+	ldap/admin/src/scripts/91upgradednformat.pl \
 	ldap/admin/src/scripts/dnaplugindepends.ldif
 
 update_SCRIPTS = ldap/admin/src/scripts/exampleupdate.sh

File diff suppressed because it is too large
+ 258 - 169
Makefile.in


File diff suppressed because it is too large
+ 10 - 6401
aclocal.m4


+ 11 - 10
compile

@@ -1,9 +1,10 @@
 #! /bin/sh
 # Wrapper for compilers which do not understand `-c -o'.
 
-scriptversion=2005-05-14.22
+scriptversion=2009-10-06.20; # UTC
 
-# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009  Free Software
+# Foundation, Inc.
 # Written by Tom Tromey <[email protected]>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -17,8 +18,7 @@ scriptversion=2005-05-14.22
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -103,13 +103,13 @@ if test -z "$ofile" || test -z "$cfile"; then
 fi
 
 # Name of file we expect compiler to create.
-cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
 
 # Create the lock directory.
-# Note: use `[/.-]' here to ensure that we don't use the same name
+# Note: use `[/\\:.-]' here to ensure that we don't use the same name
 # that we are using for the .o file.  Also, base the name on the expected
 # object file name, since that is what matters with a parallel build.
-lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
 while true; do
   if mkdir "$lockdir" >/dev/null 2>&1; then
     break
@@ -124,9 +124,9 @@ trap "rmdir '$lockdir'; exit 1" 1 2 15
 ret=$?
 
 if test -f "$cofile"; then
-  mv "$cofile" "$ofile"
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
 elif test -f "${cofile}bj"; then
-  mv "${cofile}bj" "$ofile"
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
 fi
 
 rmdir "$lockdir"
@@ -138,5 +138,6 @@ exit $ret
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
 # End:

+ 170 - 132
config.guess

@@ -1,9 +1,10 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
 
-timestamp='2005-07-08'
+timestamp='2009-11-20'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -26,16 +27,16 @@ timestamp='2005-07-08'
 # the same distribution terms that you use for the rest of that program.
 
 
-# Originally written by Per Bothner <[email protected]>.
-# Please send patches to <[email protected]>.  Submit a context
-# diff and a properly formatted ChangeLog entry.
+# Originally written by Per Bothner.  Please send patches (context
+# diff format) to <[email protected]> and include a ChangeLog
+# entry.
 #
 # This script attempts to guess a canonical system name similar to
 # config.sub.  If it succeeds, it prints the system name on stdout, and
 # exits with 0.  Otherwise, it exits with 1.
 #
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
 
 me=`echo "$0" | sed -e 's,.*/,,'`
 
@@ -55,8 +56,8 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -106,7 +107,7 @@ set_cc_for_build='
 trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
 trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
 : ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
  { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
  { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
  { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
@@ -160,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	    arm*) machine=arm-unknown ;;
 	    sh3el) machine=shl-unknown ;;
 	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
 	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
 	esac
 	# The Operating System including object format, if it has switched
@@ -168,7 +170,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
 		eval $set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
-			| grep __ELF__ >/dev/null
+			| grep -q __ELF__
 		then
 		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
 		    # Return netbsd for either.  FIX?
@@ -206,8 +208,11 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:ekkoBSD:*:*)
 	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
 	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
     macppc:MirBSD:*:*)
-	echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
 	exit ;;
     *:MirBSD:*:*)
 	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
@@ -319,14 +324,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	case `/usr/bin/uname -p` in
 	    sparc) echo sparc-icl-nx7; exit ;;
 	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
     sun4H:SunOS:5.*:*)
 	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 	exit ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
 	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 	exit ;;
-    i86pc:SunOS:5.*:*)
-	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 	exit ;;
     sun4*:SunOS:6*:*)
 	# According to config.sub, this is the proper way to canonicalize
@@ -527,7 +551,7 @@ EOF
 		echo rs6000-ibm-aix3.2
 	fi
 	exit ;;
-    *:AIX:*:[45])
+    *:AIX:*:[456])
 	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
 	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
 		IBM_ARCH=rs6000
@@ -635,7 +659,7 @@ EOF
 	    # => hppa64-hp-hpux11.23
 
 	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
-		grep __LP64__ >/dev/null
+		grep -q __LP64__
 	    then
 		HP_ARCH="hppa2.0w"
 	    else
@@ -764,12 +788,19 @@ EOF
 	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
 	exit ;;
     *:FreeBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
 	exit ;;
     i*:CYGWIN*:*)
 	echo ${UNAME_MACHINE}-pc-cygwin
 	exit ;;
-    i*:MINGW*:*)
+    *:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit ;;
     i*:windows32*:*)
@@ -779,12 +810,24 @@ EOF
     i*:PW*:*)
 	echo ${UNAME_MACHINE}-pc-pw32
 	exit ;;
-    x86:Interix*:[34]*)
-	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
-	exit ;;
+    *:Interix*:*)
+    	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
     [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
 	echo i${UNAME_MACHINE}-pc-mks
 	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
     i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
 	# How do we know it's Interix rather than the generic POSIX subsystem?
 	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
@@ -794,7 +837,7 @@ EOF
     i*:UWIN*:*)
 	echo ${UNAME_MACHINE}-pc-uwin
 	exit ;;
-    amd64:CYGWIN*:*:*)
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
 	echo x86_64-unknown-cygwin
 	exit ;;
     p*:CYGWIN*:*)
@@ -814,7 +857,31 @@ EOF
     i*86:Minix:*:*)
 	echo ${UNAME_MACHINE}-pc-minix
 	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
     arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-gnu
+	else
+	    echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
     cris:Linux:*:*)
@@ -826,6 +893,17 @@ EOF
     frv:Linux:*:*)
     	echo frv-unknown-linux-gnu
 	exit ;;
+    i*86:Linux:*:*)
+	LIBC=gnu
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+	exit ;;
     ia64:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
@@ -835,63 +913,33 @@ EOF
     m68*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
-    mips:Linux:*:*)
-	eval $set_cc_for_build
-	sed 's/^	//' << EOF >$dummy.c
-	#undef CPU
-	#undef mips
-	#undef mipsel
-	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	CPU=mipsel
-	#else
-	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	CPU=mips
-	#else
-	CPU=
-	#endif
-	#endif
-EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
-	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
-	;;
-    mips64:Linux:*:*)
+    mips:Linux:*:* | mips64:Linux:*:*)
 	eval $set_cc_for_build
 	sed 's/^	//' << EOF >$dummy.c
 	#undef CPU
-	#undef mips64
-	#undef mips64el
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
 	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	CPU=mips64el
+	CPU=${UNAME_MACHINE}el
 	#else
 	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	CPU=mips64
+	CPU=${UNAME_MACHINE}
 	#else
 	CPU=
 	#endif
 	#endif
 EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
 	;;
-    ppc:Linux:*:*)
-	echo powerpc-unknown-linux-gnu
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
 	exit ;;
-    ppc64:Linux:*:*)
-	echo powerpc64-unknown-linux-gnu
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-gnu
 	exit ;;
-    alpha:Linux:*:*)
-	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
-	  EV5)   UNAME_MACHINE=alphaev5 ;;
-	  EV56)  UNAME_MACHINE=alphaev56 ;;
-	  PCA56) UNAME_MACHINE=alphapca56 ;;
-	  PCA57) UNAME_MACHINE=alphapca56 ;;
-	  EV6)   UNAME_MACHINE=alphaev6 ;;
-	  EV67)  UNAME_MACHINE=alphaev67 ;;
-	  EV68*) UNAME_MACHINE=alphaev68 ;;
-        esac
-	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
-	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
-	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
 	exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
 	# Look for CPU level
@@ -901,8 +949,11 @@ EOF
 	  *)    echo hppa-unknown-linux-gnu ;;
 	esac
 	exit ;;
-    parisc64:Linux:*:* | hppa64:Linux:*:*)
-	echo hppa64-unknown-linux-gnu
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
 	exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
 	echo ${UNAME_MACHINE}-ibm-linux
@@ -916,68 +967,15 @@ EOF
     sparc:Linux:*:* | sparc64:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
 	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
     x86_64:Linux:*:*)
 	echo x86_64-unknown-linux-gnu
 	exit ;;
-    i*86:Linux:*:*)
-	# The BFD linker knows what the default object file format is, so
-	# first see if it will tell us. cd to the root directory to prevent
-	# problems with other programs or directories called `ld' in the path.
-	# Set LC_ALL=C to ensure ld outputs messages in English.
-	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
-			 | sed -ne '/supported targets:/!d
-				    s/[ 	][ 	]*/ /g
-				    s/.*supported targets: *//
-				    s/ .*//
-				    p'`
-        case "$ld_supported_targets" in
-	  elf32-i386)
-		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
-		;;
-	  a.out-i386-linux)
-		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
-		exit ;;
-	  coff-i386)
-		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
-		exit ;;
-	  "")
-		# Either a pre-BFD a.out linker (linux-gnuoldld) or
-		# one that does not give us useful --help.
-		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
-		exit ;;
-	esac
-	# Determine whether the default compiler is a.out or elf
-	eval $set_cc_for_build
-	sed 's/^	//' << EOF >$dummy.c
-	#include <features.h>
-	#ifdef __ELF__
-	# ifdef __GLIBC__
-	#  if __GLIBC__ >= 2
-	LIBC=gnu
-	#  else
-	LIBC=gnulibc1
-	#  endif
-	# else
-	LIBC=gnulibc1
-	# endif
-	#else
-	#ifdef __INTEL_COMPILER
-	LIBC=gnu
-	#else
-	LIBC=gnuaout
-	#endif
-	#endif
-	#ifdef __dietlibc__
-	LIBC=dietlibc
-	#endif
-EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
-	test x"${LIBC}" != x && {
-		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
-		exit
-	}
-	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
-	;;
+    xtensa*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
     i*86:DYNIX/ptx:4*:*)
 	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
 	# earlier versions are messed up and put the nodename in both
@@ -1006,7 +1004,7 @@ EOF
     i*86:syllable:*:*)
 	echo ${UNAME_MACHINE}-pc-syllable
 	exit ;;
-    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
 	echo i386-unknown-lynxos${UNAME_RELEASE}
 	exit ;;
     i*86:*DOS:*:*)
@@ -1050,8 +1048,11 @@ EOF
     pc:*:*:*)
 	# Left here for compatibility:
         # uname -m prints for DJGPP always 'pc', but it prints nothing about
-        # the processor, so we play safe by assuming i386.
-	echo i386-pc-msdosdjgpp
+        # the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
         exit ;;
     Intel:Mach:3*:*)
 	echo i386-pc-mach3
@@ -1089,6 +1090,16 @@ EOF
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
         /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
           && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
     m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
 	echo m68k-unknown-lynxos${UNAME_RELEASE}
 	exit ;;
@@ -1101,7 +1112,7 @@ EOF
     rs6000:LynxOS:2.*:*)
 	echo rs6000-unknown-lynxos${UNAME_RELEASE}
 	exit ;;
-    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
 	echo powerpc-unknown-lynxos${UNAME_RELEASE}
 	exit ;;
     SM[BE]S:UNIX_SV:*:*)
@@ -1164,6 +1175,9 @@ EOF
     BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
 	echo i586-pc-beos
 	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
     SX-4:SUPER-UX:*:*)
 	echo sx4-nec-superux${UNAME_RELEASE}
 	exit ;;
@@ -1173,6 +1187,15 @@ EOF
     SX-6:SUPER-UX:*:*)
 	echo sx6-nec-superux${UNAME_RELEASE}
 	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
     Power*:Rhapsody:*:*)
 	echo powerpc-apple-rhapsody${UNAME_RELEASE}
 	exit ;;
@@ -1182,7 +1205,16 @@ EOF
     *:Darwin:*:*)
 	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
 	case $UNAME_PROCESSOR in
-	    *86) UNAME_PROCESSOR=i686 ;;
+	    i386)
+		eval $set_cc_for_build
+		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		      grep IS_64BIT_ARCH >/dev/null
+		  then
+		      UNAME_PROCESSOR="x86_64"
+		  fi
+		fi ;;
 	    unknown) UNAME_PROCESSOR=powerpc ;;
 	esac
 	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
@@ -1261,6 +1293,12 @@ EOF
     i*86:skyos:*:*)
 	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
 	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
 esac
 
 #echo '(No uname command or uname output not recognized.)' 1>&2
@@ -1421,9 +1459,9 @@ This script, last modified $timestamp, has failed to recognize
 the operating system you are using. It is advised that you
 download the most up to date version of the config scripts from
 
-  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
 and
-  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
 
 If the version you run ($0) is already up to date, please
 send the following data and any information you think might be

+ 5 - 1
config.h.in

@@ -321,6 +321,10 @@
    slash. */
 #undef LSTAT_FOLLOWS_SLASHED_SYMLINK
 
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
 /* Linux */
 #undef Linux
 
@@ -432,7 +436,7 @@
 /* Define to `int' if <sys/types.h> does not define. */
 #undef pid_t
 
-/* Define to `unsigned' if <sys/types.h> does not define. */
+/* Define to `unsigned int' if <sys/types.h> does not define. */
 #undef size_t
 
 /* SunOS5 */

+ 179 - 53
config.sub

@@ -1,9 +1,10 @@
 #! /bin/sh
 # Configuration validation subroutine script.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
 
-timestamp='2005-07-08'
+timestamp='2009-11-20'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -31,13 +32,16 @@ timestamp='2005-07-08'
 
 
 # Please send patches to <[email protected]>.  Submit a context
-# diff and a properly formatted ChangeLog entry.
+# diff and a properly formatted GNU ChangeLog entry.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
 # Supply the specified configuration type as an argument.
 # If it is invalid, we print an error message on stderr and exit with code 1.
 # Otherwise, we print the canonical config type on stdout and succeed.
 
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
 # This file is supposed to be the same for all GNU packages
 # and recognize all the CPU types, system types and aliases
 # that are meaningful with *any* GNU software.
@@ -71,8 +75,8 @@ Report bugs and patches to <[email protected]>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -119,8 +123,10 @@ esac
 # Here we must recognize all the valid KERNEL-OS combinations.
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
-  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
     ;;
@@ -146,10 +152,13 @@ case $os in
 	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
 	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
 	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-	-apple | -axis | -knuth | -cray)
+	-apple | -axis | -knuth | -cray | -microblaze)
 		os=
 		basic_machine=$1
 		;;
+        -bluegene*)
+	        os=-cnk
+		;;
 	-sim | -cisco | -oki | -wec | -winbond)
 		os=
 		basic_machine=$1
@@ -171,6 +180,10 @@ case $os in
 	-hiux*)
 		os=-hiuxwe2
 		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
 	-sco5)
 		os=-sco3.2v5
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -187,6 +200,10 @@ case $os in
 		# Don't forget version if it is 3.2v4 or newer.
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
 	-sco*)
 		os=-sco3.2v2
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -231,20 +248,24 @@ case $basic_machine in
 	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
 	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
 	| am33_2.0 \
-	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
 	| bfin \
 	| c4x | clipper \
 	| d10v | d30v | dlx | dsp16xx \
-	| fr30 | frv \
+	| fido | fr30 | frv \
 	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 	| i370 | i860 | i960 | ia64 \
 	| ip2k | iq2000 \
-	| m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
 	| mips | mipsbe | mipseb | mipsel | mipsle \
 	| mips16 \
 	| mips64 | mips64el \
-	| mips64vr | mips64vrel \
+	| mips64octeon | mips64octeonel \
 	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
 	| mips64vr4100 | mips64vr4100el \
 	| mips64vr4300 | mips64vr4300el \
 	| mips64vr5000 | mips64vr5000el \
@@ -257,35 +278,40 @@ case $basic_machine in
 	| mipsisa64sr71k | mipsisa64sr71kel \
 	| mipstx39 | mipstx39el \
 	| mn10200 | mn10300 \
-	| ms1 \
+	| moxie \
+	| mt \
 	| msp430 \
+	| nios | nios2 \
 	| ns16k | ns32k \
 	| or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
 	| pyramid \
-	| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
 	| sh64 | sh64le \
-	| sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
-	| sparcv8 | sparcv9 | sparcv9b \
-	| strongarm \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
 	| tahoe | thumb | tic4x | tic80 | tron \
+	| ubicom32 \
 	| v850 | v850e \
 	| we32k \
-	| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
-	| z8k)
-		basic_machine=$basic_machine-unknown
-		;;
-	m32c)
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k | z80)
 		basic_machine=$basic_machine-unknown
 		;;
-	m6811 | m68hc11 | m6812 | m68hc12)
+	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
 		# Motorola 68HC11/12.
 		basic_machine=$basic_machine-unknown
 		os=-none
 		;;
 	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
 		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
 
 	# We use `pc' rather than `unknown'
 	# because (1) that's what they normally are, and
@@ -305,25 +331,28 @@ case $basic_machine in
 	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
 	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
 	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-	| avr-* \
+	| avr-* | avr32-* \
 	| bfin-* | bs2000-* \
 	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
 	| clipper-* | craynv-* | cydra-* \
 	| d10v-* | d30v-* | dlx-* \
 	| elxsi-* \
-	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
 	| h8300-* | h8500-* \
 	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 	| i*86-* | i860-* | i960-* | ia64-* \
 	| ip2k-* | iq2000-* \
-	| m32r-* | m32rle-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
 	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
 	| mips16-* \
 	| mips64-* | mips64el-* \
-	| mips64vr-* | mips64vrel-* \
+	| mips64octeon-* | mips64octeonel-* \
 	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
 	| mips64vr4100-* | mips64vr4100el-* \
 	| mips64vr4300-* | mips64vr4300el-* \
 	| mips64vr5000-* | mips64vr5000el-* \
@@ -336,30 +365,34 @@ case $basic_machine in
 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
 	| mipstx39-* | mipstx39el-* \
 	| mmix-* \
-	| ms1-* \
+	| mt-* \
 	| msp430-* \
+	| nios-* | nios2-* \
 	| none-* | np1-* | ns16k-* | ns32k-* \
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
 	| pyramid-* \
-	| romp-* | rs6000-* \
-	| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
 	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-	| sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
 	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
 	| tahoe-* | thumb-* \
-	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
 	| tron-* \
+	| ubicom32-* \
 	| v850-* | v850e-* | vax-* \
 	| we32k-* \
-	| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
-	| xstormy16-* | xtensa-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa*-* \
 	| ymp-* \
-	| z8k-*)
+	| z8k-* | z80-*)
 		;;
-	m32c-*)
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
 		;;
 	# Recognize the various machine names and aliases which stand
 	# for a CPU type and a company and sometimes even an OS.
@@ -423,6 +456,10 @@ case $basic_machine in
 		basic_machine=m68k-apollo
 		os=-bsd
 		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
 	aux)
 		basic_machine=m68k-apple
 		os=-aux
@@ -431,10 +468,26 @@ case $basic_machine in
 		basic_machine=ns32k-sequent
 		os=-dynix
 		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
 	c90)
 		basic_machine=c90-cray
 		os=-unicos
 		;;
+        cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
 	convex-c1)
 		basic_machine=c1-convex
 		os=-bsd
@@ -463,8 +516,8 @@ case $basic_machine in
 		basic_machine=craynv-cray
 		os=-unicosmp
 		;;
-	cr16c)
-		basic_machine=cr16c-unknown
+	cr16)
+		basic_machine=cr16-unknown
 		os=-elf
 		;;
 	crds | unos)
@@ -502,6 +555,10 @@ case $basic_machine in
 		basic_machine=m88k-motorola
 		os=-sysv3
 		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
 	djgpp)
 		basic_machine=i586-pc
 		os=-msdosdjgpp
@@ -656,6 +713,14 @@ case $basic_machine in
 		basic_machine=m68k-isi
 		os=-sysv
 		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
 	m88k-omron*)
 		basic_machine=m88k-omron
 		;;
@@ -667,10 +732,17 @@ case $basic_machine in
 		basic_machine=ns32k-utek
 		os=-sysv
 		;;
+        microblaze)
+		basic_machine=microblaze-xilinx
+		;;
 	mingw32)
 		basic_machine=i386-pc
 		os=-mingw32
 		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
 	miniframe)
 		basic_machine=m68000-convergent
 		;;
@@ -696,6 +768,9 @@ case $basic_machine in
 		basic_machine=i386-pc
 		os=-msdos
 		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
 	mvs)
 		basic_machine=i370-ibm
 		os=-mvs
@@ -794,6 +869,14 @@ case $basic_machine in
 		basic_machine=i860-intel
 		os=-osf
 		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
 	pbd)
 		basic_machine=sparc-tti
 		;;
@@ -803,6 +886,12 @@ case $basic_machine in
 	pc532 | pc532-*)
 		basic_machine=ns32k-pc532
 		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
 	pentium | p5 | k5 | k6 | nexgen | viac3)
 		basic_machine=i586-pc
 		;;
@@ -859,6 +948,10 @@ case $basic_machine in
 		basic_machine=i586-unknown
 		os=-pw32
 		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
 	rom68k)
 		basic_machine=m68k-rom68k
 		os=-coff
@@ -885,6 +978,10 @@ case $basic_machine in
 	sb1el)
 		basic_machine=mipsisa64sb1el-unknown
 		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
 	sei)
 		basic_machine=mips-sei
 		os=-seiux
@@ -896,6 +993,9 @@ case $basic_machine in
 		basic_machine=sh-hitachi
 		os=-hms
 		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
 	sh64)
 		basic_machine=sh64-unknown
 		;;
@@ -985,6 +1085,10 @@ case $basic_machine in
 		basic_machine=tic6x-unknown
 		os=-coff
 		;;
+	tile*)
+		basic_machine=tile-unknown
+		os=-linux-gnu
+		;;
 	tx39)
 		basic_machine=mipstx39-unknown
 		;;
@@ -1060,6 +1164,10 @@ case $basic_machine in
 		basic_machine=z8k-unknown
 		os=-sim
 		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
 	none)
 		basic_machine=none-none
 		os=-none
@@ -1098,10 +1206,10 @@ case $basic_machine in
 	we32k)
 		basic_machine=we32k-att
 		;;
-	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
 		basic_machine=sh-unknown
 		;;
-	sparc | sparcv8 | sparcv9 | sparcv9b)
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
 		basic_machine=sparc-sun
 		;;
 	cydra)
@@ -1148,6 +1256,9 @@ case $os in
         # First match some system type aliases
         # that might get confused with valid system types.
 	# -solaris* is a basic system type, with this one exception.
+        -auroraux)
+	        os=-auroraux
+		;;
 	-solaris1 | -solaris1.*)
 		os=`echo $os | sed -e 's|solaris1|sunos4|'`
 		;;
@@ -1168,27 +1279,30 @@ case $os in
 	# Each alternative MUST END IN A *, to match a version number.
 	# -sysv* is not here because it comes later, after sysvr4.
 	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
-	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* \
 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* \
+	      | -aos* | -aros* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
 	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
 	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-	      | -chorusos* | -chorusrdb* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
 	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku*)
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1318,6 +1432,9 @@ case $os in
 	-zvmoe)
 		os=-zvmoe
 		;;
+	-dicos*)
+		os=-dicos
+		;;
 	-none)
 		;;
 	*)
@@ -1340,6 +1457,12 @@ else
 # system, and we'll never get to this point.
 
 case $basic_machine in
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
 	*-acorn)
 		os=-riscix1.2
 		;;
@@ -1349,9 +1472,9 @@ case $basic_machine in
 	arm*-semi)
 		os=-aout
 		;;
-    c4x-* | tic4x-*)
-        os=-coff
-        ;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
 	# This must come before the *-dec entry.
 	pdp10-*)
 		os=-tops20
@@ -1377,6 +1500,9 @@ case $basic_machine in
 	m68*-cisco)
 		os=-aout
 		;;
+        mep-*)
+		os=-elf
+		;;
 	mips*-cisco)
 		os=-elf
 		;;
@@ -1506,7 +1632,7 @@ case $basic_machine in
 			-sunos*)
 				vendor=sun
 				;;
-			-aix*)
+			-cnk*|-aix*)
 				vendor=ibm
 				;;
 			-beos*)

File diff suppressed because it is too large
+ 578 - 257
configure


+ 136 - 36
depcomp

@@ -1,9 +1,10 @@
 #! /bin/sh
 # depcomp - compile a program generating dependencies as side-effects
 
-scriptversion=2005-07-09.11
+scriptversion=2009-04-28.21; # UTC
 
-# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
+# Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,9 +17,7 @@ scriptversion=2005-07-09.11
 # GNU General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -86,12 +85,34 @@ if test "$depmode" = dashXmstdout; then
    depmode=dashmstdout
 fi
 
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+   # This is just like msvisualcpp but w/o cygpath translation.
+   # Just convert the backslash-escaped backslashes to single forward
+   # slashes to satisfy depend.m4
+   cygpath_u="sed s,\\\\\\\\,/,g"
+   depmode=msvisualcpp
+fi
+
 case "$depmode" in
 gcc3)
 ## gcc 3 implements dependency tracking that does exactly what
 ## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
 ## it if -MD -MP comes after the -MF stuff.  Hmm.
-  "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
   stat=$?
   if test $stat -eq 0; then :
   else
@@ -178,14 +199,14 @@ sgi)
 ' < "$tmpdepfile" \
     | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
     tr '
-' ' ' >> $depfile
-    echo >> $depfile
+' ' ' >> "$depfile"
+    echo >> "$depfile"
 
     # The second pass generates a dummy entry for each header file.
     tr ' ' '
 ' < "$tmpdepfile" \
    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
-   >> $depfile
+   >> "$depfile"
   else
     # The sourcefile does not contain any dependencies, so just
     # store a dummy comment line, to avoid errors with the Makefile
@@ -201,34 +222,39 @@ aix)
   # current directory.  Also, the AIX compiler puts `$object:' at the
   # start of each line; $object doesn't have directory information.
   # Version 6 uses the directory in both cases.
-  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
-  tmpdepfile="$stripped.u"
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
   if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
     "$@" -Wc,-M
   else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
     "$@" -M
   fi
   stat=$?
 
-  if test -f "$tmpdepfile"; then :
-  else
-    stripped=`echo "$stripped" | sed 's,^.*/,,'`
-    tmpdepfile="$stripped.u"
-  fi
-
   if test $stat -eq 0; then :
   else
-    rm -f "$tmpdepfile"
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
     exit $stat
   fi
 
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
   if test -f "$tmpdepfile"; then
-    outname="$stripped.o"
     # Each line is of the form `foo.o: dependent.h'.
     # Do two passes, one to just change these to
     # `$object: dependent.h' and one to simply `dependent.h:'.
-    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
-    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+    sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+    # That's a tab and a space in the [].
+    sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
   else
     # The sourcefile does not contain any dependencies, so just
     # store a dummy comment line, to avoid errors with the Makefile
@@ -276,6 +302,51 @@ icc)
   rm -f "$tmpdepfile"
   ;;
 
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add `dependent.h:' lines.
+    sed -ne '2,${
+	       s/^ *//
+	       s/ \\*$//
+	       s/$/:/
+	       p
+	     }' "$tmpdepfile" >> "$depfile"
+  else
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
 tru64)
    # The Tru64 compiler uses -MD to generate dependencies as a side
    # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
@@ -288,13 +359,13 @@ tru64)
 
    if test "$libtool" = yes; then
       # With Tru64 cc, shared objects can also be used to make a
-      # static library.  This mecanism is used in libtool 1.4 series to
+      # static library.  This mechanism is used in libtool 1.4 series to
       # handle both shared and static libraries in a single compilation.
       # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
       #
       # With libtool 1.5 this exception was removed, and libtool now
       # generates 2 separate objects for the 2 libraries.  These two
-      # compilations output dependencies in in $dir.libs/$base.o.d and
+      # compilations output dependencies in $dir.libs/$base.o.d and
       # in $dir$base.o.d.  We have to check for both files, because
       # one of the two compilations can be disabled.  We should prefer
       # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
@@ -345,7 +416,7 @@ dashmstdout)
 
   # Remove the call to Libtool.
   if test "$libtool" = yes; then
-    while test $1 != '--mode=compile'; do
+    while test "X$1" != 'X--mode=compile'; do
       shift
     done
     shift
@@ -396,32 +467,39 @@ makedepend)
   "$@" || exit $?
   # Remove any Libtool call
   if test "$libtool" = yes; then
-    while test $1 != '--mode=compile'; do
+    while test "X$1" != 'X--mode=compile'; do
       shift
     done
     shift
   fi
   # X makedepend
   shift
-  cleared=no
-  for arg in "$@"; do
+  cleared=no eat=no
+  for arg
+  do
     case $cleared in
     no)
       set ""; shift
       cleared=yes ;;
     esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
     case "$arg" in
     -D*|-I*)
       set fnord "$@" "$arg"; shift ;;
     # Strip any option that makedepend may not understand.  Remove
     # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
     -*|$object)
       ;;
     *)
       set fnord "$@" "$arg"; shift ;;
     esac
   done
-  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
   touch "$tmpdepfile"
   ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
   rm -f "$depfile"
@@ -441,7 +519,7 @@ cpp)
 
   # Remove the call to Libtool.
   if test "$libtool" = yes; then
-    while test $1 != '--mode=compile'; do
+    while test "X$1" != 'X--mode=compile'; do
       shift
     done
     shift
@@ -479,13 +557,27 @@ cpp)
 
 msvisualcpp)
   # Important note: in order to support this mode, a compiler *must*
-  # always write the preprocessed file to stdout, regardless of -o,
-  # because we must use -o when running libtool.
+  # always write the preprocessed file to stdout.
   "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
   IFS=" "
   for arg
   do
     case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
     "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
 	set fnord "$@"
 	shift
@@ -498,16 +590,23 @@ msvisualcpp)
 	;;
     esac
   done
-  "$@" -E |
-  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
   rm -f "$depfile"
   echo "$object : \\" > "$depfile"
-  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
   echo "	" >> "$depfile"
-  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
   rm -f "$tmpdepfile"
   ;;
 
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
 none)
   exec "$@"
   ;;
@@ -526,5 +625,6 @@ exit 0
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
 # End:

+ 357 - 160
install-sh

@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2005-05-14.22
+scriptversion=2009-04-28.21; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -39,38 +39,68 @@ scriptversion=2005-05-14.22
 # when there is no Makefile.
 #
 # This script is compatible with the BSD install script, but was written
-# from scratch.  It can only install one file at a time, a restriction
-# shared with many OS's install programs.
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
 
 # set DOITPROG to echo to test this script
 
 # Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
 
-# put in absolute paths if you don't have them in your path; or use env. vars.
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
 
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
 
-chmodcmd="$chmodprog 0755"
-chowncmd=
 chgrpcmd=
-stripcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
 rmcmd="$rmprog -f"
-mvcmd="$mvprog"
+stripcmd=
+
 src=
 dst=
 dir_arg=
-dstarg=
+dst_arg=
+
+copy_on_change=false
 no_target_directory=
 
-usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
    or: $0 [OPTION]... SRCFILES... DIRECTORY
    or: $0 [OPTION]... -t DIRECTORY SRCFILES...
    or: $0 [OPTION]... -d DIRECTORIES...
@@ -80,81 +110,86 @@ In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
 In the 4th, create DIRECTORIES.
 
 Options:
--c         (ignored)
--d         create directories instead of installing files.
--g GROUP   $chgrpprog installed files to GROUP.
--m MODE    $chmodprog installed files to MODE.
--o USER    $chownprog installed files to USER.
--s         $stripprog installed files.
--t DIRECTORY  install into DIRECTORY.
--T         report an error if DSTFILE is a directory.
---help     display this help and exit.
---version  display version info and exit.
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
 
 Environment variables override the default commands:
-  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
 "
 
-while test -n "$1"; do
+while test $# -ne 0; do
   case $1 in
-    -c) shift
-        continue;;
+    -c) ;;
+
+    -C) copy_on_change=true;;
 
-    -d) dir_arg=true
-        shift
-        continue;;
+    -d) dir_arg=true;;
 
     -g) chgrpcmd="$chgrpprog $2"
-        shift
-        shift
-        continue;;
+	shift;;
 
     --help) echo "$usage"; exit $?;;
 
-    -m) chmodcmd="$chmodprog $2"
-        shift
-        shift
-        continue;;
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
 
     -o) chowncmd="$chownprog $2"
-        shift
-        shift
-        continue;;
+	shift;;
 
-    -s) stripcmd=$stripprog
-        shift
-        continue;;
+    -s) stripcmd=$stripprog;;
 
-    -t) dstarg=$2
-	shift
-	shift
-	continue;;
+    -t) dst_arg=$2
+	shift;;
 
-    -T) no_target_directory=true
-	shift
-	continue;;
+    -T) no_target_directory=true;;
 
     --version) echo "$0 $scriptversion"; exit $?;;
 
-    *)  # When -d is used, all remaining arguments are directories to create.
-	# When -t is used, the destination is already specified.
-	test -n "$dir_arg$dstarg" && break
-        # Otherwise, the last argument is the destination.  Remove it from $@.
-	for arg
-	do
-          if test -n "$dstarg"; then
-	    # $@ is not empty: it contains at least $arg.
-	    set fnord "$@" "$dstarg"
-	    shift # fnord
-	  fi
-	  shift # arg
-	  dstarg=$arg
-	done
+    --)	shift
 	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
   esac
+  shift
 done
 
-if test -z "$1"; then
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+  done
+fi
+
+if test $# -eq 0; then
   if test -z "$dir_arg"; then
     echo "$0: no input file specified." >&2
     exit 1
@@ -164,24 +199,47 @@ if test -z "$1"; then
   exit 0
 fi
 
+if test -z "$dir_arg"; then
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
 for src
 do
   # Protect names starting with `-'.
   case $src in
-    -*) src=./$src ;;
+    -*) src=./$src;;
   esac
 
   if test -n "$dir_arg"; then
     dst=$src
-    src=
-
-    if test -d "$dst"; then
-      mkdircmd=:
-      chmodcmd=
-    else
-      mkdircmd=$mkdirprog
-    fi
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
   else
+
     # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
     # might cause directories to be created, which would be especially bad
     # if $src (and thus $dsttmp) contains '*'.
@@ -190,71 +248,199 @@ do
       exit 1
     fi
 
-    if test -z "$dstarg"; then
+    if test -z "$dst_arg"; then
       echo "$0: no destination specified." >&2
       exit 1
     fi
 
-    dst=$dstarg
+    dst=$dst_arg
     # Protect names starting with `-'.
     case $dst in
-      -*) dst=./$dst ;;
+      -*) dst=./$dst;;
     esac
 
     # If destination is a directory, append the input filename; won't work
     # if double slashes aren't ignored.
     if test -d "$dst"; then
       if test -n "$no_target_directory"; then
-	echo "$0: $dstarg: Is a directory" >&2
+	echo "$0: $dst_arg: Is a directory" >&2
 	exit 1
       fi
-      dst=$dst/`basename "$src"`
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
     fi
   fi
 
-  # This sed command emulates the dirname command.
-  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writeable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
 
-  # Make sure that the destination directory exists.
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
 
-  # Skip lots of stat calls in the usual case.
-  if test ! -d "$dstdir"; then
-    defaultIFS='
-	 '
-    IFS="${IFS-$defaultIFS}"
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
 
-    oIFS=$IFS
-    # Some sh's can't handle IFS=/ for some reason.
-    IFS='%'
-    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
-    shift
-    IFS=$oIFS
+      case $dstdir in
+	/*) prefix='/';;
+	-*) prefix='./';;
+	*)  prefix='';;
+      esac
 
-    pathcomp=
+      eval "$initialize_posix_glob"
 
-    while test $# -ne 0 ; do
-      pathcomp=$pathcomp$1
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
       shift
-      if test ! -d "$pathcomp"; then
-        $mkdirprog "$pathcomp"
-	# mkdir can fail with a `File exist' error in case several
-	# install-sh are creating the directory concurrently.  This
-	# is OK.
-	test -d "$pathcomp" || exit
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test -z "$d" && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
       fi
-      pathcomp=$pathcomp/
-    done
+    fi
   fi
 
   if test -n "$dir_arg"; then
-    $doit $mkdircmd "$dst" \
-      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
-      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
-      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
-      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
-
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
   else
-    dstfile=`basename "$dst"`
 
     # Make a couple of temp file names in the proper directory.
     dsttmp=$dstdir/_inst.$$_
@@ -262,10 +448,9 @@ do
 
     # Trap to clean up those temp files at exit.
     trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
-    trap '(exit $?); exit' 1 2 13 15
 
     # Copy the file name to the temp name.
-    $doit $cpprog "$src" "$dsttmp" &&
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
 
     # and set any options; do chmod last to preserve setuid bits.
     #
@@ -273,51 +458,63 @@ do
     # ignore errors from any of these, just make sure not to ignore
     # errors from the above "$doit $cpprog $src $dsttmp" command.
     #
-    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
-      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
-      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
-      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
-
-    # Now rename the file to the real destination.
-    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
-      || {
-	   # The rename failed, perhaps because mv can't rename something else
-	   # to itself, or perhaps because mv is so ancient that it does not
-	   # support -f.
-
-	   # Now remove or move aside any old file at destination location.
-	   # We try this two ways since rm can't unlink itself on some
-	   # systems and the destination file might be busy for other
-	   # reasons.  In this case, the final cleanup might fail but the new
-	   # file should still install successfully.
-	   {
-	     if test -f "$dstdir/$dstfile"; then
-	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
-	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
-	       || {
-		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
-		 (exit 1); exit 1
-	       }
-	     else
-	       :
-	     fi
-	   } &&
-
-	   # Now rename the file to the real destination.
-	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
-	 }
-    }
-  fi || { (exit 1); exit 1; }
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
 done
 
-# The final little trick to "correctly" pass the exit status to the exit trap.
-{
-  (exit 0); exit 0
-}
-
 # Local variables:
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
 # End:

+ 5 - 0
ldap/admin/src/scripts/50smd5pwdstorageplugin.ldif

@@ -6,3 +6,8 @@ nsslapd-pluginpath: libpwdstorage-plugin
 nsslapd-plugininitfunc: smd5_pwd_storage_scheme_init
 nsslapd-plugintype: pwdstoragescheme
 nsslapd-pluginenabled: on
+# these will be replaced when the server loads the plugin
+nsslapd-pluginId: ID
+nsslapd-pluginVersion: PACKAGE_VERSION
+nsslapd-pluginVendor: VENDOR
+nsslapd-pluginDescription: DESC

+ 145 - 0
ldap/admin/src/scripts/91upgradednformat.pl

@@ -0,0 +1,145 @@
+use Mozilla::LDAP::Conn;
+use Mozilla::LDAP::Utils qw(normalizeDN);
+use Mozilla::LDAP::API qw(:constant ldap_url_parse ldap_explode_dn);
+use File::Basename;
+use File::Copy;
+
+# Upgrade DN format if needed.
+# For each backend instance, 
+#     run upgradednformat with -N (dryrun mode),
+#     if it returns 0 (Upgrade candidates are found), 
+#     recursively copy the instance dir to the work dir (dnupgrade)
+#     run upgradednformat w/o -N against the DB in the work dir
+#     if it went ok, replace the original instance dir with the work dir.
+sub runinst {
+    my ($inf, $inst, $dseldif, $conn) = @_;
+
+    my @errs;
+
+    my $config = "cn=config";
+    my $mappingtree = "cn=mapping tree,cn=config";
+    my $ldbmbase = "cn=ldbm database,cn=plugins,cn=config";
+
+    my $backend_entry;
+    my $mtentry = $conn->search($mappingtree, "onelevel", "(cn=*)", 0, @attr);
+    if (!$mtentry) {
+        return ("error_no_mapping_tree_entries", $!);
+    }
+
+    # If a suffix in the mapping tree is doube-quoted and 
+    # the cn value has only the double-quoted value, e.g.
+    #   dn: cn="dc=example,dc=com",cn=mapping tree,cn=config
+    #   cn: "dc=example,dc=com"
+    # the following code adds non-quoted value:
+    #   cn: dc=example,dc=com
+    while ($mtentry) {
+        my $numvals = $mtentry->size("cn");
+        my $i;
+        my $withquotes = -1;
+        my $noquotes = -1;
+        for ($i = 0; $i < $numvals; $i++) {
+            if ($mtentry->{"cn"}[$i] =~ /^".*"$/) {
+                $withquotes = $i;
+            } else {
+                $noquotes = $i;
+            }
+        }
+        if ($withquotes >= 0 && $noquotes == -1) {
+            # Has only cn: "<suffix>"
+            # Adding cn: <suffix>
+            my $stripped = $mtentry->{"cn"}[$withquotes];
+            $stripped =~ s/^"(.*)"$/$1/;
+            $mtentry->addValue("cn", $stripped);
+            $conn->update($mtentry);
+        }
+        $mtentry = $conn->nextEntry();
+    }
+
+    my $config_entry = $conn->search($config, "base", "(cn=*)", 0, ("nsslapd-instancedir"));
+    if (!$config_entry) {
+        return ("error_no_configuration_entry", $!);
+    }
+    my $instancedir = $config_entry->{"nsslapd-instancedir"}[0];
+    my $upgradednformat = $instancedir . "/upgradednformat";
+
+    # Scan through all of the backends to see if any of them
+    # contain escape characters in the DNs.  If we find any
+    # escapes, we need to run the conversion tool on that
+    # backend.
+    $backend_entry = $conn->search($ldbmbase, "onelevel", "(objectClass=nsBackendInstance)", 0, @attr);
+    if (!$backend_entry) {
+        return ("error_no_backend_entries", $!);
+    }
+
+    while ($backend_entry) {
+        my $backend = $backend_entry->{"cn"}[0];
+        my $dbinstdir = $backend_entry->{"nsslapd-directory"}[0];
+        my $workdir = $dbinstdir . "/dnupgrade";
+        my $dbdir = dirname($dbinstdir);
+        my $pdbdir = dirname($dbdir);
+        my $instname = basename($dbinstdir);
+
+        if ("$dbdir" eq "" || "$instname" eq "") {
+            push @errs, ["error_invalid_dbinst_dir", $dbinstdir];
+            return @errs;
+        }
+
+        # clean up db region files, which might contain the old pages
+        if ( -d $dbdir  && -f $dbdir."/__db.001") {
+            unlink <$dbdir/__db.*>;
+        }
+
+        if (-e "$dbinstdir/id2entry.db4") {
+            # Check if any DNs contain escape characters with dbscan.
+            # dryrun mode
+            # return values:  0 -- need to upgrade dn format
+            #                 1 -- no need to upgrade dn format
+            #                -1 -- error
+            my $escapes = system("$upgradednformat -n $backend -a $dbinstdir -N");
+            if (0 == $escapes) {
+                my $rc = 0;
+
+                if (system("cd $pdbdir; tar cf - db/DBVERSION | (cd $dbinstdir; tar xf -)") ||
+                    system("cd $pdbdir; tar cf - db/$instname/{DBVERSION,*.db4} | (cd $dbinstdir; tar xf -)")) {
+                    push @errs, ["error_cant_backup_db", $backend, $!];
+                    return @errs;
+                }
+                my @stat = stat("$dbdir");
+                my $mode = $stat[2];
+                my $uid = $stat[4];
+                my $gid = $stat[5];
+
+                move("$dbinstdir/db", "$workdir");
+                chmod($mode, $workdir);
+                chown($uid, $gid, $workdir);
+
+                @stat = stat("$dbinstdir");
+                $mode = $stat[2];
+                $uid = $stat[4];
+                $gid = $stat[5];
+
+                chmod($mode, "$workdir/$instname");
+                chown($uid, $gid, "$workdir/$instname");
+
+                # call conversion tool here and get return status.
+                $rc = system("$upgradednformat -n $backend -a $workdir/$instname");
+                if ($rc == 0) { # success
+                    move("$dbinstdir", "$dbinstdir.orig");
+                    move("$dbinstdir.orig/dnupgrade/$instname", "$dbinstdir");
+                    copy("$dbinstdir.orig/dnupgrade/DBVERSION", "$dbdir");
+                } else {
+                    # Conversion failed. Cleanup and bail.
+                    unlink <$dbinstdir/dnupgrade/$backend/*>;
+                    rmdir("$dbinstdir/dnupgrade/$backend");
+                    unlink <$dbinstdir/dnupgrade/*>;
+                    rmdir("$dbinstdir/dnupgrade");
+                    return ("error_cant_convert_db", $backend, $rc);
+                }
+            }
+        }
+
+        $backend_entry = $conn->nextEntry();
+    }
+
+    return ();
+}

+ 7 - 0
ldap/admin/src/scripts/setup-ds.res.in

@@ -185,3 +185,10 @@ error_online_update = Could not open a connection to the server at %s port %s as
 Please make sure the server is up and running before using online mode,\
 or use offline mode.\n\n
 error_offline_update = Could not read the server config file '%s'. Error: %s\n\n
+error_no_mapping_tree_entries = Could not find a mapping tree entry.  Error: %s\n
+error_no_configuration_entry = Could not find a configuration entry.  Error: %s\n
+error_no_configuration_entry = Could not find a backend entry.  Error: %s\n
+error_invalid_dbinst_dir = Invalid database instance dir '%s'.\n
+error_cant_backup_db = Failed to back up backend instance '%s'.  Error: %s\n
+error_cant_convert_db = Failed to convert backend instance '%s'.  Error: %s\n
+error_missing_entrydn = Backend instance '%s' does not have database files to upgrade.\n

+ 56 - 0
ldap/admin/src/scripts/template-upgradednformat.in

@@ -0,0 +1,56 @@
+#!/bin/sh
+
+# upgradednformat -- upgrade DN format to the new style (RFC 4514)
+# Usgae: upgradednformat [-N] -n backend_instance -a db_instance_directory
+#        -N: dryrun
+#            exit code: 0 -- needs upgrade; 1 -- no need to upgrade; -1 -- error
+#        -n backend_instance -- instance name to be examined or upgraded
+#        -a db_instance_directory -- full path to the db instance dir
+#                                    e.g., /var/lib/dirsrv/slapd-ID/db/userRoot
+prefix="{{DS-ROOT}}"
+if [ "$prefix" = "/" ] ; then
+    prefix=""
+fi
+LD_LIBRARY_PATH=$prefix/{{SERVER-DIR}}:$prefix@nss_libdir@:$prefix@libdir@:$prefix@pcre_libdir@
+if [ -n "$prefix" ] ; then
+    LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:@nss_libdir@"
+fi
+export LD_LIBRARY_PATH
+SHLIB_PATH=$LD_LIBRARY_PATH
+export SHLIB_PATH
+
+cd {{SERVERBIN-DIR}}
+
+dir=""
+be=""
+dryrun=0
+while [ "$1" != "" ]
+do
+    if [ "$1" = "-a" ]; then
+        shift
+        dir="$1"
+    elif [ "$1" = "-n" ]; then
+        shift
+        be="$1"
+    elif [ "$1" = "-N" ]; then
+        dryrun=1
+    fi
+    if [ "$1" != "" ]; then
+        shift
+    fi
+done
+
+if [ "$be" = "" ] || [ "$dir" = "" ]; then
+        echo "be: $be"
+        echo "dir: $dir"
+    echo "Usage: $0 [-N] -n backend_instance -a db_instance_directory"
+    exit 1
+fi
+
+if [ $dryrun -eq 0 ]; then
+    ./ns-slapd upgradednformat -D {{CONFIG-DIR}} -a $dir -n $be
+else
+    ./ns-slapd upgradednformat -D {{CONFIG-DIR}} -a $dir -n $be -N
+fi
+rc=$?
+exit $rc

+ 5 - 1
ldap/ldif/template-bitwise.ldif.in

@@ -7,4 +7,8 @@ nsslapd-pluginPath: libbitwise-plugin
 nsslapd-pluginInitfunc: bitwise_init
 nsslapd-pluginType: matchingRule
 nsslapd-pluginEnabled: on
-
+# these will be replaced when the server loads the plugin
+nsslapd-pluginId: ID
+nsslapd-pluginVersion: PACKAGE_VERSION
+nsslapd-pluginVendor: VENDOR
+nsslapd-pluginDescription: DESC

+ 21 - 16
ldap/servers/plugins/syntaxes/string.c

@@ -601,7 +601,7 @@ string_assertion2keys_ava(
     size_t len;
 	char		*w, *c;
     Slapi_Value *tmpval=NULL;
-	char *alt = NULL;
+    char *alt = NULL;
 
     switch ( ftype ) {
     case LDAP_FILTER_EQUALITY_FAST: 
@@ -613,12 +613,14 @@ string_assertion2keys_ava(
         }
         memcpy(tmpval->bv.bv_val,slapi_value_get_string(val),len);
         tmpval->bv.bv_val[len]='\0';
-		/* 3rd arg: 1 - trim leading blanks */
+        /* 3rd arg: 1 - trim leading blanks */
         value_normalize_ext(tmpval->bv.bv_val, syntax, 1, &alt );
-		if (alt) {
-            slapi_ch_free_string(&tmpval->bv.bv_val);
-        	tmpval->bv.bv_val = alt;
-		}
+        if (alt) {
+            if (len >=  tmpval->bv.bv_len) {
+                slapi_ch_free_string(&tmpval->bv.bv_val);
+            }
+            tmpval->bv.bv_val = alt;
+        }
         tmpval->bv.bv_len=strlen(tmpval->bv.bv_val);
         break;
 	case LDAP_FILTER_EQUALITY:
@@ -627,7 +629,7 @@ string_assertion2keys_ava(
 		/* 3rd arg: 1 - trim leading blanks */
 		value_normalize_ext( (*ivals)[0]->bv.bv_val, syntax, 1, &alt );
 		if (alt) {
-            slapi_ch_free_string(&(*ivals)[0]->bv.bv_val);
+			slapi_ch_free_string(&(*ivals)[0]->bv.bv_val);
 			(*ivals)[0]->bv.bv_val = alt;
 		}
 		(*ivals)[0]->bv.bv_len = strlen( (*ivals)[0]->bv.bv_val );
@@ -687,8 +689,11 @@ string_assertion2keys_sub(
 	int maxsublen;
 	char	*comp_buf = NULL;
 	char *altinit = NULL;
+	char *oaltinit = NULL;
 	char **altany = NULL;
+	char **oaltany = NULL;
 	char *altfinal = NULL;
+	char *oaltfinal = NULL;
 	int anysize = 0;
 
 	slapi_pblock_get(pb, SLAPI_SYNTAX_SUBSTRLENS, &substrlens);
@@ -719,6 +724,7 @@ string_assertion2keys_sub(
 	if ( initial != NULL ) {
 		/* 3rd arg: 0 - DO NOT trim leading blanks */
 		value_normalize_ext( initial, syntax, 0, &altinit );
+		oaltinit = altinit;
 		if (NULL == altinit) {
 			altinit = initial;
 		}
@@ -737,11 +743,14 @@ string_assertion2keys_sub(
 		anysize++;
 	}
 	altany = (char **)slapi_ch_calloc(anysize + 1, sizeof(char *));
+	oaltany = (char **)slapi_ch_calloc(anysize + 1, sizeof(char *));
 	for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
 		/* 3rd arg: 0 - DO NOT trim leading blanks */
 		value_normalize_ext( any[i], syntax, 0, &altany[i] );
 		if (NULL == altany[i]) {
 			altany[i] = any[i];
+		} else {
+			oaltany[i] = altany[i];
 		}
 		len = strlen( altany[i] );
 		if ( len >= substrlens[INDEX_SUBSTRMIDDLE] ) {
@@ -751,6 +760,7 @@ string_assertion2keys_sub(
 	if ( final != NULL ) {
 		/* 3rd arg: 0 - DO NOT trim leading blanks */
 		value_normalize_ext( final, syntax, 0, &altfinal );
+		oaltfinal = altfinal;
 		if (NULL == altfinal) {
 			altfinal = final;
 		}
@@ -784,10 +794,8 @@ string_assertion2keys_sub(
 	if ( altinit != NULL ) {
 		substring_comp_keys( ivals, &nsubs, altinit, initiallen, '^', syntax,
 							 comp_buf, substrlens );
-		if (altinit != initial) {
-			slapi_ch_free_string(&altinit);
-		}
 	}
+	slapi_ch_free_string(&oaltinit);
 	for ( i = 0; altany != NULL && altany[i] != NULL; i++ ) {
 		len = strlen( altany[i] );
 		if ( len < substrlens[INDEX_SUBSTRMIDDLE] ) {
@@ -795,18 +803,15 @@ string_assertion2keys_sub(
 		}
 		substring_comp_keys( ivals, &nsubs, altany[i], len, 0, syntax,
 							 comp_buf, substrlens );
-		if (altany[i] != any[i]) {
-			slapi_ch_free_string(&altany[i]);
-		}
+		slapi_ch_free_string(&oaltany[i]);
 	}
+	slapi_ch_free((void **)&oaltany);
 	slapi_ch_free((void **)&altany);
 	if ( altfinal != NULL ) {
 		substring_comp_keys( ivals, &nsubs, altfinal, finallen, '$', syntax,
 							 comp_buf, substrlens );
-		if (altfinal != final) {
-			slapi_ch_free_string(&final);
-		}
 	}
+	slapi_ch_free_string(&oaltfinal);
 	(*ivals)[nsubs] = NULL;
 	slapi_ch_free_string(&comp_buf);
 

+ 8 - 1
ldap/servers/slapd/back-ldbm/back-ldbm.h

@@ -167,7 +167,14 @@ typedef unsigned short u_int16_t;
  */
 #define BDB_IMPL        "bdb"
 #define BDB_BACKEND     "libback-ldbm" /* This backend plugin */
+#define BDB_NEWIDL      "newidl"       /* new idl format */
 #define BDB_RDNFORMAT   "rdn-format"   /* Subtree rename enabled */
+#define BDB_DNFORMAT    "dn-4514"      /* DN format RFC 4514 compliant */
+
+#define DBVERSION_NEWIDL      0x1
+#define DBVERSION_RDNFORMAT   0x2
+#define DBVERSION_DNFORMAT    0x4
+#define DBVERSION_ALL   0xffffffff
 
 /*
  * While we support both new and old idl index,
@@ -789,7 +796,7 @@ typedef struct _back_search_result_set
 #define BE_INDEX_TOMBSTONE	8   /* Index entry as a tombstone */
 #define BE_INDEX_DONT_ENCRYPT	16   /* Disable any encryption if this flag is set */
 #define BE_INDEX_EQUALITY	32  /* (w/DEL) remove the equality index */
-#define BE_INDEX_NORMALIZED SLAPI_ATTR_FLAG_NORMALIZED /* value already normalized */
+#define BE_INDEX_NORMALIZED SLAPI_ATTR_FLAG_NORMALIZED /* value already normalized (0x200) */
 
 /* Name of attribute type used for binder-based look through limit */
 #define LDBM_LOOKTHROUGHLIMIT_AT	"nsLookThroughLimit"

+ 38 - 34
ldap/servers/slapd/back-ldbm/dblayer.c

@@ -1706,7 +1706,7 @@ int dblayer_start(struct ldbminfo *li, int dbmode)
         if ( (DBLAYER_NORMAL_MODE == dbmode ) && 
              (0 == return_value)) {
             /* update the dbversion file */
-            dbversion_write(li, region_dir, NULL);
+            dbversion_write(li, region_dir, NULL, DBVERSION_ALL);
 
             /* if dblayer_close then dblayer_start is called,
                this flag is set */
@@ -2013,7 +2013,7 @@ int dblayer_instance_start(backend *be, int mode)
             }
         } else {
             /* The dbversion file didn't exist, so we'll create one. */
-            dbversion_write(li, inst_dirp, NULL);
+            dbversion_write(li, inst_dirp, NULL, DBVERSION_ALL);
         }
     } /* on import we don't mess with the dbversion file except to write it
        * when done with the import. */
@@ -2210,7 +2210,7 @@ out:
     }
 
     if (mode & DBLAYER_NORMAL_MODE) {
-        dbversion_write(li, inst_dirp, NULL);
+        dbversion_write(li, inst_dirp, NULL, DBVERSION_ALL);
         /* richm - not sure if need to acquire the be lock first? */
         /* need to set state back to started - set to stopped in
            dblayer_instance_close */
@@ -2284,7 +2284,7 @@ int dblayer_get_aux_id2entry(backend *be, DB **ppDB, DB_ENV **ppEnv)
     size_t cachesize;
     PRFileInfo prfinfo;
     PRStatus prst;
-    char *id2entry_file;
+    char *id2entry_file = NULL;
     char inst_dir[MAXPATHLEN];
     char *inst_dirp = NULL;
     char *data_directories[2] = {0, 0};
@@ -2651,35 +2651,6 @@ int dblayer_post_close(struct ldbminfo *li, int dbmode)
     return_value = pEnv->dblayer_DB_ENV->close(pEnv->dblayer_DB_ENV, 0);
     dblayer_free_env(&priv->dblayer_env); /* pEnv is now garbage */
 
-#if 0    /* DBDB do NOT remove the environment: bad, bad idea */
-    if (return_value == 0) {
-        DB_ENV *env = 0;
-        return_value = db_env_create(&env, 0);
-        /* don't be tempted to use the
-           previously nulled out env handle
-           as Sleepycat 3.x is unhappy if
-           the env handle handed to remove
-           was used elsewhere. rwagner  */
-        if (return_value == 0) {
-            char *home_dir = dblayer_get_home_dir(li, NULL);
-            if (home_dir)
-                return_value = env->remove(env, home_dir, 0);
-            if (0 == return_value
-                && !((DBLAYER_ARCHIVE_MODE|DBLAYER_EXPORT_MODE) & dbmode)
-                && !priv->dblayer_bad_stuff_happened) {
-                /*
-                 * If we got here, we have a good consistent database,
-                 * so we write the guard file
-                 */
-                commit_good_database(priv);
-            } else if (return_value == EBUSY) {
-                /* something else is using the env so ignore */
-                /* but let's not make a guardian file */
-                return_value = 0; 
-            }
-        }
-    }
-#endif
     if (0 == return_value
         && !((DBLAYER_ARCHIVE_MODE|DBLAYER_EXPORT_MODE) & dbmode)
         && !priv->dblayer_bad_stuff_happened) {
@@ -2744,11 +2715,44 @@ int dblayer_close(struct ldbminfo *li, int dbmode)
  * for the transacted database, we interpret this as an instruction
  * to write a checkpoint.
  */
-int    dblayer_flush(struct ldbminfo *li)
+int
+dblayer_flush(struct ldbminfo *li)
 {
     return 0;
 }
 
+/* API to remove the environment */
+int
+dblayer_remove_env(struct ldbminfo *li)
+{
+    DB_ENV *env = NULL;
+    dblayer_private *priv = NULL;
+    char *home_dir = NULL;
+    int rc = db_env_create(&env, 0);
+    if (rc) {
+        LDAPDebug1Arg(LDAP_DEBUG_ANY,
+                      "ERROR -- Failed to create DB_ENV (returned: %d)\n", rc);
+        return rc;
+    }
+    if (NULL == li) {
+        LDAPDebug0Args(LDAP_DEBUG_ANY, "ERROR -- No ldbm info is given\n");
+        return -1;
+    }
+    priv = (dblayer_private *)li->li_dblayer_private;
+
+    home_dir = dblayer_get_home_dir(li, NULL);
+    if (home_dir) {
+        rc = env->remove(env, home_dir, 0);
+        if (rc) {
+            LDAPDebug1Arg(LDAP_DEBUG_ANY,
+                          "ERROR -- Failed to remove DB environment files. "
+                          "Please remove %s/__db.00# (# is 1 through 6)\n",
+                          home_dir);
+        }
+    }
+    return rc;
+}
+
 #if !defined(DB_DUPSORT)
 #define DB_DUPSORT 0
 #endif

+ 21 - 26
ldap/servers/slapd/back-ldbm/dbversion.c

@@ -74,7 +74,7 @@ mk_dbversion_fullpath(struct ldbminfo *li, const char *directory, char *filename
  */
 int
 dbversion_write(struct ldbminfo *li, const char *directory,
-                const char *dataversion)
+                const char *dataversion, PRUint32 flags)
 {
     char filename[ MAXPATHLEN*2 ];
     PRFileDesc *prfd;
@@ -99,33 +99,28 @@ dbversion_write(struct ldbminfo *li, const char *directory,
     else
     {
         /* Write the file */
-        PRInt32    len;
         char buf[ LDBM_VERSION_MAXBUF ];
-        /* recognize the difference between an old/new database regarding idl
-         * (406922) */
-        if (idl_get_idl_new())
-        {
-            if (entryrdn_get_switch()) {
-                sprintf(buf, "%s/%d.%d/%s/%s\n", 
-                        BDB_IMPL, DB_VERSION_MAJOR, DB_VERSION_MINOR,
-                        BDB_BACKEND, BDB_RDNFORMAT);
-            } else {
-                sprintf(buf, "%s/%d.%d/%s\n", 
-                        BDB_IMPL, DB_VERSION_MAJOR, DB_VERSION_MINOR,
-                        BDB_BACKEND);
-            }
+        char *ptr = NULL;
+        size_t len = 0;
+        /* Base DB Version */
+        PR_snprintf(buf, sizeof(buf), "%s/%d.%d/%s",
+                    BDB_IMPL, DB_VERSION_MAJOR, DB_VERSION_MINOR, BDB_BACKEND);
+        len = strlen(buf);
+        ptr = buf + len;
+        if (idl_get_idl_new() && (flags & DBVERSION_NEWIDL)) {
+            PR_snprintf(ptr, sizeof(buf) - len, "/%s", BDB_NEWIDL);
+            len = strlen(buf);
+            ptr = buf + len;
         }
-        else
-        {
-            if (entryrdn_get_switch()) {
-                sprintf(buf, "%s/%d.%d/%s/%s\n", 
-                        BDB_IMPL, DB_VERSION_MAJOR, DB_VERSION_MINOR,
-                        BDB_BACKEND, BDB_RDNFORMAT);
-            } else {
-                sprintf(buf, "%s/%d.%d/%s\n", 
-                        BDB_IMPL, DB_VERSION_MAJOR, DB_VERSION_MINOR,
-                        BDB_BACKEND);
-            }
+        if (entryrdn_get_switch() && (flags & DBVERSION_RDNFORMAT)) {
+            PR_snprintf(ptr, sizeof(buf) - len, "/%s", BDB_RDNFORMAT);
+            len = strlen(buf);
+            ptr = buf + len;
+        }
+        if (flags & DBVERSION_DNFORMAT) {
+            PR_snprintf(ptr, sizeof(buf) - len, "/%s", BDB_DNFORMAT);
+            len = strlen(buf);
+            ptr = buf + len;
         }
         len = strlen( buf );
         if ( slapi_write_buffer( prfd, buf, len ) != len )

+ 747 - 33
ldap/servers/slapd/back-ldbm/import-threads.c

@@ -378,6 +378,7 @@ import_producer(void *param)
     ldif_context c;
     int my_version = 0;
     size_t newesize = 0;
+    Slapi_Attr *attr = NULL;
 
     PR_ASSERT(info != NULL);
     PR_ASSERT(inst != NULL);
@@ -405,7 +406,6 @@ import_producer(void *param)
      * as we read it.
      */
     while (! finished) {
-        Slapi_Attr *attr = NULL;
         int flags = 0;
         int prev_lineno = 0;
         int lines_in_entry = 0;
@@ -586,7 +586,6 @@ import_producer(void *param)
         /* If we are importing pre-encrypted attributes, we need
          * to skip syntax checks for the encrypted values. */
         if (!(job->encrypt) && inst->attrcrypt_configured) {
-            Slapi_Attr *attr = NULL;
             Slapi_Entry *e_copy = NULL;
 
             /* Scan through the entry to see if any present
@@ -1042,6 +1041,7 @@ index_producer(void *param)
                             rc = 0; /* assume this is a suffix */
                         } else {
                             ID pid = (ID)strtol(pid_str, (char **)NULL, 10);
+                            slapi_ch_free_string(&pid_str);
                             /* if pid is larger than the current pid temp_id,
                              * the parent entry hasn't */
                             rc = import_get_and_add_parent_rdns(info, inst, db,
@@ -1123,6 +1123,593 @@ error:
     info->state = ABORTED;
 }
 
+struct upgradedn_attr {
+    char *ud_type;
+    char *ud_value;
+    struct upgradedn_attr *ud_next;
+    int ud_flags;
+#define OLD_DN_NORMALIZE 0x1
+};
+
+static void
+upgradedn_free_list(struct upgradedn_attr **ud_list)
+{
+    struct upgradedn_attr *ptr = *ud_list;
+
+    while (ptr) {
+        struct upgradedn_attr *next = ptr->ud_next;
+        slapi_ch_free_string(&ptr->ud_type);
+        slapi_ch_free_string(&ptr->ud_value);
+        slapi_ch_free((void **)&ptr);
+        ptr = next;
+    }
+    *ud_list = NULL;
+    return;
+}
+
+static void
+upgradedn_add_to_list(struct upgradedn_attr **ud_list, 
+                      char *type, char *value, int flag)
+{
+    struct upgradedn_attr *elem =
+       (struct upgradedn_attr *) slapi_ch_malloc(sizeof(struct upgradedn_attr));
+    elem->ud_type = type;
+    elem->ud_value = value;
+    elem->ud_flags = flag;
+    elem->ud_next = *ud_list;
+    *ud_list = elem;
+    return;
+}
+
+/* 
+ * Producer thread for upgrading dn format 
+ * FLAG_UPGRADEDNFORMAT | FLAG_DRYRUN -- check the necessity of dn upgrade
+ * FLAG_UPGRADEDNFORMAT -- execute dn upgrade
+ *
+ * Read id2entry, 
+ * Check the DN syntax attributes if it contains '\' or not AND
+ * Check the RDNs of the attributes if the value is surrounded by 
+ * double-quotes or not.
+ * If both are false, skip the entry and go to next
+ * If either is true, create an entry which contains a correctly normalized
+ *     DN attribute values in e_attr list and the original entrydn in the 
+ *     deleted attribute list e_deleted_attrs.
+ *
+ * If FLAG_UPGRADEDNFORMAT is set, worker_threads for indexing DN syntax
+ * attributes are brought up.  Foreman thread updates entrydn index
+ * as well as the entry itself in the id2entry.db#.
+ *
+ * Note: QUIT state for info->state is introduced for DRYRUN mode to
+ *       distinguish the intentional QUIT (found the dn upgrade candidate)
+ *       from ABORTED (aborted or error) and FINISHED (scan all the entries
+ *       and found no candidate to upgrade)
+ */
+void 
+upgradedn_producer(void *param)
+{
+    ImportWorkerInfo *info = (ImportWorkerInfo *)param;
+    ImportJob *job = info->job;
+    ID id = job->first_ID;
+    Slapi_Entry *e = NULL;
+    struct backentry *ep = NULL, *old_ep = NULL;
+    ldbm_instance *inst = job->inst;
+    PRIntervalTime sleeptime;
+    int finished = 0;
+    int idx;
+    int rc = 0;
+    Slapi_Attr *a = NULL;
+    Slapi_DN *sdn = NULL;
+    char *workdn = NULL;
+    int doit = 0;
+    int skipit = 0;
+    int isentrydn = 0;
+    Slapi_Value *value = NULL;
+    struct upgradedn_attr *ud_list = NULL;
+    char **ud_vals = NULL;
+    char **ud_valp = NULL;
+    struct upgradedn_attr *ud_ptr = NULL;
+    Slapi_Attr *ud_attr = NULL;
+    char *ecopy = NULL;
+
+    /* vars for Berkeley DB */
+    DB_ENV *env = NULL;
+    DB *db = NULL;
+    DBC *dbc = NULL;
+    DBT key = {0};
+    DBT data = {0};
+    int db_rval = -1;
+    backend *be = inst->inst_be;
+    int isfirst = 1;
+    int curr_entry = 0;
+    size_t newesize = 0;
+
+    PR_ASSERT(info != NULL);
+    PR_ASSERT(inst != NULL);
+    PR_ASSERT(be != NULL);
+    
+    if ( job->flags & FLAG_ABORT )
+        goto error;
+
+    sleeptime = PR_MillisecondsToInterval(import_sleep_time);
+
+    /* pause until we're told to run */
+    while ((info->command == PAUSE) && !(job->flags & FLAG_ABORT)) {
+        info->state = WAITING;
+        DS_Sleep(sleeptime);
+    }
+    info->state = RUNNING;
+
+    /* open id2entry with dedicated db env and db handler */
+    if ( dblayer_get_aux_id2entry( be, &db, &env ) != 0  || db == NULL ||
+         env == NULL) {
+        LDAPDebug( LDAP_DEBUG_ANY, "Could not open id2entry\n", 0, 0, 0 );
+        goto error;
+    }
+
+    /* get a cursor to we can walk over the table */
+    db_rval = db->cursor(db, NULL, &dbc, 0);
+    if ( 0 != db_rval ) {
+        LDAPDebug( LDAP_DEBUG_ANY,
+                   "Failed to get cursor for reindexing\n", 0, 0, 0 );
+        dblayer_release_id2entry(be, db);
+        goto error;
+    }
+
+    /* we loop around reading the input files and processing each entry
+     * as we read it.
+     */
+    finished = 0;
+    while (!finished) {
+        ID temp_id;
+
+        if (job->flags & FLAG_ABORT) {   
+            goto error;
+        }
+        while ((info->command == PAUSE)  && !(job->flags & FLAG_ABORT)){
+            info->state = WAITING;
+            DS_Sleep(sleeptime);
+        }
+        info->state = RUNNING;
+
+        key.flags = DB_DBT_MALLOC;
+        data.flags = DB_DBT_MALLOC;
+        if (isfirst)
+        {
+            db_rval = dbc->c_get(dbc, &key, &data, DB_FIRST);
+            isfirst = 0;
+        }
+        else
+        {
+            db_rval = dbc->c_get(dbc, &key, &data, DB_NEXT);
+        }
+        
+        if (0 != db_rval) {
+            if (DB_NOTFOUND != db_rval) {
+                LDAPDebug(LDAP_DEBUG_ANY, "%s: Failed to read database, "
+                    "errno=%d (%s)\n", inst->inst_name, db_rval,
+                    dblayer_strerror(db_rval));
+                if (job->task) {
+                    slapi_task_log_notice(job->task,
+                        "%s: Failed to read database, err %d (%s)",
+                        inst->inst_name, db_rval,
+                        dblayer_strerror(db_rval));
+                }
+            }
+            finished = 1;
+            break; /* error or done */
+        }
+        curr_entry++;
+        temp_id = id_stored_to_internal((char *)key.data);
+        slapi_ch_free(&(key.data));
+
+        /* call post-entry plugin */
+        plugin_call_entryfetch_plugins((char **)&data.dptr, &data.dsize);
+        ecopy = (char *)slapi_ch_malloc(data.dsize + 1);
+        memcpy(ecopy, data.dptr, data.dsize);
+        *(ecopy + data.dsize) = '\0';
+        if (entryrdn_get_switch()) {
+            char *rdn = NULL;
+    
+            /* rdn is allocated in get_value_from_string */
+            rc = get_value_from_string((const char *)data.dptr, "rdn", &rdn);
+            if (rc) {
+                /* data.dptr may not include rdn: ..., try "dn: ..." */
+                e = slapi_str2entry( data.dptr, 0 );
+            } else {
+                char *dn = NULL;
+                struct backdn *bdn = 
+                                  dncache_find_id(&inst->inst_dncache, temp_id);
+                if (bdn) {
+                    /* don't free dn */
+                    dn = (char *)slapi_sdn_get_dn(bdn->dn_sdn);
+                    CACHE_RETURN(&inst->inst_dncache, &bdn);
+                } else {
+                    Slapi_DN *sdn = NULL;
+                    rc = entryrdn_lookup_dn(be, rdn, temp_id, &dn, NULL);
+                    if (rc) {
+                        /* We cannot use the entryrdn index;
+                         * Compose dn from the entries in id2entry */
+                        Slapi_RDN psrdn = {0};
+                        char *pid_str = NULL;
+                        char *pdn = NULL;
+
+                        LDAPDebug2Args( LDAP_DEBUG_TRACE,
+                                   "index_producer: entryrdn is not available; "
+                                   "composing dn (rdn: %s, ID: %d)\n", 
+                                   rdn, temp_id);
+                        rc = get_value_from_string((const char *)data.dptr,
+                                                   LDBM_PARENTID_STR, &pid_str);
+                        if (rc) {
+                            rc = 0; /* assume this is a suffix */
+                        } else {
+                            ID pid = (ID)strtol(pid_str, (char **)NULL, 10);
+                            slapi_ch_free_string(&pid_str);
+                            /* if pid is larger than the current pid temp_id,
+                             * the parent entry hasn't */
+                            rc = import_get_and_add_parent_rdns(info, inst, db,
+                                                 pid, &id, &psrdn, &curr_entry);
+                            if (rc) {
+                                LDAPDebug2Args( LDAP_DEBUG_ANY,
+                                   "ldbm2index: Failed to compose dn for "
+                                   "(rdn: %s, ID: %d)\n", rdn, temp_id);
+                                slapi_ch_free_string(&rdn);
+                                slapi_rdn_done(&psrdn);
+                                continue;
+                            }
+                            /* Generate DN string from Slapi_RDN */
+                            rc = slapi_rdn_get_dn(&psrdn, &pdn);
+                            slapi_rdn_done(&psrdn);
+                            if (rc) {
+                                LDAPDebug2Args( LDAP_DEBUG_ANY,
+                                       "ldbm2index: Failed to compose dn for "
+                                       "(rdn: %s, ID: %d) from Slapi_RDN\n",
+                                       rdn, temp_id);
+                                slapi_ch_free_string(&rdn);
+                                continue;
+                            }
+                        }
+                        dn = slapi_ch_smprintf("%s%s%s",
+                                               rdn, pdn?",":"", pdn?pdn:"");
+                        slapi_ch_free_string(&pdn);
+                    }
+                    /* dn is not dup'ed in slapi_sdn_new_dn_byref.
+                     * It's set to bdn and put in the dn cache. */
+                    sdn = slapi_sdn_new_dn_byref(dn);
+                    bdn = backdn_init(sdn, temp_id, 0);
+                    CACHE_ADD( &inst->inst_dncache, bdn, NULL );
+                    CACHE_RETURN(&inst->inst_dncache, &bdn);
+                    slapi_log_error(SLAPI_LOG_CACHE, "ldbm2index",
+                                    "entryrdn_lookup_dn returned: %s, "
+                                    "and set to dn cache\n", dn);
+                }
+                e = slapi_str2entry_ext( dn, data.dptr, 0 );
+                slapi_ch_free_string(&rdn);
+            }
+        } else {
+            e = slapi_str2entry(data.data, 0);
+        }
+        slapi_ch_free(&(data.data));
+        if ( NULL == e ) {
+            if (job->task) {
+                slapi_task_log_notice(job->task,
+                        "%s: WARNING: skipping badly formatted entry (id %lu)",
+                        inst->inst_name, (u_long)temp_id);
+            }
+            LDAPDebug(LDAP_DEBUG_ANY,
+                      "%s: WARNING: skipping badly formatted entry (id %lu)\n",
+                      inst->inst_name, (u_long)temp_id, 0);
+            continue;
+        } 
+
+        /* Check DN syntax attr values if it contains '\\' or not */
+        /* Start from the rdn */
+        if (entryrdn_get_switch()) { /* subtree-rename: on */
+            char *rdn = NULL;
+            size_t rdnlen = 0;
+            rc = get_value_from_string((const char *)ecopy, "rdn", &rdn);
+            if (rc || (NULL == rdn)) {
+                LDAPDebug2Args(LDAP_DEBUG_ANY,
+                       "%s: WARNING: skipping an entry with no RDN (id %lu)\n",
+                       inst->inst_name, (u_long)temp_id);
+                continue;
+            }
+
+            /* rdn contains '\\'.  We have to update the value */
+            if (PL_strchr(rdn, '\\')) {
+                upgradedn_add_to_list(&ud_list,
+                                      slapi_ch_strdup(LDBM_ENTRYRDN_STR),
+                                      slapi_ch_strdup(rdn), 0);
+                LDAPDebug(LDAP_DEBUG_TRACE,
+                          "%s: Found upgradedn candidate: %s (id %lu)\n", 
+                          inst->inst_name, *ud_valp, (u_long)temp_id);
+                doit = 1;
+            } else {
+                rdnlen = strlen(rdn);
+                /* DN contains an RDN <type>="<value>" ? */
+                if (('"' == *rdn) && 
+                    ('"' == *(rdn + rdnlen - 1))) {
+                    upgradedn_add_to_list(&ud_list, 
+                                          slapi_ch_strdup(LDBM_ENTRYRDN_STR),
+                                          slapi_ch_strdup(rdn), 0);
+                    LDAPDebug(LDAP_DEBUG_TRACE,
+                              "%s: Found upgradedn candidate: %s (id %lu)\n", 
+                              inst->inst_name, rdn, (u_long)temp_id);
+                    doit = 1;
+                }
+            }
+            slapi_ch_free_string(&rdn);
+        }
+        for (a = e->e_attrs; a; a = a->a_next) {
+            if (slapi_attr_is_dn_syntax_attr(a)) { /* is dn syntax attr? */
+                rc = get_values_from_string((const char *)ecopy,
+                                             a->a_type, &ud_vals);
+                if (rc || (NULL == ud_vals)) {
+                    continue; /* empty; ignore it */
+                }
+
+                for (ud_valp = ud_vals; ud_valp && *ud_valp; ud_valp++) {
+                    char **rdns = NULL;
+                    char **rdnsp = NULL;
+                    char *valueptr = NULL;
+                    int valuelen;
+
+                    /* ud_valp contains '\\'.  We have to update the value */
+                    if (PL_strchr(*ud_valp, '\\')) {
+                        upgradedn_add_to_list(&ud_list, 
+                                              slapi_ch_strdup(a->a_type),
+                                              slapi_ch_strdup(*ud_valp),
+                                              0);
+                        LDAPDebug(LDAP_DEBUG_TRACE,
+                              "%s: Found upgradedn candidate: %s (id %lu)\n", 
+                              inst->inst_name, *ud_valp, (u_long)temp_id);
+                        doit = 1;
+                        continue;
+                    }
+                    /* Also check RDN contains double quoted values */
+                    if (strcasecmp(a->a_type, "entrydn")) {
+                        /* except entrydn */
+                        workdn = slapi_ch_strdup(*ud_valp);
+                        isentrydn = 0;
+                    } else {
+                        /* entrydn: Get Slapi DN */
+                        sdn = slapi_entry_get_sdn(e);
+                        workdn = slapi_ch_strdup(slapi_sdn_get_dn(sdn));
+                        isentrydn = 1;
+                    }
+                    rdns = ldap_explode_dn(workdn, 0);
+                    skipit = 0;
+                    for (rdnsp = rdns; rdnsp && *rdnsp; rdnsp++) {
+                        valueptr = PL_strchr(*rdnsp, '=');
+                        if (NULL == valueptr) {
+                            skipit = 1;
+                            break;
+                        }
+                        valueptr++;
+                        while ((' ' == *valueptr) || ('\t' == *valueptr)) {
+                            valueptr++;
+                        }
+                        valuelen = strlen(valueptr);
+                        if (0 == valuelen) {
+                            skipit = 1;
+                            break;
+                        }
+                        /* DN contains an RDN <type>="<value>" ? */
+                        if (('"' == *valueptr) && 
+                            ('"' == *(valueptr + valuelen - 1))) {
+                            upgradedn_add_to_list(&ud_list, 
+                                                  slapi_ch_strdup(a->a_type),
+                                                  slapi_ch_strdup(*ud_valp),
+                                                  isentrydn?0:OLD_DN_NORMALIZE);
+                            LDAPDebug(LDAP_DEBUG_TRACE,
+                                "%s: Found upgradedn candidate: %s (id %lu)\n", 
+                                inst->inst_name, valueptr, (u_long)temp_id);
+                            doit = 1;
+                            break;
+                        }
+                    }
+                    if (rdns) {
+                        slapi_ldap_value_free(rdns);
+                    } else {
+                        skipit = 1;
+                    }
+                    if (skipit) {
+                        break;
+                    }
+                    slapi_ch_free_string(&workdn);
+                } /* for (ud_valp = ud_vals; ud_valp && *ud_valp; ud_valp++) */
+                charray_free(ud_vals);
+                ud_vals = NULL;
+                if (skipit) {
+                    LDAPDebug(LDAP_DEBUG_ANY, "%s: WARNING: skipping an entry "
+                              "with a corrupted dn (syntax value): %s "
+                              "(id %lu)\n",
+                              inst->inst_name, 
+                              workdn?workdn:"unknown", (u_long)temp_id);
+                    slapi_ch_free_string(&workdn);
+                    upgradedn_free_list(&ud_list);
+                    break;
+                }
+            } /* if (slapi_attr_is_dn_syntax_attr(a)) */
+        } /* for (a = e->e_attrs; a; a = a->a_next)  */
+        slapi_ch_free_string(&ecopy);
+        if (skipit) {
+            upgradedn_free_list(&ud_list);
+            slapi_entry_free(e); e = NULL;
+            continue;
+        }
+
+        if (!doit) {
+            /* We don't have to update dn syntax values. */
+            upgradedn_free_list(&ud_list);
+            slapi_entry_free(e); e = NULL;
+            continue;
+        }
+        
+        /* doit */
+        if (job->flags & FLAG_DRYRUN) {
+            /* We can return SUCCESS (== found upgrade dn candidates) */
+            finished = 0; /* make it sure ... */
+            upgradedn_free_list(&ud_list);
+            slapi_entry_free(e); e = NULL;
+            goto bail;
+        }
+
+        skipit = 0;
+        for (ud_ptr = ud_list; ud_ptr; ud_ptr = ud_ptr->ud_next) {
+            /* Move the current value to e_deleted_attrs. */
+            /* entryrdn is special since it does not have an attribute in db */
+            if (0 == strcmp(ud_ptr->ud_type, LDBM_ENTRYRDN_STR)) {
+                /* entrydn contains half normalized value in id2entry,
+                   thus we have to replace it in id2entry.  
+                   The other DN syntax attribute values store 
+                   the originals.  They are taken care by the normalizer.
+                 */
+                a = slapi_attr_new();
+                slapi_attr_init(a, ud_ptr->ud_type);
+                value = slapi_value_new_string(ud_ptr->ud_value);
+                slapi_attr_add_value(a, value);
+                slapi_value_free(&value);
+                attrlist_add(&e->e_deleted_attrs, a);
+            } else { /* except "entryrdn" */
+                ud_attr = attrlist_find(e->e_attrs, ud_ptr->ud_type);
+                if (ud_attr) {
+                    /* We have to normalize the orignal string to generate
+                       the key in the index.
+                     */
+                    a = attrlist_find(e->e_deleted_attrs, ud_ptr->ud_type);
+                    if (!a) {
+                        a = slapi_attr_new();
+                        slapi_attr_init(a, ud_ptr->ud_type);
+                    } else {
+                        a = attrlist_remove(&e->e_deleted_attrs,
+                                            ud_ptr->ud_type);
+                    }
+                    slapi_dn_normalize_case_original(ud_ptr->ud_value);
+                    value = slapi_value_new_string(ud_ptr->ud_value);
+                    slapi_attr_add_value(a, value);
+                    slapi_value_free(&value);
+                    attrlist_add(&e->e_deleted_attrs, a);
+                }
+            }
+        }
+        upgradedn_free_list(&ud_list);
+        if (skipit) {
+            slapi_entry_free(e); e = NULL;
+            continue;
+        }
+
+        ep = import_make_backentry(e, temp_id);
+        if (!ep) {
+            slapi_entry_free(e); e = NULL;
+            goto error;
+        }
+
+        /* Add the newly case-normalized dn to entrydn in the e_attrs list. */
+        add_update_entrydn_operational_attributes(ep);
+
+        if (job->flags & FLAG_ABORT)
+             goto error;
+
+        /* Now we have this new entry, all decoded
+         * Next thing we need to do is:
+         * (1) see if the appropriate fifo location contains an
+         *     entry which had been processed by the indexers.
+         *     If so, proceed.
+         *     If not, spin waiting for it to become free.
+         * (2) free the old entry and store the new one there.
+         * (3) Update the job progress indicators so the indexers
+         *     can use the new entry.
+         */
+        idx = id % job->fifo.size;
+        old_ep = job->fifo.item[idx].entry;
+        if (old_ep) {
+            /* for the slot to be recycled, it needs to be already absorbed
+             * by the foreman (id >= ready_EID), and all the workers need to
+             * be finished with it (refcount = 0).
+             */
+            while (((old_ep->ep_refcnt > 0) ||
+                    (old_ep->ep_id >= job->ready_EID))
+                   && (info->command != ABORT) && !(job->flags & FLAG_ABORT)) {
+                info->state = WAITING;
+                DS_Sleep(sleeptime);
+            }
+            if (job->flags & FLAG_ABORT)
+                goto error;
+
+            info->state = RUNNING;
+            PR_ASSERT(old_ep == job->fifo.item[idx].entry);
+            job->fifo.item[idx].entry = NULL;
+            if (job->fifo.c_bsize > job->fifo.item[idx].esize)
+                job->fifo.c_bsize -= job->fifo.item[idx].esize;
+            else
+                job->fifo.c_bsize = 0;
+            backentry_free(&old_ep);
+        }
+
+        newesize = (slapi_entry_size(ep->ep_entry) + sizeof(struct backentry));
+        if (newesize > job->fifo.bsize) {    /* entry too big */
+            char ebuf[BUFSIZ];
+            import_log_notice(job, "WARNING: skipping entry \"%s\"",
+                    escape_string(slapi_entry_get_dn(e), ebuf));
+            import_log_notice(job, "REASON: entry too large (%lu bytes) for "
+                    "the buffer size (%lu bytes)", newesize, job->fifo.bsize);
+            backentry_free(&ep);
+            job->skipped++;
+            continue;
+        }
+        /* Now check if fifo has enough space for the new entry */
+        if ((job->fifo.c_bsize + newesize) > job->fifo.bsize) {
+            import_wait_for_space_in_fifo( job, newesize );
+        }
+
+        /* We have enough space */
+        job->fifo.item[idx].filename = ID2ENTRY LDBM_FILENAME_SUFFIX;
+        job->fifo.item[idx].line = curr_entry;
+        job->fifo.item[idx].entry = ep;
+        job->fifo.item[idx].bad = 0;
+        job->fifo.item[idx].esize = newesize;
+
+        /* Add the entry size to total fifo size */
+        job->fifo.c_bsize += ep->ep_entry? job->fifo.item[idx].esize : 0;
+
+        /* Update the job to show our progress */
+        job->lead_ID = id;
+        if ((id - info->first_ID) <= job->fifo.size) {
+            job->trailing_ID = info->first_ID;
+        } else {
+            job->trailing_ID = id - job->fifo.size;
+        }
+
+        /* Update our progress meter too */
+        info->last_ID_processed = id;
+        id++;
+        if (job->flags & FLAG_ABORT)
+            goto error;
+        if (info->command == STOP)
+        {
+            finished = 1;
+        }
+    }
+bail:
+    dbc->c_close(dbc);
+    dblayer_release_aux_id2entry( be, db, env );
+    if (job->flags & FLAG_DRYRUN) {
+        if (finished) { /* Set if dn upgrade candidates are not found */
+            info->state = FINISHED;
+        } else { /* At least one dn upgrade candidate is found */
+            info->state = QUIT;
+        }
+    } else {
+        info->state = FINISHED;
+    }
+    return;
+
+error:
+    dbc->c_close(dbc);
+    dblayer_release_aux_id2entry( be, db, env );
+    info->state = ABORTED;
+}
+
 static void
 import_wait_for_space_in_fifo(ImportJob *job, size_t new_esize)
 {
@@ -1198,6 +1785,39 @@ foreman_do_entrydn(ImportJob *job, FifoItem *fi)
     int err = 0, ret = 0;
     IDList *IDL;
 
+    if (job->flags & FLAG_UPGRADEDNFORMAT) {
+        /* Get the entrydn attribute value from deleted attr list */
+        Slapi_Value *value = NULL;
+        Slapi_Attr *entrydn_to_del =
+              attrlist_remove(&fi->entry->ep_entry->e_deleted_attrs, "entrydn");
+
+        if (entrydn_to_del) {
+            /* Delete it. */
+            ret = slapi_attr_first_value(entrydn_to_del, &value);
+            if (ret < 0) {
+                import_log_notice(job, 
+                                  "Error: retrieving entrydn value (error %d)",
+                                  ret);
+            } else {
+                const struct berval *bval = 
+                             slapi_value_get_berval((const Slapi_Value *)value);
+                ret = index_addordel_string(be, "entrydn", 
+                             bval->bv_val,
+                             fi->entry->ep_id,
+                             BE_INDEX_DEL|BE_INDEX_EQUALITY|BE_INDEX_NORMALIZED,
+                             NULL);
+                if (ret) {
+                    import_log_notice(job, 
+                                      "Error: deleting %s from  entrydn index "
+                                      "(error %d: %s)",
+                                      bval->bv_val, ret, dblayer_strerror(ret));
+                    return ret;
+                }
+            }
+            slapi_attr_free(&entrydn_to_del);
+        }
+    }
+
     /* insert into the entrydn index */
     bv.bv_val = (void*)backentry_get_ndn(fi->entry);   /* jcm - Had to cast away const */
     bv.bv_len = strlen(bv.bv_val);
@@ -1210,29 +1830,49 @@ foreman_do_entrydn(ImportJob *job, FifoItem *fi)
     /* So, we do an index read first */
     err = 0;
     IDL = index_read(be, LDBM_ENTRYDN_STR, indextype_EQUALITY, &bv, NULL, &err);
-
-    /* Did this work ? */
-    if (NULL != IDL) {
-        /* IMPOSTER ! Get thee hence... */
-        import_log_notice(job, "WARNING: Skipping duplicate entry "
-                          "\"%s\" found at line %d of file \"%s\"",
-                          slapi_entry_get_dn(fi->entry->ep_entry),
-                          fi->line, fi->filename);
-        idl_free(IDL);
-        /* skip this one */
-        fi->bad = 1;
-        job->skipped++;
-        return -1;      /* skip to next entry */
-    }
-    if ((ret = index_addordel_string(be, LDBM_ENTRYDN_STR, 
-                                     bv.bv_val,
-                                     fi->entry->ep_id,
-                                     BE_INDEX_ADD|BE_INDEX_NORMALIZED, NULL)) != 0) {
-        import_log_notice(job, "Error writing entrydn index "
-                          "(error %d: %s)",
-                          ret, dblayer_strerror(ret));
-        return ret;
+    if (job->flags & FLAG_UPGRADEDNFORMAT) {
+        /*
+         * In the UPGRADEDNFORMAT case, if entrydn value exists, 
+         * that means entrydn is not upgraded. And it is normal.
+         * We could add entrydn only when the value is not found in the db.
+         */
+        if (IDL) {
+            idl_free(IDL);
+        } else {
+            ret = index_addordel_string(be, "entrydn", 
+                                        bv.bv_val, fi->entry->ep_id,
+                                        BE_INDEX_ADD|BE_INDEX_NORMALIZED, NULL);
+            if (ret) {
+                import_log_notice(job, "Error writing entrydn index "
+                                       "(error %d: %s)",
+                                       ret, dblayer_strerror(ret));
+                return ret;
+            }
+        }
+    } else {
+        /* Did this work ? */
+        if (IDL) {
+            /* IMPOSTER ! Get thee hence... */
+            import_log_notice(job, "WARNING: Skipping duplicate entry "
+                              "\"%s\" found at line %d of file \"%s\"",
+                              slapi_entry_get_dn(fi->entry->ep_entry),
+                              fi->line, fi->filename);
+            idl_free(IDL);
+            /* skip this one */
+            fi->bad = 1;
+            job->skipped++;
+            return -1;      /* skip to next entry */
+        }
+        ret = index_addordel_string(be, "entrydn", bv.bv_val, fi->entry->ep_id,
+                                    BE_INDEX_ADD|BE_INDEX_NORMALIZED, NULL);
+        if (ret) {
+            import_log_notice(job, "Error writing entrydn index "
+                                   "(error %d: %s)",
+                                   ret, dblayer_strerror(ret));
+            return ret;
+        }
     }
+
     return 0;
 }
 
@@ -1243,6 +1883,34 @@ foreman_do_entryrdn(ImportJob *job, FifoItem *fi)
     backend *be = job->inst->inst_be;
     int ret = 0;
 
+    if (job->flags & FLAG_UPGRADEDNFORMAT) {
+        /* Get the entrydn attribute value from deleted attr list */
+        Slapi_Value *value = NULL;
+        Slapi_Attr *entryrdn_to_del = NULL;
+        entryrdn_to_del = attrlist_remove(&fi->entry->ep_entry->e_deleted_attrs,
+                                          LDBM_ENTRYRDN_STR);
+        if (entryrdn_to_del) {
+            /* Delete it. */
+            ret = slapi_attr_first_value(entryrdn_to_del, &value);
+            if (ret < 0) {
+                import_log_notice(job, 
+                                  "Error: retrieving entryrdn value (error %d)",
+                                  ret);
+            } else {
+                const struct berval *bval = 
+                             slapi_value_get_berval((const Slapi_Value *)value);
+                ret = entryrdn_index_entry(be, fi->entry, BE_INDEX_DEL, NULL);
+                if (ret) {
+                    import_log_notice(job, 
+                                      "Error: deleting %s from  entrydn index "
+                                      "(error %d: %s)",
+                                      bval->bv_val, ret, dblayer_strerror(ret));
+                    return ret;
+                }
+            }
+            slapi_attr_free(&entryrdn_to_del);
+        }
+    }
     if ((ret = entryrdn_index_entry(be, fi->entry, BE_INDEX_ADD, NULL)) != 0) {
         import_log_notice(job, "Error writing entryrdn index "
                           "(error %d: %s)",
@@ -1294,7 +1962,8 @@ import_foreman(void *param)
         }
 
         while ( ((info->command == PAUSE) || (id > job->lead_ID)) &&
-                (info->command != STOP) && (info->command != ABORT)  && !(job->flags & FLAG_ABORT)) {
+                (info->command != STOP) && (info->command != ABORT) &&
+                !(job->flags & FLAG_ABORT) ) {
             /* Check to see if we've been told to stop */
             info->state = WAITING;
             DS_Sleep(sleeptime);
@@ -1335,9 +2004,9 @@ import_foreman(void *param)
              * Only check for a parent and add to the entry2dn index if
              * the entry is not a tombstone.
              */
-             if (job->flags & FLAG_ABORT) {       
-                 goto error;
-             }
+            if (job->flags & FLAG_ABORT) {       
+                goto error;
+            }
 
             if (parent_status == IMPORT_ADD_OP_ATTRS_NO_PARENT) {
                 /* If this entry is a suffix entry, this is not a problem */
@@ -1386,6 +2055,9 @@ import_foreman(void *param)
              * (that isn't really an index -- it's the storehouse of the entries
              * themselves.)
              */
+            /* id2entry_add_ext replaces an entry if it already exists. 
+             * therefore, the Entry ID stays the same.
+             */
             ret = id2entry_add_ext(be, fi->entry, NULL, job->encrypt);
             if (ret) {
                 /* DB_RUNRECOVERY usually occurs if disk fills */
@@ -1412,7 +2084,10 @@ import_foreman(void *param)
             goto error;
         }
 
-        if (! slapi_entry_flag_is_set(fi->entry->ep_entry,
+        if (!(job->flags & FLAG_UPGRADEDNFORMAT) && /* Upgrade dn format mode
+                                                       does not need to update
+                                                       parentid index */
+            !slapi_entry_flag_is_set(fi->entry->ep_entry,
                                       SLAPI_ENTRY_FLAG_TOMBSTONE)) {
             /* parentid index
              * (we have to do this here, because the parentID is dependent on
@@ -1427,9 +2102,9 @@ import_foreman(void *param)
                vlv code to see whether it's within the scope a VLV index. */
             vlv_grok_new_import_entry(fi->entry, be);
         }
-         if (job->flags & FLAG_ABORT) { 
-             goto error;
-         }
+        if (job->flags & FLAG_ABORT) { 
+            goto error;
+        }
 
 
         /* Remove the entry from the cache (Put in the cache in id2entry_add) */
@@ -1547,7 +2222,8 @@ import_worker(void *param)
                  * thread, and the state is neither STOP nor ABORT
                  */
             while (((info->command == PAUSE) || (id > job->ready_ID)) &&
-                   (info->command != STOP) && (info->command != ABORT) && !(job->flags & FLAG_ABORT)) {
+                   (info->command != STOP) && (info->command != ABORT) && 
+                   !(job->flags & FLAG_ABORT)) {
                 /* Check to see if we've been told to stop */
                 info->state = WAITING;
                 DS_Sleep(sleeptime);                
@@ -1594,6 +2270,43 @@ import_worker(void *param)
                 slapi_pblock_destroy(pb);
             } else {
                 /* No, process regular index */
+                if (job->flags & FLAG_UPGRADEDNFORMAT) {
+                    /* Get the attribute value from deleted attr list */
+                    Slapi_Value *value = NULL;
+                    const struct berval *bval = NULL;
+                    Slapi_Attr *key_to_del =
+                          attrlist_remove(&fi->entry->ep_entry->e_deleted_attrs,
+                                          info->index_info->name);
+            
+                    if (key_to_del) {
+                        int idx = 0;
+                        /* Delete it. */
+                        for (idx = slapi_attr_first_value(key_to_del, &value);
+                             idx >= 0;
+                             idx = slapi_attr_next_value(key_to_del, idx, 
+                                                                     &value)) {
+                            bval = 
+                             slapi_value_get_berval((const Slapi_Value *)value);
+                            ret = index_addordel_string(be, 
+                                         info->index_info->name, 
+                                         bval->bv_val,
+                                         fi->entry->ep_id,
+                                         BE_INDEX_DEL|BE_INDEX_EQUALITY|
+                                         BE_INDEX_NORMALIZED,
+                                         NULL);
+                            if (ret) {
+                                import_log_notice(job, 
+                                    "Error deleting %s from %s index "
+                                    "(error %d: %s)",
+                                     bval->bv_val, info->index_info->name,
+                                     ret, dblayer_strerror(ret));
+                                goto error;
+                            }
+                        }
+                        slapi_attr_free(&key_to_del);
+                    }
+                }
+
                 /* Look for the attribute we're indexing and its subtypes */
                 /* For each attr write to the index */
                 attrlist_cursor = NULL;
@@ -2488,6 +3201,7 @@ import_get_and_add_parent_rdns(ImportWorkerInfo *info,
             rc = 0; /* assume this is a suffix */
         } else {
             ID pid = (ID)strtol(pid_str, (char **)NULL, 10);
+            slapi_ch_free_string(&pid_str);
             rc = import_get_and_add_parent_rdns(info, inst, db, pid, total_id,
                                                 &mysrdn, curr_entry);
             if (rc) {

+ 220 - 118
ldap/servers/slapd/back-ldbm/import.c

@@ -51,6 +51,7 @@
 #include "import.h"
 
 #define ERR_IMPORT_ABORTED      -23
+#define DRYRUN_QUIT             -24
 
 
 /********** routines to manipulate the entry fifo **********/
@@ -193,8 +194,16 @@ void import_log_notice(ImportJob *job, char *format, ...)
         slapi_task_log_notice(job->task, "%s", buffer);
     }
     /* also save it in the logs for posterity */
-    LDAPDebug(LDAP_DEBUG_ANY, "import %s: %s\n", job->inst->inst_name,
-          buffer, 0);
+    if (job->flags & FLAG_UPGRADEDNFORMAT) {
+        LDAPDebug(LDAP_DEBUG_ANY, "upgradedn %s: %s\n", job->inst->inst_name,
+                  buffer, 0);
+    } else if (job->flags & FLAG_REINDEXING) {
+        LDAPDebug(LDAP_DEBUG_ANY, "reindex %s: %s\n", job->inst->inst_name,
+                  buffer, 0);
+    } else {
+        LDAPDebug(LDAP_DEBUG_ANY, "import %s: %s\n", job->inst->inst_name,
+                  buffer, 0);
+    }
 }
 
 static void import_task_destroy(Slapi_Task *task)
@@ -245,6 +254,22 @@ static int import_attr_callback(void *node, void *param)
     ImportJob *job = (ImportJob *)param;
     struct attrinfo *a = (struct attrinfo *)node;
 
+    if (job->flags & FLAG_DRYRUN) { /* dryrun; we don't need the workers */
+        return 0;
+    }
+    if (job->flags & FLAG_UPGRADEDNFORMAT) {
+        /* Bring up import workers just for indexes having DN syntax 
+         * attribute type. (except entrydn -- taken care below) */
+        int rc = 0;
+        Slapi_Attr attr = {0};
+        slapi_attr_init(&attr, a->ai_type);
+        rc = slapi_attr_is_dn_syntax_attr(&attr);
+        attr_done(&attr);
+        if (0 == rc) {
+            return 0;
+        }
+    }
+
     /* OK, so we now have hold of the attribute structure and the job info, 
      * let's see what we have.  Remember that although this function is called
      * many times, all these calls are in the context of a single thread, so we
@@ -255,29 +280,29 @@ static int import_attr_callback(void *node, void *param)
      * ancestorid indexes because we build those in the foreman thread.
      */
     if (IS_INDEXED(a->ai_indexmask) &&
-    (strcasecmp(a->ai_type, LDBM_ENTRYDN_STR) != 0) &&
-    (strcasecmp(a->ai_type, LDBM_ENTRYRDN_STR) != 0) &&
-    (strcasecmp(a->ai_type, LDBM_PARENTID_STR) != 0) &&
-    (strcasecmp(a->ai_type, LDBM_ANCESTORID_STR) != 0) &&
-    (strcasecmp(a->ai_type, numsubordinates) != 0)) {
-    /* Make an import_index_info structure, fill it in and insert into the
-     * job's list */
-    IndexInfo *info = CALLOC(IndexInfo);
+        (strcasecmp(a->ai_type, LDBM_ENTRYDN_STR) != 0) &&
+        (strcasecmp(a->ai_type, LDBM_ENTRYRDN_STR) != 0) &&
+        (strcasecmp(a->ai_type, LDBM_PARENTID_STR) != 0) &&
+        (strcasecmp(a->ai_type, LDBM_ANCESTORID_STR) != 0) &&
+        (strcasecmp(a->ai_type, numsubordinates) != 0)) {
+        /* Make an import_index_info structure, fill it in and insert into the
+         * job's list */
+        IndexInfo *info = CALLOC(IndexInfo);
     
-    if (NULL == info) {
-        /* Memory allocation error */
-        return -1;
-    }
-    info->name = slapi_ch_strdup(a->ai_type);
-    info->ai = a;
-    if (NULL == info->name) {
-        /* Memory allocation error */
-        FREE(info);
-        return -1;
-    }
-    info->next = job->index_list;
-    job->index_list = info;
-    job->number_indexers++;
+        if (NULL == info) {
+            /* Memory allocation error */
+            return -1;
+        }
+        info->name = slapi_ch_strdup(a->ai_type);
+        info->ai = a;
+        if (NULL == info->name) {
+            /* Memory allocation error */
+            FREE(info);
+            return -1;
+        }
+        info->next = job->index_list;
+        job->index_list = info;
+        job->number_indexers++;
     }
     return 0;
 }
@@ -402,12 +427,12 @@ static int import_start_threads(ImportJob *job)
     import_init_worker_info(foreman, job);
     foreman->work_type = FOREMAN;
     if (! CREATE_THREAD(PR_USER_THREAD, (VFP)import_foreman, foreman,
-            PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD,
-            PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE)) {    
+                        PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD,
+                        PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE)) {
         PRErrorCode prerr = PR_GetError();
         LDAPDebug(LDAP_DEBUG_ANY, "unable to spawn import foreman thread, "
-                SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
-                prerr, slapd_pr_strerror(prerr), 0);
+                  SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
+                  prerr, slapd_pr_strerror(prerr), 0);
         FREE(foreman);
         goto error;
     }
@@ -659,7 +684,7 @@ static int import_monitor_threads(ImportJob *job, int *status)
     time_t time_now = 0;
     time_t last_time = 0;
     time_t time_interval = 0;
-
+    int rc = 0;
 
     for (current_worker = job->worker_list; current_worker != NULL; 
          current_worker = current_worker->next) {
@@ -722,7 +747,10 @@ static int import_monitor_threads(ImportJob *job, int *status)
                 import_calc_rate(current_worker, time_interval);
                 import_print_worker_status(current_worker);
             }
-            if (current_worker->state != FINISHED) {
+            if (current_worker->state == QUIT) {
+                rc = DRYRUN_QUIT; /* Set the RC; Don't abort now; 
+                                     We have to stop other threads */
+            } else if (current_worker->state != FINISHED) {
                 finished = 0;
             }
             if (current_worker->state == ABORTED) {
@@ -765,8 +793,10 @@ static int import_monitor_threads(ImportJob *job, int *status)
 
         /* if the producer is finished, and the foreman has caught up... */
         if (producer) {
-            producer_done = (producer->state == FINISHED);
+            producer_done = (producer->state == FINISHED) ||
+                            (producer->state == QUIT);
         } else {
+            /* set in ldbm_back_wire_import */
             producer_done = (job->flags & FLAG_PRODUCER_DONE);
         }
         if (producer_done && (job->lead_ID == job->ready_ID)) {
@@ -802,6 +832,7 @@ static int import_monitor_threads(ImportJob *job, int *status)
     for (current_worker = job->worker_list; current_worker != NULL; ) {
         if ((current_worker->state != FINISHED) &&
             (current_worker->state != ABORTED) &&
+            (current_worker->state != QUIT) &&
             (current_worker->work_type != PRODUCER)) {
             DS_Sleep(tenthsecond);    /* Only sleep if we hit a thread that is still not done */
             continue;
@@ -826,7 +857,7 @@ static int import_monitor_threads(ImportJob *job, int *status)
     } else {
         *status = IMPORT_COMPLETE_PASS;
     }
-    return 0;
+    return rc;
 
 error_abort:
     return ERR_IMPORT_ABORTED;
@@ -843,16 +874,16 @@ static int import_run_pass(ImportJob *job, int *status)
     ret = import_start_threads(job);
     if (ret != 0) {
         import_log_notice(job, "Starting threads failed: %d\n", ret);
-    goto error;
+        goto error;
     }
 
     /* Monitor the threads until we're done or fail */
     ret = import_monitor_threads(job, status);
-    if (ret == ERR_IMPORT_ABORTED) {
+    if ((ret == ERR_IMPORT_ABORTED) || (ret == DRYRUN_QUIT)) {
         goto error;
     } else if (ret != 0) {
         import_log_notice(job, "Thread monitoring aborted: %d\n", ret);
-    goto error;
+        goto error;
     }
 
 error:
@@ -876,20 +907,18 @@ static void import_set_abort_flag_all(ImportJob *job, int wait_for_them)
         /* allow all the aborts to be processed */
              DS_Sleep(PR_MillisecondsToInterval(3000)); 
 
-     if (wait_for_them) {
+    if (wait_for_them) {
         /* Having done that, wait for them to say that they've stopped */
         for (worker = job->worker_list; worker != NULL; ) {
             DS_Sleep(PR_MillisecondsToInterval(100));
-            if ((worker->state != FINISHED) &&
-                (worker->state != ABORTED)){
+            if ((worker->state != FINISHED) && (worker->state != ABORTED) &&
+                (worker->state != QUIT)){
                 continue;
-        }
-            else{
+            } else {
                 worker = worker->next;
-        }
+            }
         }
     }
-
 }
 
 
@@ -908,11 +937,12 @@ void import_abort_all(ImportJob *job, int wait_for_them)
         /* Having done that, wait for them to say that they've stopped */
         for (worker = job->worker_list; worker != NULL; ) {
             DS_Sleep(PR_MillisecondsToInterval(100));
-            if ((worker->state != FINISHED) &&
-                (worker->state != ABORTED))
+            if ((worker->state != FINISHED) && (worker->state != ABORTED) &&
+                (worker->state != QUIT)) {
                 continue;
-            else
+            } else {
                 worker = worker->next;
+            }
         }
     }
 }
@@ -1019,13 +1049,13 @@ static int import_all_done(ImportJob *job, int ret)
     ldbm_instance *inst = job->inst;
 
     /* Writing this file indicates to future server startups that
-     * the db is OK */
-    if (ret == 0) {
+     * the db is OK unless it's in the dry run mode. */
+    if ((ret == 0) && !(job->flags & FLAG_DRYRUN)) {
         char inst_dir[MAXPATHLEN*2];
         char *inst_dirp = NULL;
         inst_dirp = dblayer_get_full_inst_dir(inst->inst_li, inst,
                                               inst_dir, MAXPATHLEN*2);
-        ret = dbversion_write(inst->inst_li, inst_dirp, NULL);
+        ret = dbversion_write(inst->inst_li, inst_dirp, NULL, DBVERSION_ALL);
         if (inst_dirp != inst_dir)
             slapi_ch_free_string(&inst_dirp);
     }
@@ -1078,10 +1108,20 @@ int import_main_offline(void *arg)
     int verbose = 1;
     int aborted = 0;
     ImportWorkerInfo *producer = NULL;
+    char *opstr = "Import";
 
     if (job->task)
         slapi_task_inc_refcount(job->task);
 
+    if (job->flags & FLAG_UPGRADEDNFORMAT) {
+        if (job->flags & FLAG_DRYRUN) {
+            opstr = "Upgrade Dn Dryrun";
+        } else {
+            opstr = "Upgrade Dn";
+        }
+    } else if (job->flags & FLAG_REINDEXING) {
+        opstr = "Reindexing";
+    }
     PR_ASSERT(inst != NULL);
     time(&beginning);
 
@@ -1120,7 +1160,20 @@ int import_main_offline(void *arg)
         /* start the producer */
         import_init_worker_info(producer, job);
         producer->work_type = PRODUCER;
-        if (job->flags & FLAG_REINDEXING)
+        if (job->flags & FLAG_UPGRADEDNFORMAT)
+        {
+            if (! CREATE_THREAD(PR_USER_THREAD, (VFP)upgradedn_producer, 
+                producer, PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD,
+                PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE)) {
+                PRErrorCode prerr = PR_GetError();
+                LDAPDebug(LDAP_DEBUG_ANY,
+                          "unable to spawn upgrade dn producer thread, "
+                          SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
+                          prerr, slapd_pr_strerror(prerr), 0);
+                goto error;
+            }
+        }
+        else if (job->flags & FLAG_REINDEXING)
         {
             if (! CREATE_THREAD(PR_USER_THREAD, (VFP)index_producer, producer,
                 PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD,
@@ -1128,9 +1181,9 @@ int import_main_offline(void *arg)
                 SLAPD_DEFAULT_THREAD_STACKSIZE)) {
                 PRErrorCode prerr = PR_GetError();
                 LDAPDebug(LDAP_DEBUG_ANY,
-                    "unable to spawn index producer thread, "
-                    SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
-                    prerr, slapd_pr_strerror(prerr), 0);
+                          "unable to spawn index producer thread, "
+                          SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
+                          prerr, slapd_pr_strerror(prerr), 0);
                 goto error;
             }
         }
@@ -1189,15 +1242,18 @@ int import_main_offline(void *arg)
         if (ret == ERR_IMPORT_ABORTED) {
             /* at least one of the threads has aborted -- shut down ALL
              * of the threads */
-            import_log_notice(job, "Aborting all import threads...");
+            import_log_notice(job, "Aborting all %s threads...", opstr);
             /* this abort sets the  abort flag on the threads and will block for 
              * the exit of all threads 
              */
             import_set_abort_flag_all(job, 1); 
-            import_log_notice(job, "Import threads aborted.");
+            import_log_notice(job, "%s threads aborted.", opstr);
             aborted = 1;
             goto error;
         }
+        if (ret == DRYRUN_QUIT) {
+            goto error; /* Found the candidate; close the db files and quit */
+        }
 
         if (0 != ret) {
             /* Some horrible fate has befallen the import */
@@ -1297,7 +1353,8 @@ int import_main_offline(void *arg)
      * Database. */
         
 error:
-    /* If we fail, the database is now in a mess, so we delete it */
+    /* If we fail, the database is now in a mess, so we delete it 
+       except dry run mode */
     import_log_notice(job, "Closing files...");
     cache_clear(&job->inst->inst_cache, CACHE_TYPE_ENTRY);
     if (entryrdn_get_switch()) {
@@ -1324,7 +1381,10 @@ error:
         }
     }
     if (0 != ret) {
-        dblayer_delete_instance_dir(be);
+        if (!(job->flags & FLAG_DRYRUN)) { /* If not dryrun */
+            /* if running in the dry run mode, don't touch the db */
+            dblayer_delete_instance_dir(be);
+        }
         dblayer_instance_close(job->inst->inst_be);
     } else {
         if (0 != (ret = dblayer_instance_close(job->inst->inst_be)) ) {
@@ -1338,52 +1398,82 @@ error:
     if (verbose && (0 == ret)) {
         int seconds_to_import = end - beginning;
         size_t entries_processed = job->lead_ID - (job->starting_ID - 1);
-        double entries_per_second = (double) entries_processed / 
-                                    (double) seconds_to_import;
-
-        if (job->not_here_skipped)
-        {
-            if (job->skipped)
-                import_log_notice(job, "Import complete.  Processed %lu entries "
-                    "(%d bad entries were skipped, "
-                    "%d entries were skipped because they don't "
-                    "belong to this database) in %d seconds. "
-                    "(%.2f entries/sec)", entries_processed,
-                    job->skipped, job->not_here_skipped,
-                    seconds_to_import, entries_per_second);
-                else
-                    import_log_notice(job, "Import complete.  Processed %lu entries "
-                        "(%d entries were skipped because they don't "
-                        "belong to this database) "
-                        "in %d seconds. (%.2f entries/sec)",
-                        entries_processed, job->not_here_skipped,
-                        seconds_to_import, entries_per_second);
-        }
-        else
-        {
-            if (job->skipped)
-                import_log_notice(job, "Import complete.  Processed %lu entries "
-                    "(%d were skipped) in %d seconds. "
-                    "(%.2f entries/sec)", entries_processed,
-                    job->skipped, seconds_to_import,
-                    entries_per_second);
-            else
-                import_log_notice(job, "Import complete.  Processed %lu entries "
-                    "in %d seconds. (%.2f entries/sec)",
-                    entries_processed, seconds_to_import,
-                    entries_per_second);
+        double entries_per_second = 
+                    seconds_to_import ?
+                    (double)entries_processed / (double)seconds_to_import : 0;
+
+        if (job->not_here_skipped) {
+            if (job->skipped) {
+                import_log_notice(job, 
+                            "%s complete.  Processed %lu entries " 
+                            "(%d bad entries were skipped, "
+                            "%d entries were skipped because they don't "
+                            "belong to this database) in %d seconds. "
+                            "(%.2f entries/sec)", 
+                            opstr, entries_processed,
+                            job->skipped, job->not_here_skipped,
+                            seconds_to_import, entries_per_second);
+            } else {
+                import_log_notice(job, 
+                            "%s complete.  Processed %lu entries "
+                            "(%d entries were skipped because they don't "
+                            "belong to this database) "
+                            "in %d seconds. (%.2f entries/sec)",
+                            opstr, entries_processed, 
+                            job->not_here_skipped, seconds_to_import, 
+                            entries_per_second);
+            }
+        } else {
+            if (job->skipped) {
+                import_log_notice(job, 
+                            "%s complete.  Processed %lu entries "
+                            "(%d were skipped) in %d seconds. "
+                            "(%.2f entries/sec)", 
+                            opstr, entries_processed,
+                            job->skipped, seconds_to_import,
+                            entries_per_second);
+            } else {
+                import_log_notice(job, 
+                            "%s complete.  Processed %lu entries "
+                            "in %d seconds. (%.2f entries/sec)",
+                            opstr, entries_processed, 
+                            seconds_to_import, entries_per_second);
+            }
         }
     }
 
-    if (0 != ret) {
-        import_log_notice(job, "Import failed.");
+    if (job->flags & FLAG_DRYRUN) {
+        if (0 == ret) {
+            import_log_notice(job, "%s complete.  %s is up-to-date.", 
+                              opstr, job->inst->inst_name);
+            ret = 1;
+            if (job->task) {
+                slapi_task_dec_refcount(job->task);
+            }
+            import_all_done(job, ret);
+        } else if (DRYRUN_QUIT == ret) {
+            import_log_notice(job, "%s complete.  %s needs upgradednformat.", 
+                              opstr, job->inst->inst_name);
+            if (job->task) {
+                slapi_task_dec_refcount(job->task);
+            }
+            import_all_done(job, ret);
+            ret = 0;
+        } else {
+            ret = -1;
+            if (job->task != NULL) {
+                slapi_task_finish(job->task, ret);
+            }
+        }
+    } else if (0 != ret) {
+        import_log_notice(job, "%s failed.", opstr);
         if (job->task != NULL) {
             slapi_task_finish(job->task, ret);
         }
     } else {
-        if (job->task)
+        if (job->task) {
             slapi_task_dec_refcount(job->task);
-
+        }
         import_all_done(job, ret);
     }
 
@@ -1393,7 +1483,6 @@ error:
     import_free_job(job);
     if (producer)
         FREE(producer);
-
     
     return(ret);
 }
@@ -1430,6 +1519,8 @@ int ldbm_back_ldif2ldbm_deluxe(Slapi_PBlock *pb)
     job->inst = (ldbm_instance *)be->be_instance_info;
     slapi_pblock_get( pb, SLAPI_LDIF2DB_NOATTRINDEXES, &noattrindexes );
     slapi_pblock_get( pb, SLAPI_LDIF2DB_FILE, &name_array );
+    slapi_pblock_get(pb, SLAPI_SEQ_TYPE, &up_flags); /* For upgrade dn and
+                                                        dn2rdn */
 
     /* the removedupvals field is blatantly overloaded here to mean
      * the chunk size too.  (chunk size = number of entries that should
@@ -1454,27 +1545,37 @@ int ldbm_back_ldif2ldbm_deluxe(Slapi_PBlock *pb)
         job->uuid_namespace = slapi_ch_strdup(namespaceid);
     }
 
-    slapi_pblock_get(pb, SLAPI_SEQ_TYPE, &up_flags);
     job->flags = FLAG_USE_FILES;
-    if (NULL == name_array) {    /* no ldif file is given */
-        job->flags |= FLAG_REINDEXING; /* call index_producer */
-        if (up_flags & SLAPI_UPGRADEDB_DN2RDN) {
-            if (entryrdn_get_switch()) {
-                job->flags |= FLAG_DN2RDN; /* migrate to the rdn format */
-            } else {
-                LDAPDebug1Arg(LDAP_DEBUG_ANY, "DN to RDN option is specified, "
-                                              "but %s is not enabled\n",
-                                              CONFIG_ENTRYRDN_SWITCH);
-                import_free_job(job);
-                FREE(job);
-                return -1;
+    if (NULL == name_array) {    /* no ldif file is given -> reindexing or
+                                                             upgradedn */
+        if (up_flags & SLAPI_UPGRADEDNFORMAT) {
+            job->flags |= FLAG_UPGRADEDNFORMAT;
+            if (up_flags & SLAPI_DRYRUN) {
+                job->flags |= FLAG_DRYRUN;
+            }
+        } else {
+            job->flags |= FLAG_REINDEXING; /* call index_producer */
+            if (up_flags & SLAPI_UPGRADEDB_DN2RDN) {
+                if (entryrdn_get_switch()) {
+                    job->flags |= FLAG_DN2RDN; /* migrate to the rdn format */
+                } else {
+                    LDAPDebug1Arg(LDAP_DEBUG_ANY,
+                                  "DN to RDN option is specified, "
+                                  "but %s is not enabled\n",
+                                  CONFIG_ENTRYRDN_SWITCH);
+                    import_free_job(job);
+                    FREE(job);
+                    return -1;
+                }
             }
         }
     }
-    if (!noattrindexes)
-    job->flags |= FLAG_INDEX_ATTRS;
-    for (i = 0; name_array && name_array[i] != NULL; i++)
+    if (!noattrindexes) {
+        job->flags |= FLAG_INDEX_ATTRS;
+    }
+    for (i = 0; name_array && name_array[i] != NULL; i++) {
         charray_add(&job->input_filenames, slapi_ch_strdup(name_array[i]));
+    }
     job->starting_ID = 1;
     job->first_ID = 1;
     job->mothers = CALLOC(import_subcount_stuff);
@@ -1482,10 +1583,10 @@ int ldbm_back_ldif2ldbm_deluxe(Slapi_PBlock *pb)
     /* how much space should we allocate to index buffering? */
     job->job_index_buffer_size = import_get_index_buffer_size();
     if (job->job_index_buffer_size == 0) {
-    /* 10% of the allocated cache size + one meg */
+        /* 10% of the allocated cache size + one meg */
         PR_Lock(job->inst->inst_li->li_config_mutex);
-    job->job_index_buffer_size = (job->inst->inst_li->li_import_cachesize/10) +
-            (1024*1024);
+        job->job_index_buffer_size = 
+               (job->inst->inst_li->li_import_cachesize/10) + (1024*1024);
         PR_Unlock(job->inst->inst_li->li_config_mutex);
     }
     import_subcount_stuff_init(job->mothers);
@@ -1498,12 +1599,13 @@ int ldbm_back_ldif2ldbm_deluxe(Slapi_PBlock *pb)
         /* add 1 to account for post-import cleanup (which can take a
          * significant amount of time)
          */
-    /* NGK - This should eventually be cleaned up to use the public
-     * task API. */
-    if (0 == total_files)    /* reindexing */
+        /* NGK - This should eventually be cleaned up to use the public
+         * task API. */
+        if (0 == total_files) {    /* reindexing */
             job->task->task_work = 2;
-    else
+        } else {
             job->task->task_work = total_files + 1;
+        }
         job->task->task_progress = 0;
         job->task->task_state = SLAPI_TASK_RUNNING;
         slapi_task_set_data(job->task, job);

+ 11 - 7
ldap/servers/slapd/back-ldbm/import.h

@@ -159,12 +159,14 @@ typedef struct {
 
 #define FLAG_INDEX_ATTRS	0x01	/* should we index the attributes? */
 #define FLAG_USE_FILES		0x02	/* import from files */
-#define FLAG_PRODUCER_DONE      0x04    /* frontend is done sending entries
-                                         * for replica initialization */
-#define FLAG_ABORT              0x08    /* import has been aborted */
-#define FLAG_ONLINE             0x10    /* bring backend online when done */
-#define FLAG_REINDEXING         0x20    /* read from id2entry and do indexing */
-#define FLAG_DN2RDN             0x40    /* modify backend to the rdn format */
+#define FLAG_PRODUCER_DONE      0x04  /* frontend is done sending entries
+                                       * for replica initialization */
+#define FLAG_ABORT              0x08  /* import has been aborted */
+#define FLAG_ONLINE             0x10  /* bring backend online when done */
+#define FLAG_REINDEXING         0x20  /* read from id2entry and do indexing */
+#define FLAG_DN2RDN             0x40  /* modify backend to the rdn format */
+#define FLAG_UPGRADEDNFORMAT    0x80  /* read from id2entry and do upgrade dn */
+#define FLAG_DRYRUN             0x100 /* dryrun for upgrade dn */
 
 
 /* Structure holding stuff about a worker thread and what it's up to */
@@ -198,7 +200,8 @@ struct _import_worker_info {
 #define WAITING 1
 #define RUNNING 2
 #define FINISHED 3
-#define ABORTED 4 
+#define ABORTED 4
+#define QUIT 5 /* quit intentionally. to distinguish from ABORTED & FINISHED */
 
 /* this is just a convenience, because the slapi_ch_* calls are annoying */
 #define CALLOC(name)	(name *)slapi_ch_calloc(1, sizeof(name))
@@ -235,5 +238,6 @@ int add_op_attrs(Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *ep,
 /* import-threads.c */
 void import_producer(void *param);
 void index_producer(void *param);
+void upgradedn_producer(void *param);
 void import_foreman(void *param);
 void import_worker(void *param);

+ 2 - 0
ldap/servers/slapd/back-ldbm/init.c

@@ -227,6 +227,8 @@ ldbm_back_init( Slapi_PBlock *pb )
 	    (void *) ldbm_back_ldbm2archive );
 	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_UPGRADEDB_FN,
 	    (void *) ldbm_back_upgradedb );
+	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_UPGRADEDNFORMAT_FN,
+	    (void *) ldbm_back_upgradednformat );
 	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_DBVERIFY_FN,
 	    (void *) ldbm_back_dbverify );
 	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_BEGIN_FN,

+ 28 - 4
ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c

@@ -999,7 +999,9 @@ entryrdn_lookup_dn(backend *be,
     static char buffer[RDN_BULK_FETCH_BUFFER_SIZE]; 
     char *keybuf = NULL;
     Slapi_RDN *srdn = NULL;
+    char *orignrdn = NULL;
     char *nrdn = NULL;
+    size_t nrdn_len = 0;
     ID workid = id; /* starting from the given id */
     ID previd = id;
     rdn_elem *elem = NULL;
@@ -1037,8 +1039,18 @@ entryrdn_lookup_dn(backend *be,
         goto bail;
     }
     srdn = slapi_rdn_new_all_dn(rdn);
-    nrdn = slapi_ch_strdup(rdn);
-    slapi_dn_normalize_case(nrdn); /* normalize in place */
+    orignrdn = slapi_ch_strdup(rdn);
+    rc = slapi_dn_normalize_case_ext(orignrdn, 0, &nrdn, &nrdn_len);
+    if (rc < 0) {
+        slapi_log_error(SLAPI_LOG_FATAL, ENTRYRDN_TAG,
+                "entryrdn_get_parent: Failed to normalize %s\n", rdn);
+        goto bail;
+    }
+    if (rc == 0) { /* orignrdn is passed in */
+        *(nrdn + nrdn_len) = '\0';
+    } else {
+        slapi_ch_free_string(&orignrdn);
+    }
 
     /* Setting the bulk fetch buffer */
     memset(&data, 0, sizeof(data));
@@ -1159,7 +1171,9 @@ entryrdn_get_parent(backend *be,
     DB_TXN *db_txn = (txn != NULL) ? txn->back_txn_txn : NULL;
     DBT key, data;
     char *keybuf = NULL;
+    char *orignrdn = NULL;
     char *nrdn = NULL;
+    size_t nrdn_len = 0;
     rdn_elem *elem = NULL;
 
     slapi_log_error(SLAPI_LOG_TRACE, ENTRYRDN_TAG,
@@ -1195,8 +1209,18 @@ entryrdn_get_parent(backend *be,
         cursor = NULL;
         goto bail;
     }
-    nrdn = slapi_ch_strdup(rdn);
-    slapi_dn_normalize_case(nrdn); /* normalize in place */
+    orignrdn = slapi_ch_strdup(rdn);
+    rc = slapi_dn_normalize_case_ext(orignrdn, 0, &nrdn, &nrdn_len);
+    if (rc < 0) {
+        slapi_log_error(SLAPI_LOG_FATAL, ENTRYRDN_TAG,
+                "entryrdn_get_parent: Failed to normalize %s\n", rdn);
+        goto bail;
+    }
+    if (rc == 0) { /* orignrdn is passed in */
+        *(nrdn + nrdn_len) = '\0';
+    } else {
+        slapi_ch_free_string(&orignrdn);
+    }
 
     /* Setting the bulk fetch buffer */
     memset(&data, 0, sizeof(data));

+ 229 - 8
ldap/servers/slapd/back-ldbm/ldif2ldbm.c

@@ -2438,7 +2438,7 @@ ldbm_exclude_attr_from_export( struct ldbminfo *li , const char *attr,
 void upgradedb_core(Slapi_PBlock *pb, ldbm_instance *inst);
 int upgradedb_copy_logfiles(struct ldbminfo *li, char *destination_dir, int restore, int *cnt);
 int upgradedb_delete_indices_4cmd(ldbm_instance *inst, int flags);
-void normalize_dir(char *dir);
+static void normalize_dir(char *dir);
 
 /*
  * ldbm_back_upgradedb - 
@@ -2467,6 +2467,7 @@ int ldbm_back_upgradedb(Slapi_PBlock *pb)
     char *inst_dirp = NULL;
     int cnt = 0;
     PRFileInfo info = {0};
+    PRUint32 dbversion_flags = DBVERSION_ALL;
                                                                          
     slapi_pblock_get(pb, SLAPI_SEQ_TYPE, &up_flags);
     slapi_log_error(SLAPI_LOG_TRACE, "upgrade DB", "Reindexing all...\n");
@@ -2685,15 +2686,19 @@ int ldbm_back_upgradedb(Slapi_PBlock *pb)
     home_dir = dblayer_get_home_dir(li, NULL);
 
     /* write db version files */
-    dbversion_write(li, home_dir, NULL);
+    dbversion_write(li, home_dir, NULL, DBVERSION_ALL);
 
+    if ((up_flags & SLAPI_UPGRADEDB_DN2RDN) && entryrdn_get_switch()) {
+        /* exclude dnformat to allow upgradednformat later */
+        dbversion_flags = DBVERSION_ALL ^ DBVERSION_DNFORMAT;;
+    }
     inst_obj = objset_first_obj(li->li_instance_set);
     while (NULL != inst_obj)
     {
         char *inst_dirp = NULL;
         inst_dirp = dblayer_get_full_inst_dir(li, inst, inst_dir, MAXPATHLEN);
         inst = (ldbm_instance *)object_get_data(inst_obj);
-        dbversion_write(li, inst_dirp, NULL);
+        dbversion_write(li, inst_dirp, NULL, dbversion_flags);
         inst_obj = objset_next_obj(li->li_instance_set, inst_obj);
         if (inst_dirp != inst_dir)
             slapi_ch_free_string(&inst_dirp);
@@ -2781,15 +2786,26 @@ fail0:
     return rval;
 }
 
-void normalize_dir(char *dir)
+static void
+normalize_dir(char *dir)
 {
-    int l = strlen(dir);
-    if ('/' == dir[l-1] || '\\' == dir[l-1])
-    {
-        dir[l-1] = '\0';
+    char *p = NULL;
+    int l = 0;
+
+    if (NULL == dir) {
+        return;
     }
+    l = strlen(dir);
+
+    for (p = dir + l - 1; p && *p; p--) {
+        if (' ' != *p && '\t' != *p && '/' != *p && '\\' != *p) {
+            break;
+        }
+    }
+    *(p+1) = '\0';
 }
 
+
 #define LOG    "log."
 #define LOGLEN    4
 int upgradedb_copy_logfiles(struct ldbminfo *li, char *destination_dir,
@@ -3330,3 +3346,208 @@ bail:
     slapi_ch_free_string(&prdn);
     return rc;
 }
+
+/*
+ * ldbm_back_upgradednformat 
+ *
+ * Update old DN format in entrydn and the leaf attr value to the new one
+ *
+ * The implementation would be similar to the upgradedb for new idl.
+ * Scan each entry, checking the entrydn value with the result of 
+ * slapi_dn_normalize_ext_case(dn).
+ * If they don't match,
+ *   replace the old entrydn value with the new one in the entry 
+ *   in id2entry.db4.
+ *   also get the leaf RDN attribute value, unescape it, and check 
+ *   if it is in the entry.  If not, add it.
+ * Then, update the key in the entrydn index and the leaf RDN attribute
+ * (if need it).
+ *
+ * Return value:  0: success (the backend instance includes update 
+ *                   candidates for DRYRUN mode)
+ *                1: the backend instance is up-to-date (DRYRUN mode only)
+ *               -1: error
+ *
+ * standalone only -- not allowed to run while DS is up.
+ */
+int ldbm_back_upgradednformat(Slapi_PBlock *pb)
+{
+    int rc = -1;
+    struct ldbminfo *li = NULL;
+    int run_from_cmdline = 0;
+    int task_flags = 0;
+    int server_running = 0;
+    Slapi_Task *task;
+    ldbm_instance *inst = NULL;
+    char *instance_name = NULL;
+    backend *be = NULL;
+    PRStatus prst = 0;
+    PRFileInfo prfinfo = {0};
+    PRDir *dirhandle = NULL;
+    PRDirEntry *direntry = NULL;
+    size_t id2entrylen = 0;
+    int found = 0;
+    char *rawworkdbdir = NULL;
+    char *workdbdir = NULL;
+    char *origdbdir = NULL;
+    char *origlogdir = NULL;
+    char *originstparentdir = NULL;
+    char *sep = NULL;
+    char *ldbmversion = NULL;
+    char *dataversion = NULL;
+    int ud_flags = 0;
+                                                                         
+    slapi_pblock_get(pb, SLAPI_TASK_FLAGS, &task_flags);
+    slapi_pblock_get(pb, SLAPI_BACKEND_TASK, &task);
+    slapi_pblock_get(pb, SLAPI_DB2LDIF_SERVER_RUNNING, &server_running);
+    slapi_pblock_get(pb, SLAPI_BACKEND_INSTANCE_NAME, &instance_name);
+    slapi_pblock_get( pb, SLAPI_SEQ_TYPE, &ud_flags ); 
+
+    run_from_cmdline = (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE);
+    slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &li);
+    if (run_from_cmdline) {
+        ldbm_config_load_dse_info(li);
+        if (check_and_set_import_cache(li) < 0) {
+            return -1;
+        }
+    } else {
+        slapi_log_error(SLAPI_LOG_FATAL, "Upgrade DN Format",
+                        " Online mode is not supported. "
+                        "Shutdown the server and run the tool\n");
+        goto bail;
+    }
+
+    /* Find the instance that the ldif2db will be done on. */
+    inst = ldbm_instance_find_by_name(li, instance_name);
+    if (NULL == inst) {
+        slapi_log_error(SLAPI_LOG_FATAL, "Upgrade DN Format",
+                        "Unknown ldbm instance %s\n", instance_name);
+        goto bail;
+    }
+    slapi_log_error(SLAPI_LOG_FATAL, "Upgrade DN Format",
+                    "%s: Start upgrade dn format.\n", inst->inst_name);
+
+    slapi_pblock_set(pb, SLAPI_BACKEND, inst->inst_be);
+    slapi_pblock_get(pb, SLAPI_SEQ_VAL, &rawworkdbdir);
+    normalize_dir(rawworkdbdir); /* remove trailing spaces and slashes */
+
+    prst = PR_GetFileInfo(rawworkdbdir, &prfinfo);
+    if (PR_FAILURE == prst || PR_FILE_DIRECTORY != prfinfo.type) {
+        slapi_log_error(SLAPI_LOG_FATAL, "Upgrade DN Format",
+                        "Working DB instance dir %s is not a directory\n",
+                        rawworkdbdir);
+        goto bail;
+    }
+    dirhandle = PR_OpenDir(rawworkdbdir);
+    if (!dirhandle)
+    {
+        slapi_log_error(SLAPI_LOG_FATAL, "Upgrade DN Format",
+                        "Failed to open working DB instance dir %s\n",
+                        rawworkdbdir);
+        goto bail;
+    }
+    id2entrylen = strlen(ID2ENTRY);
+    while ((direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) {
+        if (!direntry->name)
+            break;
+        if (0 == strncasecmp(ID2ENTRY, direntry->name, id2entrylen)) {
+            found = 1;
+            break;
+        }
+    }
+    PR_CloseDir(dirhandle);
+
+    if (!found) {
+        slapi_log_error(SLAPI_LOG_FATAL, "Upgrade DN Format",
+                        "Working DB instance dir %s does not include %s file\n",
+                        rawworkdbdir, ID2ENTRY);
+        goto bail;
+    }
+
+    if (run_from_cmdline) {
+        ldbm_config_internal_set(li, CONFIG_DB_TRANSACTION_LOGGING, "off");
+    }
+
+    /* We have to work on the copied db.  So, the path should be set here. */
+    origdbdir = li->li_directory;
+    origlogdir = li->li_dblayer_private->dblayer_log_directory;
+    originstparentdir = inst->inst_parent_dir_name;
+
+    workdbdir = rel2abspath(rawworkdbdir);
+
+    dbversion_read(li, workdbdir, &ldbmversion, &dataversion);
+    if (ldbmversion && PL_strstr(ldbmversion, BDB_DNFORMAT)) {
+        slapi_log_error(SLAPI_LOG_FATAL, "Upgrade DN Format",
+                        "Instance %s in %s is up-to-date\n", 
+                        instance_name, workdbdir);
+        rc = 1; /* 1: up-to-date; 0: need upgrade; otherwise: error */
+        goto bail;
+    }
+
+    sep = PL_strrchr(workdbdir, '/');
+    if (!sep) {
+        slapi_log_error(SLAPI_LOG_FATAL, "Upgrade DN Format",
+                        "Working DB instance dir %s does not include %s file\n",
+                        workdbdir, ID2ENTRY);
+        goto bail;
+    }
+    *sep = '\0';
+    li->li_directory = workdbdir;
+    li->li_dblayer_private->dblayer_log_directory = workdbdir;
+    inst->inst_parent_dir_name = workdbdir;
+    
+    if (run_from_cmdline) {
+        if (0 != dblayer_start(li, DBLAYER_IMPORT_MODE)) {
+            slapi_log_error(SLAPI_LOG_FATAL, "Upgrade DN Format",
+                            "Failed to init database\n");
+            goto bail;
+        }
+    }
+
+    /* dblayer_instance_start will init the id2entry index. */
+    be = inst->inst_be;
+    if (0 != dblayer_instance_start(be, DBLAYER_IMPORT_MODE))
+    {
+        slapi_log_error(SLAPI_LOG_FATAL, "Upgrade DB Format",
+                    "Failed to init instance %s\n", inst->inst_name);
+        goto bail;
+    }
+
+    if (run_from_cmdline) {
+        vlv_init(inst);    /* Initialise the Virtual List View code */
+    }
+
+    rc = ldbm_back_ldif2ldbm_deluxe(pb);
+
+    /* close the database */
+    if (run_from_cmdline) {
+        if (0 != dblayer_flush(li)) {
+            slapi_log_error(SLAPI_LOG_FATAL, "Upgrade DN Format",
+                            "Failed to flush database\n");
+        }
+        if (0 != dblayer_close(li,DBLAYER_IMPORT_MODE)) {
+            slapi_log_error(SLAPI_LOG_FATAL, "Upgrade DN Format",
+                            "Failed to close database\n");
+            goto bail;
+        }
+    }
+    *sep = '/';
+    if (((0 == rc) && !(ud_flags & SLAPI_DRYRUN)) ||
+        ((rc > 0) && (ud_flags & SLAPI_DRYRUN))) {
+        /* modify the DBVERSION files if the DN upgrade was successful OR
+         * if DRYRUN, the backend instance is up-to-date. */
+        dbversion_write(li, workdbdir, NULL, DBVERSION_ALL); /* inst db dir */
+    }
+    /* Remove the DB env files */
+    dblayer_remove_env(li);
+
+    li->li_directory = origdbdir;
+    li->li_dblayer_private->dblayer_log_directory = origlogdir;
+    inst->inst_parent_dir_name = originstparentdir;
+
+bail:
+    slapi_ch_free_string(&workdbdir);
+    slapi_ch_free_string(&ldbmversion);
+    slapi_ch_free_string(&dataversion);
+    return rc;
+}

+ 96 - 0
ldap/servers/slapd/back-ldbm/misc.c

@@ -482,3 +482,99 @@ bail:
     slapi_ch_free_string(&copy);
     return rc;
 }
+
+/* 
+ * Get value array of type from string.
+ * multi-value support for get_value_from_string
+ */
+/* caller is responsible to release "valuearray" */
+int
+get_values_from_string(const char *string, char *type, char ***valuearray)
+{
+    int rc = -1;
+    size_t typelen = 0;
+    char *ptr = NULL;
+    char *copy = NULL;
+    char *tmpptr = NULL;
+    char *tmptype = NULL;
+    char *valueptr = NULL;
+#if defined (USE_OPENLDAP)
+    ber_len_t valuelen;
+#else
+    int valuelen;
+#endif
+    char *value = NULL;
+    int idx = 0;
+#define get_values_INITIALMAXCNT 1
+    int maxcnt = get_values_INITIALMAXCNT;
+
+    if (NULL == string || NULL == type || NULL == valuearray) {
+        return rc;
+    }
+    *valuearray = NULL;
+    tmpptr = (char *)string;
+    ptr = PL_strcasestr(tmpptr, type);
+    if (NULL == ptr) {
+        return rc;
+    }
+
+    typelen = strlen(type);
+    while (NULL != (ptr = ldif_getline(&tmpptr))) {
+        if ((0 != PL_strncasecmp(ptr, type, typelen)) ||
+            (*(ptr + typelen) != ';' && *(ptr + typelen) != ':')) {
+            /* did not match */
+            /* ldif_getline replaces '\n' and '\r' with '\0' */
+            if ('\0' == *(tmpptr - 1)) {
+                *(tmpptr - 1) = '\n';
+            }
+            if ('\0' == *(tmpptr - 2)) {
+                *(tmpptr - 2) = '\r';
+            }
+            continue;
+        }
+        /* matched */
+        copy = slapi_ch_strdup(ptr);
+        /* ldif_getline replaces '\n' and '\r' with '\0' */
+        if ('\0' == *(tmpptr - 1)) {
+            *(tmpptr - 1) = '\n';
+        }
+        if ('\0' == *(tmpptr - 2)) {
+            *(tmpptr - 2) = '\r';
+        }
+        rc = ldif_parse_line(copy, &tmptype, &valueptr, &valuelen);
+        if (0 > rc || NULL == valueptr || 0 >= valuelen) {
+            continue;
+        }
+        if (0 != strcasecmp(type, tmptype)) {
+            char *p = PL_strchr(tmptype, ';'); /* subtype ? */
+            if (p) {
+                if (0 != strncasecmp(type, tmptype, p - tmptype)) {
+                    slapi_log_error(SLAPI_LOG_FATAL, "get_values_from_string", 
+                                    "type does not match: %s != %s\n", 
+                                    type, tmptype);
+                    goto bail;
+                }
+            } else {
+                slapi_log_error(SLAPI_LOG_FATAL, "get_values_from_string", 
+                                "type does not match: %s != %s\n", 
+                                type, tmptype);
+                goto bail;
+            }
+        }
+        value = (char *)slapi_ch_malloc(valuelen + 1);
+        memcpy(value, valueptr, valuelen);
+        *(value + valuelen) = '\0';
+        if ((get_values_INITIALMAXCNT == maxcnt) || !valuearray || 
+            (idx + 1 >= maxcnt)) {
+            maxcnt *= 2;
+            *valuearray = (char **)slapi_ch_realloc((char *)*valuearray, 
+                                                    sizeof(char *) * maxcnt);
+        }
+        (*valuearray)[idx++] = value;
+        (*valuearray)[idx] = NULL;
+        slapi_ch_free_string(&copy);
+    }
+bail:
+    slapi_ch_free_string(&copy);
+    return rc;
+}

+ 4 - 2
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h

@@ -171,7 +171,7 @@ int dblayer_db_uses_transactions(DB_ENV *db_env);
 int dblayer_db_uses_mpool(DB_ENV *db_env);
 int dblayer_db_uses_logging(DB_ENV *db_env);
 int dblayer_bt_compare(DB *db, const DBT *dbt1, const DBT *dbt2);
-
+int dblayer_remove_env(struct ldbminfo *li);
 
 /*
  * dn2entry.c
@@ -361,6 +361,7 @@ int mkdir_p(char *dir, unsigned int mode);
 int is_fullpath(char *path);
 char get_sep(char *path);
 int get_value_from_string(const char *string, char *type, char **value);
+int get_values_from_string(const char *string, char *type, char ***valuearray);
 
 
 /*
@@ -465,6 +466,7 @@ int ldbm_back_ldif2ldbm( Slapi_PBlock *pb );
 int ldbm_back_ldbm2ldif( Slapi_PBlock *pb );
 int ldbm_back_ldbm2ldifalt( Slapi_PBlock *pb );
 int ldbm_back_ldbm2index( Slapi_PBlock *pb );
+int ldbm_back_upgradednformat( Slapi_PBlock *pb );
 int ldbm_back_archive2ldbm( Slapi_PBlock *pb );
 int ldbm_back_ldbm2archive( Slapi_PBlock *pb );
 int ldbm_back_upgradedb( Slapi_PBlock *pb );
@@ -586,7 +588,7 @@ int ldbm_attribute_always_indexed(const char *attrtype);
 /*
  * dbversion.c
  */
-int dbversion_write(struct ldbminfo *li, const char *dir, const char *dversion);
+int dbversion_write(struct ldbminfo *li, const char *directory, const char *dataversion, PRUint32 flags);
 int dbversion_read(struct ldbminfo *li, const char *directory,
                    char **ldbmversion, char **dataversion);
 int dbversion_exists(struct ldbminfo *li, const char *directory);

+ 1 - 1
ldap/servers/slapd/back-ldbm/start.c

@@ -205,7 +205,7 @@ ldbm_back_start( Slapi_PBlock *pb )
   home_dir = dblayer_get_home_dir(li, NULL);
   if (!dbversion_exists(li, home_dir))
   {
-      dbversion_write (li, home_dir, NULL);
+      dbversion_write (li, home_dir, NULL, DBVERSION_ALL);
   }
 
 

+ 1 - 1
ldap/servers/slapd/delete.c

@@ -113,7 +113,7 @@ do_delete( Slapi_PBlock *pb )
 	}
 	err = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
 	if (err < 0) {
-		op_shared_log_error_access(pb, "DEL", "???", "invalid dn");
+		op_shared_log_error_access(pb, "DEL", rawdn?rawdn:"", "invalid dn");
 		send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, 
 						 NULL, "invalid dn", 0, NULL);
 		slapi_ch_free_string(&rawdn);

+ 11 - 1
ldap/servers/slapd/dn.c

@@ -449,7 +449,6 @@ static int
 ISEOV(char *s, char *ends)
 {
     char *p;
-    int rc = 1;
     for (p = s; p && *p && p < ends; p++) {
         if (SEPARATOR(*p)) {
             return 1;
@@ -1159,6 +1158,17 @@ rdn_av_swap( struct berval *av1, struct berval *av2, int escape )
     }
 }
 
+/* Introduced for the upgrade tool. DON'T USE THIS API! */
+char *
+slapi_dn_normalize_case_original( char *dn )
+{
+	/* LDAPDebug( LDAP_DEBUG_TRACE, "=> slapi_dn_normalize \"%s\"\n", dn, 0, 0 ); */
+	*(substr_dn_normalize_orig( dn, dn + strlen( dn ))) = '\0';
+	/* LDAPDebug( LDAP_DEBUG_TRACE, "<= slapi_dn_normalize \"%s\"\n", dn, 0, 0 ); */
+
+	/* normalize case */
+	return( slapi_dn_ignore_case( dn ));
+}
 
 /*
  * DEPRECATED: this function does nothing.

+ 113 - 4
ldap/servers/slapd/main.c

@@ -113,6 +113,7 @@ static int slapd_exemode_db2index();
 static int slapd_exemode_archive2db();
 static int slapd_exemode_db2archive();
 static int slapd_exemode_upgradedb();
+static int slapd_exemode_upgradednformat();
 static int slapd_exemode_dbverify();
 static int slapd_exemode_dbtest();
 static int slapd_exemode_suffix2instance();
@@ -374,14 +375,16 @@ name2exemode( char *progname, char *s, int exit_if_unknown )
 		exemode = SLAPD_EXEMODE_SUFFIX2INSTANCE;
 	} else if ( strcmp( s, "upgradedb" ) == 0 ) {
 		exemode = SLAPD_EXEMODE_UPGRADEDB;
+    } else if ( strcmp( s, "upgradednformat" ) == 0 ) {
+        exemode = SLAPD_EXEMODE_UPGRADEDNFORMAT;
 	} else if ( strcmp( s, "dbverify" ) == 0 ) {
 		exemode = SLAPD_EXEMODE_DBVERIFY;
 	}
 	else if ( exit_if_unknown ) {
 		fprintf( stderr, "usage: %s -D configdir "
 				 "[ldif2db | db2ldif | archive2db "
-				 "| db2archive | db2index | refer | suffix2instance"
-				 " | upgradedb | dbverify] "
+				 "| db2archive | db2index | refer | suffix2instance "
+				 "| upgradedb | upgradednformat | dbverify] "
 				 "[options]\n", progname );
 		exit( 1 );
 	} else {
@@ -441,6 +444,9 @@ usage( char *name, char *extraname )
     case SLAPD_EXEMODE_UPGRADEDB:
 	usagestr = "usage: %s %s%s-D configdir [-d debuglevel] [-f] [-r] -a archivedir\n";
 	break;
+    case SLAPD_EXEMODE_UPGRADEDNFORMAT:
+	usagestr = "usage: %s %s%s-D configdir [-d debuglevel] [-N] -n backend-instance-name -a fullpath-backend-instance-dir-full\n";
+	break;
     case SLAPD_EXEMODE_DBVERIFY:
 	usagestr = "usage: %s %s%s-D configdir [-d debuglevel] [-n backend-instance-name]\n";
 	break;
@@ -484,6 +490,7 @@ static int dbverify_verbose = 0;
 static char *ldif2db_namespaceid = NULL;
 int importexport_encrypt = 0;
 static int upgradedb_flags = 0;
+static int upgradednformat_dryrun = 0;
 
 /* taken from idsktune */
 #if defined(__sun)
@@ -990,6 +997,11 @@ main( int argc, char **argv)
 		goto cleanup;
 		break;
 
+	case SLAPD_EXEMODE_UPGRADEDNFORMAT:
+		return_value = slapd_exemode_upgradednformat();
+		goto cleanup;
+		break;
+
 	case SLAPD_EXEMODE_DBVERIFY:
 		return_value = slapd_exemode_dbverify();
 		goto cleanup;
@@ -1416,6 +1428,16 @@ process_command_line(int argc, char **argv, char *myname,
 		{"configDir",ArgRequired,'D'},
 		{0,0,0}};
 
+	char *opts_upgradednformat = "vd:a:n:D:N"; 
+	struct opt_ext long_options_upgradednformat[] = {
+		{"version",ArgNone,'v'},
+		{"debug",ArgRequired,'d'},
+		{"backend",ArgRequired,'n'},
+		{"archive",ArgRequired,'a'}, /* Path to the work db instance dir */
+		{"configDir",ArgRequired,'D'},
+		{"dryrun",ArgNone,'N'},
+		{0,0,0}};
+
 	char *opts_dbverify = "vVfd:n:D:"; 
 	struct opt_ext long_options_dbverify[] = {
 		{"version",ArgNone,'v'},
@@ -1521,6 +1543,10 @@ process_command_line(int argc, char **argv, char *myname,
 		opts = opts_upgradedb;
 		long_opts = long_options_upgradedb;
 		break;
+	case SLAPD_EXEMODE_UPGRADEDNFORMAT:
+		opts = opts_upgradednformat;
+		long_opts = long_options_upgradednformat;
+		break;
 	case SLAPD_EXEMODE_DBVERIFY:
 		opts = opts_dbverify;
 		long_opts = long_options_dbverify;
@@ -1623,6 +1649,7 @@ process_command_line(int argc, char **argv, char *myname,
 			break;
 		case 'n':	/* which backend to do ldif2db/bak2db for */
 			if (slapd_exemode == SLAPD_EXEMODE_LDIF2DB ||
+				slapd_exemode == SLAPD_EXEMODE_UPGRADEDNFORMAT ||
 				slapd_exemode == SLAPD_EXEMODE_DBTEST ||
 				slapd_exemode == SLAPD_EXEMODE_DB2INDEX ||
 				slapd_exemode == SLAPD_EXEMODE_ARCHIVE2DB) {
@@ -1665,8 +1692,10 @@ process_command_line(int argc, char **argv, char *myname,
 			db2ldif_dump_replica = 1;
 			break;
 		case 'N':	/* do not do ldif2db duplicate value check */
+					/* Or dryrun mode for upgradednformat */
 			if ( slapd_exemode != SLAPD_EXEMODE_LDIF2DB && 
-				slapd_exemode != SLAPD_EXEMODE_DB2LDIF) {
+				slapd_exemode != SLAPD_EXEMODE_DB2LDIF &&
+				slapd_exemode != SLAPD_EXEMODE_UPGRADEDNFORMAT) {
 				usage( myname, *extraname );
 				exit( 1 );
 			}
@@ -1681,6 +1710,9 @@ process_command_line(int argc, char **argv, char *myname,
 			if ( slapd_exemode == SLAPD_EXEMODE_DB2LDIF ) {
 				ldif_printkey &= ~EXPORT_PRINTKEY;
 			}
+			if ( slapd_exemode == SLAPD_EXEMODE_UPGRADEDNFORMAT ) {
+				upgradednformat_dryrun = 1;
+			}
 
 			break;
 
@@ -2171,7 +2203,7 @@ slapd_exemode_ldif2db()
     }
     /* check for slapi v2 support */
     if (! SLAPI_PLUGIN_IS_V2(plugin)) {
-        LDAPDebug(LDAP_DEBUG_ANY, "ERROR: %s is too old to do imports.\n",
+        LDAPDebug(LDAP_DEBUG_ANY, "ERROR: %s is too old to reindex all.\n",
                   plugin->plg_name, 0, 0);
         return 1;
     }
@@ -2686,6 +2718,83 @@ slapd_exemode_upgradedb()
     return( return_value );
 }
 
+/* Command to upgrade the old dn format to the new style */
+static int
+slapd_exemode_upgradednformat()
+{
+    int rc = -1; /* error, by default */
+    Slapi_PBlock pb;
+    struct slapdplugin *backend_plugin;
+    slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+    if ( archive_name == NULL ) {
+        LDAPDebug0Args(LDAP_DEBUG_ANY, "ERROR: Required argument "
+                       "\"-a <path to work db instance dir>\" is missing\n");
+        usage( myname, extraname );
+        goto bail;
+    }
+
+    /* this should be the first time to be called!  if the init order
+     * is ever changed, these lines should be changed (or erased)!
+     */
+    mapping_tree_init();
+
+    if ((backend_plugin = plugin_get_by_name("ldbm database")) == NULL) {
+        LDAPDebug0Args(LDAP_DEBUG_ANY,
+                       "ERROR: Could not find the ldbm backend plugin.\n");
+        goto bail;
+    }
+
+    /* Make sure we aren't going to run slapd in 
+     * a mode that is going to conflict with other
+     * slapd processes that are currently running
+     * Pretending to execute import.
+     */
+    if (add_new_slapd_process(slapd_exemode, 0, skip_db_protect_check) 
+                                                                        == -1) {
+        LDAPDebug0Args(LDAP_DEBUG_ANY, "Shutting down due to possible "
+                                      "conflicts with other slapd processes\n");
+        goto bail;
+    }
+    /* check for slapi v2 support */
+    if (! SLAPI_PLUGIN_IS_V2(backend_plugin)) {
+        LDAPDebug1Arg(LDAP_DEBUG_ANY, 
+                      "ERROR: %s is too old to upgrade dn format.\n",
+                      backend_plugin->plg_name);
+        goto bail;
+    }
+
+    memset( &pb, '\0', sizeof(pb) );
+    pb.pb_backend = NULL;
+    pb.pb_plugin = backend_plugin;
+    pb.pb_instance_name = cmd_line_instance_name;
+    if (upgradednformat_dryrun) {
+        pb.pb_seq_type = SLAPI_UPGRADEDNFORMAT|SLAPI_DRYRUN;
+    } else {
+        pb.pb_seq_type = SLAPI_UPGRADEDNFORMAT;
+    }
+    pb.pb_seq_val = archive_name; /* Path to the work db instance dir */
+    pb.pb_task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE;
+    /* borrowing import code, so need to set up the import variables */
+    pb.pb_ldif_generate_uniqueid = ldif2db_generate_uniqueid;
+    pb.pb_ldif_namespaceid = ldif2db_namespaceid;
+    pb.pb_ldif2db_noattrindexes = 0;
+    pb.pb_removedupvals = 0;
+#ifndef _WIN32
+    main_setuid(slapdFrontendConfig->localuser);
+#endif
+    if ( backend_plugin->plg_upgradednformat != NULL ) {
+        rc  = (*backend_plugin->plg_upgradednformat)( &pb );
+    } else {
+        LDAPDebug( LDAP_DEBUG_ANY,
+                   "ERROR: no upgradednformat function defined for "
+                   "%s\n", backend_plugin->plg_name, 0, 0 );
+    }
+bail:
+    slapi_ch_free((void**)&myname );
+    return( rc  );
+}
+
 /*
  * function to perform DB verify
  */

+ 14 - 0
ldap/servers/slapd/mapping_tree.c

@@ -1080,6 +1080,15 @@ int mapping_tree_entry_modify_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefor
             {
                 parent_node = mapping_tree_root;
             }
+            else if ((strcasecmp(mods[i]->mod_type, "cn") == 0) &&
+                      SLAPI_IS_MOD_ADD(mods[i]->mod_op))
+            {
+                /* Allow to add an additional cn.
+                 * e.g., cn: "<suffix>" for the backward compatibility.
+                 * No need to update the mapping tree node itself.
+                 */
+                continue;
+            }
             else
             {
                 /* we have to find the new parent node */
@@ -2684,6 +2693,11 @@ mtn_get_mapping_tree_node_by_entry(mapping_tree_node* node, const Slapi_DN *dn)
         return NULL;
     }
 
+    if(NULL == dn){
+        /* bad mapping tree entry operation */
+        return NULL;
+    }
+
     if  (slapi_sdn_compare(node->mtn_subtree, dn) == 0)
     {
         return node;

+ 1 - 1
ldap/servers/slapd/modify.c

@@ -193,7 +193,7 @@ do_modify( Slapi_PBlock *pb )
 		}
 		rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
 		if (rc < 0) {
-			op_shared_log_error_access(pb, "MOD", "???", "invalid dn");
+			op_shared_log_error_access(pb, "MOD", rawdn?rawdn:"", "invalid dn");
 			send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, 
 								 NULL, "invalid dn", 0, NULL);
 			slapi_ch_free((void **) &rawdn);

+ 12 - 0
ldap/servers/slapd/pblock.c

@@ -666,6 +666,12 @@ slapi_pblock_get( Slapi_PBlock *pblock, int arg, void *value )
         }
         (*(IFP *)value) = pblock->pb_plugin->plg_upgradedb;
         break;
+    case SLAPI_PLUGIN_DB_UPGRADEDNFORMAT_FN:
+        if ( pblock->pb_plugin->plg_type != SLAPI_PLUGIN_DATABASE ) {
+                return( -1 );
+        }
+        (*(IFP *)value) = pblock->pb_plugin->plg_upgradednformat;
+        break;
     case SLAPI_PLUGIN_DB_DBVERIFY_FN:
         if ( pblock->pb_plugin->plg_type != SLAPI_PLUGIN_DATABASE ) {
                 return( -1 );
@@ -2041,6 +2047,12 @@ slapi_pblock_set( Slapi_PBlock *pblock, int arg, void *value )
 		}
 		pblock->pb_plugin->plg_upgradedb = (IFP) value;
 		break;
+    case SLAPI_PLUGIN_DB_UPGRADEDNFORMAT_FN:
+		if ( pblock->pb_plugin->plg_type != SLAPI_PLUGIN_DATABASE ) {
+			return( -1 );
+		}
+		pblock->pb_plugin->plg_upgradednformat = (IFP) value;
+		break;
 	case SLAPI_PLUGIN_DB_DBVERIFY_FN:
 		if ( pblock->pb_plugin->plg_type != SLAPI_PLUGIN_DATABASE ) {
 			return( -1 );

+ 9 - 0
ldap/servers/slapd/protect_db.c

@@ -490,6 +490,15 @@ add_new_slapd_process(int exec_mode, int r_flag, int skip_flag)
             result = 0;
         }
         break;
+    case SLAPD_EXEMODE_UPGRADEDNFORMAT:
+        if (running || importing || exporting) {
+            LDAPDebug(LDAP_DEBUG_ANY, NO_UPGRADEDNFORMAT_DUE_TO_USE, 0, 0, 0);
+            result = -1;
+        } else {
+            add_this_process_to(import_dir);
+            result = 0;
+        }
+        break;
     case SLAPD_EXEMODE_DBTEST:
         if (running || importing || exporting) {
             LDAPDebug(LDAP_DEBUG_ANY, NO_DBTEST_DUE_TO_USE, 0, 0, 0);

+ 2 - 0
ldap/servers/slapd/protect_db.h

@@ -102,6 +102,8 @@ void remove_slapd_process();
 
 #define NO_UPGRADEDB_DUE_TO_USE "Unable to recreate index files because the database is being used by another slapd process.\n"
 
+#define NO_UPGRADEDNFORMAT_DUE_TO_USE "Unable to upgrade dn format because the database is being used by another slapd process.\n"
+
 #define CREATE_MUTEX_ERROR "Error - CreateMutex failed: %s\n"
   /* reason for failure */
 

+ 4 - 0
ldap/servers/slapd/slap.h

@@ -74,6 +74,7 @@ static char ptokDes[34] = "Internal (Software) Token        ";
 #define SLAPD_EXEMODE_PRINTVERSION  10
 #define SLAPD_EXEMODE_UPGRADEDB     11
 #define SLAPD_EXEMODE_DBVERIFY      12
+#define SLAPD_EXEMODE_UPGRADEDNFORMAT     13
 
 #ifdef _WIN32
 #ifndef DONT_DECLARE_SLAPD_LDAP_DEBUG
@@ -824,6 +825,7 @@ struct slapdplugin {
 			IFP	plg_un_db_archive2db; /* ldif 2 database */
 			IFP	plg_un_db_db2archive; /* database 2 ldif */
 			IFP	plg_un_db_upgradedb;  /* convert old idl to new */
+			IFP	plg_un_db_upgradednformat;  /* convert old dn format to new */
 			IFP	plg_un_db_begin;	  /* dbase txn begin */
 			IFP	plg_un_db_commit;	  /* dbase txn commit */
 			IFP	plg_un_db_abort;	  /* dbase txn abort */
@@ -863,6 +865,7 @@ struct slapdplugin {
 #define plg_archive2db		plg_un.plg_un_db.plg_un_db_archive2db
 #define plg_db2archive		plg_un.plg_un_db.plg_un_db_db2archive
 #define plg_upgradedb		plg_un.plg_un_db.plg_un_db_upgradedb
+#define plg_upgradednformat	plg_un.plg_un_db.plg_un_db_upgradednformat
 #define plg_dbverify		plg_un.plg_un_db.plg_un_db_verify
 #define plg_dbsize		plg_un.plg_un_db.plg_un_db_dbsize
 #define plg_dbtest		plg_un.plg_un_db.plg_un_db_dbtest
@@ -1132,6 +1135,7 @@ typedef struct backend {
 #define be_seq			be_database->plg_seq
 #define be_ldif2db		be_database->plg_ldif2db
 #define be_upgradedb		be_database->plg_upgradedb
+#define be_upgradednformat	be_database->plg_upgradednformat
 #define be_db2ldif		be_database->plg_db2ldif
 #define be_db2index		be_database->plg_db2index
 #define be_archive2db	be_database->plg_archive2db

+ 10 - 5
ldap/servers/slapd/slapi-private.h

@@ -375,6 +375,7 @@ Slapi_DN *slapi_sdn_init_dn_passin(Slapi_DN *sdn,const char *dn);
 Slapi_DN *slapi_sdn_init_ndn_byref(Slapi_DN *sdn,const char *dn);
 Slapi_DN *slapi_sdn_init_ndn_byval(Slapi_DN *sdn,const char *dn);
 Slapi_DN *slapi_sdn_init_dn_ndn_byref(Slapi_DN *sdn,const char *dn);
+char *slapi_dn_normalize_case_original( char *dn );
 
 /* filter.c */
 int filter_flag_is_set(const Slapi_Filter *f,unsigned char flag);
@@ -872,6 +873,7 @@ int valuearray_normalize_value(Slapi_Value **vals);
 #define SLAPI_PLUGIN_DB_ADD_SCHEMA_FN		237
 #define SLAPI_PLUGIN_DB_SEARCH_RESULTS_RELEASE_FN	238
 #define SLAPI_PLUGIN_DB_PREV_SEARCH_RESULTS_FN	239
+#define SLAPI_PLUGIN_DB_UPGRADEDNFORMAT_FN 240
 /* database plugin-specific parameters */
 #define SLAPI_PLUGIN_DB_NO_ACL        		250
 #define SLAPI_PLUGIN_DB_RMDB_FN         	280
@@ -1185,11 +1187,14 @@ void bervalarray_add_berval_fast(struct berval ***vals, const struct berval *add
 
 void    DS_Sleep(PRIntervalTime ticks);
 
-/* macro to specify the behavior of upgradedb */
-#define SLAPI_UPGRADEDB_FORCE    0x1 /* reindex all (no check w/ idl switch) */
-#define SLAPI_UPGRADEDB_SKIPINIT 0x2 /* call upgradedb as part of other op */
-#define SLAPI_UPGRADEDB_DN2RDN   0x4 /* modify id2entry from dn format to rdn;
-                                        generate entryrdn index */
+/* macro to specify the behavior of upgradedb & upgradednformat */
+#define SLAPI_UPGRADEDB_FORCE    0x1  /* reindex all (no check w/ idl switch) */
+#define SLAPI_UPGRADEDB_SKIPINIT 0x2  /* call upgradedb as part of other op */
+#define SLAPI_UPGRADEDB_DN2RDN   0x4  /* modify id2entry from dn format to rdn;
+                                         generate entryrdn index */
+#define SLAPI_UPGRADEDNFORMAT    0x8  /* specify this op is upgradednformat */
+#define SLAPI_DRYRUN             0x10 /* dryrun mode for upgradednformat */
+
 
 /*
  * Macro to set port to the 'port' field of a NSPR PRNetAddr union.

File diff suppressed because it is too large
+ 1010 - 546
ltmain.sh


+ 60 - 44
missing

@@ -1,10 +1,10 @@
 #! /bin/sh
 # Common stub for a few missing GNU programs while installing.
 
-scriptversion=2005-06-08.21
+scriptversion=2009-04-28.21; # UTC
 
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
-#   Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009 Free Software Foundation, Inc.
 # Originally by Fran,cois Pinard <[email protected]>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
@@ -18,9 +18,7 @@ scriptversion=2005-06-08.21
 # GNU General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -33,6 +31,8 @@ if test $# -eq 0; then
 fi
 
 run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
 
 # In the cases where this matters, `missing' is being run in the
 # srcdir already.
@@ -44,7 +44,7 @@ fi
 
 msg="missing on your system"
 
-case "$1" in
+case $1 in
 --run)
   # Try to run requested program, and just exit if it succeeds.
   run=
@@ -77,6 +77,7 @@ Supported PROGRAM values:
   aclocal      touch file \`aclocal.m4'
   autoconf     touch file \`configure'
   autoheader   touch file \`config.h.in'
+  autom4te     touch the output file, or create a stub one
   automake     touch all \`Makefile.in' files
   bison        create \`y.tab.[ch]', if possible, from existing .[ch]
   flex         create \`lex.yy.c', if possible, from existing .c
@@ -86,6 +87,9 @@ Supported PROGRAM values:
   tar          try tar, gnutar, gtar, then tar without non-portable flags
   yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
 
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
 Send bug reports to <[email protected]>."
     exit $?
     ;;
@@ -103,15 +107,22 @@ Send bug reports to <[email protected]>."
 
 esac
 
+# normalize program name to check for.
+program=`echo "$1" | sed '
+  s/^gnu-//; t
+  s/^gnu//; t
+  s/^g//; t'`
+
 # Now exit if we have it, but it failed.  Also exit now if we
 # don't have it and --version was passed (most likely to detect
-# the program).
-case "$1" in
-  lex|yacc)
+# the program).  This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+  lex*|yacc*)
     # Not GNU programs, they don't have --version.
     ;;
 
-  tar)
+  tar*)
     if test -n "$run"; then
        echo 1>&2 "ERROR: \`tar' requires --run"
        exit 1
@@ -135,7 +146,7 @@ esac
 
 # If it does not exist, or fails to run (possibly an outdated version),
 # try to emulate it.
-case "$1" in
+case $program in
   aclocal*)
     echo 1>&2 "\
 WARNING: \`$1' is $msg.  You should only need it if
@@ -145,7 +156,7 @@ WARNING: \`$1' is $msg.  You should only need it if
     touch aclocal.m4
     ;;
 
-  autoconf)
+  autoconf*)
     echo 1>&2 "\
 WARNING: \`$1' is $msg.  You should only need it if
          you modified \`${configure_ac}'.  You might want to install the
@@ -154,7 +165,7 @@ WARNING: \`$1' is $msg.  You should only need it if
     touch configure
     ;;
 
-  autoheader)
+  autoheader*)
     echo 1>&2 "\
 WARNING: \`$1' is $msg.  You should only need it if
          you modified \`acconfig.h' or \`${configure_ac}'.  You might want
@@ -164,7 +175,7 @@ WARNING: \`$1' is $msg.  You should only need it if
     test -z "$files" && files="config.h"
     touch_files=
     for f in $files; do
-      case "$f" in
+      case $f in
       *:*) touch_files="$touch_files "`echo "$f" |
 				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
       *) touch_files="$touch_files $f.in";;
@@ -184,7 +195,7 @@ WARNING: \`$1' is $msg.  You should only need it if
 	   while read f; do touch "$f"; done
     ;;
 
-  autom4te)
+  autom4te*)
     echo 1>&2 "\
 WARNING: \`$1' is needed, but is $msg.
          You might have modified some files without having the
@@ -192,8 +203,8 @@ WARNING: \`$1' is needed, but is $msg.
          You can get \`$1' as part of \`Autoconf' from any GNU
          archive site."
 
-    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
-    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
     if test -f "$file"; then
 	touch $file
     else
@@ -207,80 +218,78 @@ WARNING: \`$1' is needed, but is $msg.
     fi
     ;;
 
-  bison|yacc)
+  bison*|yacc*)
     echo 1>&2 "\
 WARNING: \`$1' $msg.  You should only need it if
          you modified a \`.y' file.  You may need the \`Bison' package
          in order for those modifications to take effect.  You can get
          \`Bison' from any GNU archive site."
     rm -f y.tab.c y.tab.h
-    if [ $# -ne 1 ]; then
+    if test $# -ne 1; then
         eval LASTARG="\${$#}"
-	case "$LASTARG" in
+	case $LASTARG in
 	*.y)
 	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
-	    if [ -f "$SRCFILE" ]; then
+	    if test -f "$SRCFILE"; then
 	         cp "$SRCFILE" y.tab.c
 	    fi
 	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
-	    if [ -f "$SRCFILE" ]; then
+	    if test -f "$SRCFILE"; then
 	         cp "$SRCFILE" y.tab.h
 	    fi
 	  ;;
 	esac
     fi
-    if [ ! -f y.tab.h ]; then
+    if test ! -f y.tab.h; then
 	echo >y.tab.h
     fi
-    if [ ! -f y.tab.c ]; then
+    if test ! -f y.tab.c; then
 	echo 'main() { return 0; }' >y.tab.c
     fi
     ;;
 
-  lex|flex)
+  lex*|flex*)
     echo 1>&2 "\
 WARNING: \`$1' is $msg.  You should only need it if
          you modified a \`.l' file.  You may need the \`Flex' package
          in order for those modifications to take effect.  You can get
          \`Flex' from any GNU archive site."
     rm -f lex.yy.c
-    if [ $# -ne 1 ]; then
+    if test $# -ne 1; then
         eval LASTARG="\${$#}"
-	case "$LASTARG" in
+	case $LASTARG in
 	*.l)
 	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
-	    if [ -f "$SRCFILE" ]; then
+	    if test -f "$SRCFILE"; then
 	         cp "$SRCFILE" lex.yy.c
 	    fi
 	  ;;
 	esac
     fi
-    if [ ! -f lex.yy.c ]; then
+    if test ! -f lex.yy.c; then
 	echo 'main() { return 0; }' >lex.yy.c
     fi
     ;;
 
-  help2man)
+  help2man*)
     echo 1>&2 "\
 WARNING: \`$1' is $msg.  You should only need it if
 	 you modified a dependency of a manual page.  You may need the
 	 \`Help2man' package in order for those modifications to take
 	 effect.  You can get \`Help2man' from any GNU archive site."
 
-    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
-    if test -z "$file"; then
-	file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
-    fi
-    if [ -f "$file" ]; then
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
 	touch $file
     else
 	test -z "$file" || exec >$file
 	echo ".ab help2man is required to generate this page"
-	exit 1
+	exit $?
     fi
     ;;
 
-  makeinfo)
+  makeinfo*)
     echo 1>&2 "\
 WARNING: \`$1' is $msg.  You should only need it if
          you modified a \`.texi' or \`.texinfo' file, or any other file
@@ -289,11 +298,17 @@ WARNING: \`$1' is $msg.  You should only need it if
          DU, IRIX).  You might want to install the \`Texinfo' package or
          the \`GNU make' package.  Grab either from any GNU archive site."
     # The file to touch is that specified with -o ...
-    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
     if test -z "$file"; then
       # ... or it is the one specified with @setfilename ...
       infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
-      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
+      file=`sed -n '
+	/^@setfilename/{
+	  s/.* \([^ ]*\) *$/\1/
+	  p
+	  q
+	}' $infile`
       # ... or it is derived from the source name (dir/f.texi becomes f.info)
       test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
     fi
@@ -303,7 +318,7 @@ WARNING: \`$1' is $msg.  You should only need it if
     touch $file
     ;;
 
-  tar)
+  tar*)
     shift
 
     # We have already tried tar in the generic part.
@@ -317,13 +332,13 @@ WARNING: \`$1' is $msg.  You should only need it if
     fi
     firstarg="$1"
     if shift; then
-	case "$firstarg" in
+	case $firstarg in
 	*o*)
 	    firstarg=`echo "$firstarg" | sed s/o//`
 	    tar "$firstarg" "$@" && exit 0
 	    ;;
 	esac
-	case "$firstarg" in
+	case $firstarg in
 	*h*)
 	    firstarg=`echo "$firstarg" | sed s/h//`
 	    tar "$firstarg" "$@" && exit 0
@@ -356,5 +371,6 @@ exit 0
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
 # End:

Some files were not shown because too many files changed in this diff