From a3ac3be6a7b0dd405c940ea62f7aa6af6dbe6caf Mon Sep 17 00:00:00 2001
From: Kurt Zeilenga <kurt@openldap.org>
Date: Tue, 22 Dec 1998 01:34:01 +0000
Subject: [PATCH] Added lber_get/set_option.  Removed lber_debug/ldap_debug.
 Updated other codes as needed.

---
 README                           |   2 +-
 build/lib-shared.mk              |   3 +-
 build/top.mk                     |   2 +-
 clients/gopher/go500.c           |  11 +-
 clients/gopher/go500gw.c         |  16 +--
 clients/tools/ldapdelete.c       |  15 +--
 clients/tools/ldapmodify.c       |  21 ++--
 clients/tools/ldapmodrdn.c       |  20 ++--
 clients/tools/ldappasswd.c       |  19 +++-
 clients/tools/ldapsearch.c       |  17 ++--
 clients/ud/main.c                |  14 ++-
 configure.in                     |   1 -
 doc/devel/todo                   |   1 +
 doc/man/man3/lber-decode.3       |  14 +--
 doc/man/man3/lber-decode.3.links |  12 +++
 doc/man/man3/lber-encode.3       |  14 +--
 doc/man/man3/lber-encode.3.links |  10 ++
 include/lber.h                   |  69 ++++++++-----
 include/ldap.h                   |   7 +-
 include/ldap_log.h               |  32 +++---
 include/ldif.h                   |   2 +
 libraries/liblber/Makefile.in    |   4 +-
 libraries/liblber/bprint.c       | 168 ++++++++++++++++++++++++++++---
 libraries/liblber/decode.c       |  20 ++--
 libraries/liblber/dtest.c        |  20 ++--
 libraries/liblber/encode.c       |   7 +-
 libraries/liblber/etest.c        |  18 ++--
 libraries/liblber/io.c           | 120 +++++++++++-----------
 libraries/liblber/lber-int.h     |  67 +++++++++---
 libraries/liblber/options.c      |  93 +++++++++++++++++
 libraries/libldap/cldap.c        |   2 +-
 libraries/libldap/init.c         |   2 +
 libraries/libldap/ldap-int.h     |   6 ++
 libraries/libldap/open.c         |   5 -
 libraries/libldap/options.c      |   8 ++
 libraries/libldap/request.c      |   2 +-
 libraries/libldap/test.c         |   4 +
 libraries/libldif/line64.c       |   4 +-
 servers/slapd/backend.c          |   3 +-
 servers/slapd/main.c             |  11 +-
 servers/slapd/slap.h             |  10 +-
 servers/slurpd/args.c            |  13 ++-
 servers/slurpd/re.c              |   3 +-
 servers/slurpd/slurp.h           |   4 +-
 44 files changed, 634 insertions(+), 262 deletions(-)
 create mode 100644 doc/man/man3/lber-decode.3.links
 create mode 100644 doc/man/man3/lber-encode.3.links
 create mode 100644 libraries/liblber/options.c

diff --git a/README b/README
index de693b48f9..bac6baae16 100644
--- a/README
+++ b/README
@@ -9,7 +9,7 @@ OpenLDAP Devel README
 		guidelines for developers
 
 	Client developers seeking a stable development platform
-	should use -stable.
+	should use -stable or the latest OpenLDAP release.
 
 
 OpenLDAP 1.1 README
diff --git a/build/lib-shared.mk b/build/lib-shared.mk
index 57627f1645..76774428f8 100644
--- a/build/lib-shared.mk
+++ b/build/lib-shared.mk
@@ -3,7 +3,8 @@
 ## Makefile Template for Shared Libraries
 ##
 
-LINK    = $(LTLINK) -version-info $(LIBVERSION)
+LTVERSION = -version-info $(LIBVERSION)
+LINK    = $(LTLINK)
 COMPILE = $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c
 MKDEPFLAG = -l
 
diff --git a/build/top.mk b/build/top.mk
index 090db8ea8f..03cd3d6b27 100644
--- a/build/top.mk
+++ b/build/top.mk
@@ -49,7 +49,7 @@ MKDEP = $(top_srcdir)/build/mkdep $(MKDEPFLAG) -c "$(CC)"
 
 LIBTOOL = @LIBTOOL@
 LIBVERSION = 0:0:0
-LTLINK  = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LFLAGS)
+LTLINK  = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LFLAGS) $(LTVERSION)
 LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) 
 
 # Misc UNIX commands used in makefiles
diff --git a/clients/gopher/go500.c b/clients/gopher/go500.c
index ca582e939b..2c32226353 100644
--- a/clients/gopher/go500.c
+++ b/clients/gopher/go500.c
@@ -37,7 +37,10 @@
 #include "ldapconfig.h"
 #include "lber.h"
 #include "ldap.h"
+
+#define ldap_debug debug
 #include "ldap_log.h"
+
 #include "lutil.h"
 
 #include "disptmpl.h"
@@ -96,7 +99,7 @@ main( int argc, char **argv )
 			break;
 
 		case 'd':	/* debug level */
-			debug = atoi( optarg );
+			debug |= atoi( optarg );
 			break;
 
 		case 'f':	/* ldap filter file */
@@ -156,7 +159,6 @@ main( int argc, char **argv )
 	}
 #endif	/* FD_SETSIZE*/
 
-
 	/* detach if stderr is redirected or no debugging */
 	if ( inetd == 0 )
 		lutil_detach( debug && !isatty( 1 ), 1 );
@@ -166,6 +168,11 @@ main( int argc, char **argv )
 	else
 		myname = strdup( myname + 1 );
 
+	if ( debug ) {
+		lber_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &debug);
+		ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &debug);
+	}
+	
 	if ( dosyslog ) {
 #ifdef LOG_LOCAL3
 		openlog( myname, OPENLOG_OPTIONS, LOG_LOCAL3 );
diff --git a/clients/gopher/go500gw.c b/clients/gopher/go500gw.c
index 109fa47ddd..4d83b88b6c 100644
--- a/clients/gopher/go500gw.c
+++ b/clients/gopher/go500gw.c
@@ -37,7 +37,10 @@
 
 #include "lber.h"
 #include "ldap.h"
+
+#define ldap_debug debug
 #include "ldap_log.h"
+
 #include "lutil.h"
 
 #include "disptmpl.h"
@@ -110,12 +113,7 @@ main (int  argc, char **argv )
 			break;
 
 		case 'd':	/* debugging level */
-			debug = atoi( optarg );
-#ifdef LDAP_DEBUG
-			ldap_debug = debug;
-#else
-			fprintf( stderr, "warning: ldap debugging requires LDAP_DEBUG\n" );
-#endif
+			debug |= atoi( optarg );
 			break;
 
 		case 'f':	/* ldap filter file */
@@ -194,6 +192,12 @@ main (int  argc, char **argv )
 	else
 		myname = strdup( myname + 1 );
 
+
+	if ( debug ) {
+		lber_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &debug);
+		ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &debug);
+	}
+	
 	if ( dosyslog ) {
 #ifdef LOG_LOCAL3
 		openlog( myname, OPENLOG_OPTIONS, LOG_LOCAL3 );
diff --git a/clients/tools/ldapdelete.c b/clients/tools/ldapdelete.c
index a2b477758d..df1103cda1 100644
--- a/clients/tools/ldapdelete.c
+++ b/clients/tools/ldapdelete.c
@@ -33,9 +33,9 @@ main( int argc, char **argv )
     char		*usage = "usage: %s [-n] [-v] [-k] [-W] [-d debug-level] [-f file] [-h ldaphost] [-p ldapport] [-D binddn] [-w passwd] [dn]...\n";
     char		buf[ 4096 ];
     FILE		*fp;
-    int			i, rc, authmethod, want_bindpw;
+    int			i, rc, authmethod, want_bindpw, debug;
 
-    not = verbose = contoper = want_bindpw = 0;
+    not = verbose = contoper = want_bindpw = debug = 0;
     fp = NULL;
     authmethod = LDAP_AUTH_SIMPLE;
 
@@ -74,11 +74,7 @@ main( int argc, char **argv )
 	    }
 	    break;
 	case 'd':
-#ifdef LDAP_DEBUG
-	    ldap_debug = lber_debug = atoi( optarg );	/* */
-#else /* LDAP_DEBUG */
-	    fprintf( stderr, "compile with -DLDAP_DEBUG for debugging\n" );
-#endif /* LDAP_DEBUG */
+	    debug |= atoi( optarg );
 	    break;
 	case 'p':
 	    ldapport = atoi( optarg );
@@ -104,6 +100,11 @@ main( int argc, char **argv )
 	}
     }
 
+	if ( debug ) {
+		lber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug );
+		ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug );
+	}
+
     if (( ld = ldap_open( ldaphost, ldapport )) == NULL ) {
 	perror( "ldap_open" );
 	exit( 1 );
diff --git a/clients/tools/ldapmodify.c b/clients/tools/ldapmodify.c
index 48b2524975..d634274674 100644
--- a/clients/tools/ldapmodify.c
+++ b/clients/tools/ldapmodify.c
@@ -68,7 +68,7 @@ main( int argc, char **argv )
 {
     char		*infile, *rbuf, *start, *p, *q;
     FILE		*fp;
-    int			rc, i, use_ldif, authmethod, want_bindpw;
+    int			rc, i, use_ldif, authmethod, want_bindpw, debug;
     char		*usage = "usage: %s [-abcknrvWF] [-d debug-level] [-h ldaphost] [-p ldapport] [-D binddn] [-w passwd] [ -f file | < entryfile ]\n";
 
     if (( prog = strrchr( argv[ 0 ], '/' )) == NULL ) {
@@ -79,7 +79,7 @@ main( int argc, char **argv )
     new = ( strcmp( prog, "ldapadd" ) == 0 );
 
     infile = NULL;
-    not = verbose = valsfromfiles = want_bindpw = 0;
+    not = verbose = valsfromfiles = want_bindpw = debug = 0;
     authmethod = LDAP_AUTH_SIMPLE;
 
     while (( i = getopt( argc, argv, "WFabckKnrtvh:p:D:w:d:f:" )) != EOF ) {
@@ -123,12 +123,7 @@ main( int argc, char **argv )
 	    passwd = strdup( optarg );
 	    break;
 	case 'd':
-#ifdef LDAP_DEBUG
-	    ldap_debug = lber_debug = atoi( optarg );	/* */
-#else /* LDAP_DEBUG */
-	    fprintf( stderr, "%s: compile with -DLDAP_DEBUG for debugging\n",
-		    prog );
-#endif /* LDAP_DEBUG */
+	    debug |= atoi( optarg );
 	    break;
 	case 'f':	/* read from file */
 	    infile = strdup( optarg );
@@ -165,6 +160,11 @@ main( int argc, char **argv )
 	fp = stdin;
     }
 
+	if ( debug ) {
+		lber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug );
+		ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug );
+		ldif_debug = debug;
+	}
 
     if ( !not ) {
 	if (( ld = ldap_open( ldaphost, ldapport )) == NULL ) {
@@ -173,7 +173,10 @@ main( int argc, char **argv )
 	}
 
 	/* this seems prudent */
-	ldap_set_option( ld, LDAP_OPT_DEREF, LDAP_DEREF_NEVER);
+	{
+		int deref = LDAP_DEREF_NEVER;
+		ldap_set_option( ld, LDAP_OPT_DEREF, &deref);
+	}
 
 	if (want_bindpw)
 		passwd = getpass("Enter LDAP Password: ");
diff --git a/clients/tools/ldapmodrdn.c b/clients/tools/ldapmodrdn.c
index 03d6adfcbf..3ba5ac2a37 100644
--- a/clients/tools/ldapmodrdn.c
+++ b/clients/tools/ldapmodrdn.c
@@ -35,10 +35,10 @@ main(int argc, char **argv)
     char		*usage = "usage: %s [-nvkWc] [-d debug-level] [-h ldaphost] [-p ldapport] [-D binddn] [-w passwd] [ -f file | < entryfile | dn newrdn ]\n";
     char		*myname,*infile, *entrydn, *rdn, buf[ 4096 ];
     FILE		*fp;
-    int			rc, i, remove, havedn, authmethod, want_bindpw;
+    int			rc, i, remove, havedn, authmethod, want_bindpw, debug;
 
     infile = NULL;
-    not = contoper = verbose = remove = want_bindpw = 0;
+    not = contoper = verbose = remove = want_bindpw = debug = 0;
     authmethod = LDAP_AUTH_SIMPLE;
 
     myname = (myname = strrchr(argv[0], '/')) == NULL ? argv[0] : ++myname;
@@ -72,11 +72,7 @@ main(int argc, char **argv)
 	    passwd = strdup( optarg );
 	    break;
 	case 'd':
-#ifdef LDAP_DEBUG
-	    ldap_debug = lber_debug = atoi( optarg );	/* */
-#else /* LDAP_DEBUG */
-	    fprintf( stderr, "compile with -DLDAP_DEBUG for debugging\n" );
-#endif /* LDAP_DEBUG */
+	    debug |= atoi( optarg );
 	    break;
 	case 'f':	/* read from file */
 	    infile = strdup( optarg );
@@ -128,13 +124,21 @@ main(int argc, char **argv)
 	fp = stdin;
     }
 
+	if ( debug ) {
+		lber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug );
+		ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug );
+	}
+
     if (( ld = ldap_open( ldaphost, ldapport )) == NULL ) {
 	perror( "ldap_open" );
 	exit( 1 );
     }
 
 	/* this seems prudent */
-	ldap_set_option( ld, LDAP_OPT_DEREF, LDAP_DEREF_NEVER);
+	{
+		int deref = LDAP_DEREF_NEVER;
+		ldap_set_option( ld, LDAP_OPT_DEREF, &deref);
+	}
 
 	if (want_bindpw)
 		passwd = getpass("Enter LDAP Password: ");
diff --git a/clients/tools/ldappasswd.c b/clients/tools/ldappasswd.c
index ea440a43c8..11c71c4cc6 100644
--- a/clients/tools/ldappasswd.c
+++ b/clients/tools/ldappasswd.c
@@ -388,6 +388,7 @@ main (int argc, char *argv[])
 	int		hashtype = HASHTYPE_CRYPT;
 	int		i, j;
 	int		ldapport = 0;
+	int		debug = 0;
 	int		scope = LDAP_SCOPE_SUBTREE;
 	int		sizelimit = LDAP_NO_LIMIT;
 	int		timelimit = LDAP_NO_LIMIT;
@@ -423,11 +424,7 @@ main (int argc, char *argv[])
 			break;
 
 		case 'd':	/* debugging option */
-#ifdef LDAP_DEBUG
-			ldap_debug = lber_debug = atoi (optarg);	/* */
-#else
-			fprintf (stderr, "compile with -DLDAP_DEBUG for debugging\n");
-#endif
+			debug |= atoi (optarg);
 			break;
 
 		case 'E':	/* prompt for new password */
@@ -565,6 +562,11 @@ main (int argc, char *argv[])
 		}
 	}
 
+	if ( debug ) {
+		lber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug );
+		ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug );
+	}
+
 	/* connect to server */
 	if ((ld = ldap_open (ldaphost, ldapport)) == NULL)
 	{
@@ -576,6 +578,13 @@ main (int argc, char *argv[])
 	ldap_set_option (ld, LDAP_OPT_TIMELIMIT, (void *)&timelimit);
 	ldap_set_option (ld, LDAP_OPT_SIZELIMIT, (void *)&sizelimit);
 
+	/* this seems prudent */
+	{
+		int deref = LDAP_DEREF_NEVER;
+		ldap_set_option( ld, LDAP_OPT_DEREF, &deref);
+	}
+
+
 	/* authenticate to server */
 	if (ldap_bind_s (ld, binddn, bindpw, authmethod) != LDAP_SUCCESS)
 	{
diff --git a/clients/tools/ldapsearch.c b/clients/tools/ldapsearch.c
index f601476796..7d6d118fd5 100644
--- a/clients/tools/ldapsearch.c
+++ b/clients/tools/ldapsearch.c
@@ -87,14 +87,15 @@ main( int argc, char **argv )
     char		*infile, *filtpattern, **attrs, line[ BUFSIZ ];
     FILE		*fp;
     int			rc, i, first, scope, deref, attrsonly;
-    int			referrals, timelimit, sizelimit, authmethod, want_bindpw;
+    int			referrals, timelimit, sizelimit, debug;
+	int			authmethod, want_bindpw;
     LDAP		*ld;
 
     infile = NULL;
     deref = verbose = allow_binary = not = vals2tmp =
 	    attrsonly = ldif = want_bindpw = 0;
     referrals = (int) LDAP_OPT_ON;
-    sizelimit = timelimit = 0;
+    sizelimit = timelimit = debug = 0;
     scope = LDAP_SCOPE_SUBTREE;
     authmethod = LDAP_AUTH_SIMPLE;
 
@@ -107,11 +108,7 @@ main( int argc, char **argv )
 	    ++verbose;
 	    break;
 	case 'd':
-#ifdef LDAP_DEBUG
-	    ldap_debug = lber_debug = atoi( optarg );	/* */
-#else /* LDAP_DEBUG */
-	    fprintf( stderr, "compile with -DLDAP_DEBUG for debugging\n" );
-#endif /* LDAP_DEBUG */
+	    debug |= atoi( optarg );
 	    break;
 	case 'k':	/* use kerberos bind */
 #ifdef HAVE_KERBEROS
@@ -247,6 +244,12 @@ main( int argc, char **argv )
 	printf( "ldap_open( %s, %d )\n", ldaphost, ldapport );
     }
 
+	if ( debug ) {
+		lber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug );
+		ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug );
+		ldif_debug = debug;
+	}
+
     if (( ld = ldap_open( ldaphost, ldapport )) == NULL ) {
 	perror( ldaphost );
 	exit( 1 );
diff --git a/clients/ud/main.c b/clients/ud/main.c
index 79fab94ff0..956ef1be6f 100644
--- a/clients/ud/main.c
+++ b/clients/ud/main.c
@@ -81,6 +81,7 @@ LDAPFiltDesc *lfdp;		/* LDAP filter descriptor */
 #ifdef DEBUG
 int debug;			/* debug flag */
 #endif
+int ldebug;			/* library debug flag */
 
 
 int
@@ -95,14 +96,11 @@ main( int argc, char **argv )
 	while ((c = getopt(argc, argv, "c:d:Df:l:p:s:u:vV")) != -1) {
 		switch (c) {
 		case 'l' :
-#ifdef LDAP_DEBUG
-			ldap_debug = (int) strtol(optarg, (char **) NULL, 0);
-			lber_debug = ldap_debug;
-#endif
+			ldebug |= (int) strtol(optarg, (char **) NULL, 0);
 			break;
 		case 'd' :
 #ifdef DEBUG
-			debug = (int) strtol(optarg, (char **) NULL, 0);
+			debug |= (int) strtol(optarg, (char **) NULL, 0);
 #endif
 			break;
 		case 's' :
@@ -549,6 +547,12 @@ initialize_client( void )
 	if (debug & D_TRACE)
 		printf("->initialize_client()\n");
 #endif
+
+	if (ldebug) {
+		lber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &ldebug);
+		ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &ldebug);
+	}
+
 	/*
 	 *  A per-user config file has precedence over any system-wide
 	 *  config file, if one exists.
diff --git a/configure.in b/configure.in
index d0cedc76e9..8ff7e9f9af 100644
--- a/configure.in
+++ b/configure.in
@@ -42,7 +42,6 @@ OL_ARG_ENABLE(debug,[  --enable-debug 	enable debugging], yes)dnl
 ol_enable_syslog=no
 dnl OL_ARG_ENABLE(syslog,[  --enable-syslog	enable syslog support], auto)dnl
 OL_ARG_ENABLE(proctitle,[  --enable-proctitle	enable proctitle support], yes)dnl
-OL_ARG_ENABLE(libui,[  --enable-libui	enable library user interface], yes)dnl
 OL_ARG_ENABLE(cache,[  --enable-cache	enable caching], yes)dnl
 OL_ARG_ENABLE(dns,[  --enable-dns		enable V2 DNS  extension], no)dnl
 OL_ARG_ENABLE(referrals,[  --enable-referrals	enable V2 Referrals extension], yes)dnl
diff --git a/doc/devel/todo b/doc/devel/todo
index a70b5bdb46..fde20127cd 100644
--- a/doc/devel/todo
+++ b/doc/devel/todo
@@ -40,6 +40,7 @@ Modify libraries to use application specified logging routines
 Modify libraries to use application specified memory allocation routines
 Extend configure.in to support autodetect of ISODE features.
 Port slurpd to NT
+Update manual page
 
 
 Small projects
diff --git a/doc/man/man3/lber-decode.3 b/doc/man/man3/lber-decode.3
index e885337a38..025aba5c14 100644
--- a/doc/man/man3/lber-decode.3
+++ b/doc/man/man3/lber-decode.3
@@ -10,23 +10,13 @@ ber_get_next, ber_skiptag, ber_peek_tag, ber_scanf, ber_get_int, ber_get_stringb
 .LP
 .nf
 .ft B
-typedef struct berelement {
-    char *ber_buf;
-    char *ber_ptr;
-    char *ber_end;
-    struct seqorset *ber_sos;
-    int ber_tag;
-    int ber_usertag;
-} BerElement;
+typedef struct berelement BerElement;
 .ft
 .fi
 .LP
 .nf
 .ft B
-typedef struct sockbuf {
-    int sb_sd;
-    BerElement sb_ber;
-} Sockbuf;
+typedef struct sockbuf Sockbuf;
 .ft
 .fi
 .LP
diff --git a/doc/man/man3/lber-decode.3.links b/doc/man/man3/lber-decode.3.links
new file mode 100644
index 0000000000..8d43e71e66
--- /dev/null
+++ b/doc/man/man3/lber-decode.3.links
@@ -0,0 +1,12 @@
+ber_get_next.3
+ber_skip_tag.3
+ber_peek_tag.3
+ber_scanf.3
+ber_get_int.3
+ber_get_stringa.3
+ber_get_stringb.3
+ber_get_null.3
+ber_get_boolean.3
+ber_get_bitstring.3
+ber_first_element.3
+ber_next_element.3
diff --git a/doc/man/man3/lber-encode.3 b/doc/man/man3/lber-encode.3
index 7d6806b245..f33fe2d2c8 100644
--- a/doc/man/man3/lber-encode.3
+++ b/doc/man/man3/lber-encode.3
@@ -10,23 +10,13 @@ ber_alloc, ber_flush, ber_printf, ber_put_int, ber_put_ostring, ber_put_string,
 .LP
 .nf
 .ft B
-typedef struct berelement {
-    char *ber_buf;
-    char *ber_ptr;
-    char *ber_end;
-    struct seqorset *ber_sos;
-    int ber_tag;
-    int ber_usertag;
-} BerElement;
+typedef struct berelement BerElement;
 .ft
 .fi
 .LP
 .nf
 .ft B
-typedef struct sockbuf {
-    int sb_sd;
-    BerElement sb_ber;
-} Sockbuf;
+typedef struct sockbuf Sockbuf;
 .ft
 .fi
 .LP
diff --git a/doc/man/man3/lber-encode.3.links b/doc/man/man3/lber-encode.3.links
new file mode 100644
index 0000000000..e1fef9a764
--- /dev/null
+++ b/doc/man/man3/lber-encode.3.links
@@ -0,0 +1,10 @@
+ber_alloc.3
+ber_flush.3
+ber_printf.3
+ber_put_int.3
+ber_put_ostring.3
+ber_put_string.3
+ber_put_null.3
+ber_start_set.3
+ber_put_seq.3
+ber_put_set.3
diff --git a/include/lber.h b/include/lber.h
index 559f43b9e9..ea96bd654d 100644
--- a/include/lber.h
+++ b/include/lber.h
@@ -55,33 +55,42 @@ LDAP_BEGIN_DECL
 #define OLD_LBER_SEQUENCE	0x10L	/* w/o constructed bit - broken */
 #define OLD_LBER_SET		0x11L	/* w/o constructed bit - broken */
 
-/* get/set options for BerElement */
-#define LBER_SOCKBUF_OPT_TO_FILE				0x01
-#define LBER_SOCKBUF_OPT_TO_FILE_ONLY			0x02
-#define	LBER_SOCKBUF_OPT_TO_MAX_INCOMING_SIZE	0x04
-#define LBER_SOCKBUF_OPT_TO_NO_READ_AHEAD		0x08
-#define LBER_SOCKBUF_OPT_TO_DESC				0x10
-#define	LBER_SOCKBUF_OPT_TO_COPYDESC			0x20
-#define LBER_SOCKBUF_OPT_TO_READFN				0x40
-#define LBER_SOCKBUF_OPT_TO_WRITE_FN			0x80
-
-/* LBER on/off values */
-#define LBER_OPT_ON ((void *) 1)
-#define LBER_OPT_OFF ((void *) 0)
-
 typedef int (*BERTranslateProc) LDAP_P(( char **bufp,
 	unsigned long *buflenp,
 	int free_input ));
 
+/* LBER BerElement options */
 #define LBER_USE_DER		0x01
 #define LBER_USE_INDEFINITE_LEN	0x02
 #define LBER_TRANSLATE_STRINGS	0x04
 
+/* get/set options for BerElement */
+#define LBER_OPT_BER_OPTIONS	0x01
+#define LBER_OPT_BER_DEBUG		0x02
+#define LBER_OPT_DEBUG_LEVEL	LBER_OPT_BER_DEBUG
+
+/* LBER Sockbuf options */ 
+#define LBER_TO_FILE           0x01	/* to a file referenced by sb_fd   */
+#define LBER_TO_FILE_ONLY      0x02	/* only write to file, not network */
+#define LBER_MAX_INCOMING_SIZE 0x04	/* impose limit on incoming stuff  */
+#define LBER_NO_READ_AHEAD     0x08	/* read only as much as requested  */
+
+/* get/set options for Sockbuf */
+#define LBER_OPT_SOCKBUF_DESC		0x1000
+#define LBER_OPT_SOCKBUF_OPTIONS	0x1001
+#define LBER_OPT_SOCKBUF_DEBUG		0x1002
+
+/* on/off values */
+#define LBER_OPT_ON		((void *) 1)
+#define LBER_OPT_OFF	((void *) 0)
+
+#define LBER_OPT_SUCCESS	0
+#define LBER_OPT_ERROR		(-1)
+
 typedef struct berelement BerElement;
 #define NULLBER	((BerElement *) 0)
 
 typedef struct sockbuf Sockbuf;
-#define READBUFSIZ	8192
 
 typedef struct seqorset Seqorset;
 #define NULLSEQORSET ((Seqorset *) 0)
@@ -92,16 +101,16 @@ struct berval {
 	char		*bv_val;
 };
 
-#ifdef LDAP_DEBUG
-extern int lber_debug;
-#endif
-
 /*
  * in bprint.c:
  */
 LDAP_F void ber_print_error LDAP_P(( char *data ));
 LDAP_F void ber_bprint LDAP_P(( char *data, int len ));
-#define lber_bprint(d,l)	ber_bprint((d),(l))
+#define lber_bprint(d,l)       ber_bprint((d),(l))
+
+LDAP_F void ber_dump LDAP_P(( BerElement *ber, int inout ));
+LDAP_F void ber_sos_dump LDAP_P(( Seqorset *sos ));
+
 
 /*
  * in decode.c:
@@ -160,19 +169,33 @@ LDAP_F BerElement *ber_alloc LDAP_P(( void ));
 LDAP_F BerElement *der_alloc LDAP_P(( void ));
 LDAP_F BerElement *ber_alloc_t LDAP_P(( int options ));
 LDAP_F BerElement *ber_dup LDAP_P(( BerElement *ber ));
-LDAP_F void ber_dump LDAP_P(( BerElement *ber, int inout ));
-LDAP_F void ber_sos_dump LDAP_P(( Seqorset *sos ));
 LDAP_F unsigned long ber_get_next LDAP_P(( Sockbuf *sb, unsigned long *len,
 	BerElement *ber ));
 LDAP_F void ber_init_w_nullc LDAP_P(( BerElement *ber, int options ));
 LDAP_F void ber_reset LDAP_P(( BerElement *ber, int was_writing ));
 
 /*
- * LDAP draft-ietf-ldapext-ldap-c-api-01 routines
+ * LBER draft-ietf-ldapext-ldap-c-api-01 routines
  */
 LDAP_F BerElement *ber_init LDAP_P(( struct berval *bv ));
 LDAP_F int ber_flatten LDAP_P(( BerElement *ber, struct berval **bvPtr ));
 
+/*
+ * LBER ber accessor functions
+ */
+LDAP_F int
+lber_get_option LDAP_P((void *item, int option, void *outvalue));
+
+LDAP_F int
+lber_set_option LDAP_P((void *item, int option, void *invalue));
+
+/*
+ * LBER Sockbuf functions
+ */
+LDAP_F Sockbuf *lber_sockbuf_alloc LDAP_P((void));
+LDAP_F Sockbuf *lber_sockbuf_alloc_fd LDAP_P((int fd));
+LDAP_F void lber_sockbuf_free LDAP_P((Sockbuf *sb));
+
 LDAP_END_DECL
 
 #endif /* _LBER_H */
diff --git a/include/ldap.h b/include/ldap.h
index cf04a6e7ab..ce9a1941f9 100644
--- a/include/ldap.h
+++ b/include/ldap.h
@@ -85,6 +85,9 @@ LDAP_BEGIN_DECL
 /*	for LDAPv2 compatibility */
 #define LDAP_OPT_DNS				0x1001	/* use DN & DNS */
 
+/* OpenLDAP specific options */
+#define LDAP_OPT_DEBUG_LEVEL		0x4001	/* OpenLDAP - debug level */
+
 /* on/off values */
 #define LDAP_OPT_ON		((void *) 1)
 #define LDAP_OPT_OFF	((void *) 0)
@@ -92,10 +95,6 @@ LDAP_BEGIN_DECL
 #define LDAP_OPT_SUCCESS	0
 #define	LDAP_OPT_ERROR		(-1)
 
-#ifdef LDAP_DEBUG
-extern int ldap_debug;
-#endif
-
 #define LDAP_API_INFO_VERSION	1
 typedef struct ldapapiinfo {
 	int		ldapai_info_version;		/* version of LDAPAPIInfo (1) */
diff --git a/include/ldap_log.h b/include/ldap_log.h
index 08dab9cd08..d368b8f6a0 100644
--- a/include/ldap_log.h
+++ b/include/ldap_log.h
@@ -19,25 +19,31 @@ LDAP_BEGIN_DECL
 
 /* debugging stuff */
 #ifdef LDAP_DEBUG
+
+#ifndef ldap_debug
 extern int	ldap_debug;
+#endif /* !ldap_debug */
+
 #ifdef LDAP_SYSLOG
 extern int	ldap_syslog;
 extern int	ldap_syslog_level;
 #endif /* LDAP_SYSLOG */
 
-#define LDAP_DEBUG_TRACE	0x001
-#define LDAP_DEBUG_PACKETS	0x002
-#define LDAP_DEBUG_ARGS		0x004
-#define LDAP_DEBUG_CONNS	0x008
-#define LDAP_DEBUG_BER		0x010
-#define LDAP_DEBUG_FILTER	0x020
-#define LDAP_DEBUG_CONFIG	0x040
-#define LDAP_DEBUG_ACL		0x080
-#define LDAP_DEBUG_STATS	0x100
-#define LDAP_DEBUG_STATS2	0x200
-#define LDAP_DEBUG_SHELL	0x400
-#define LDAP_DEBUG_PARSE	0x800
-#define LDAP_DEBUG_ANY		0xffff
+#define LDAP_DEBUG_TRACE	0x0001
+#define LDAP_DEBUG_PACKETS	0x0002
+#define LDAP_DEBUG_ARGS		0x0004
+#define LDAP_DEBUG_CONNS	0x0008
+#define LDAP_DEBUG_BER		0x0010
+#define LDAP_DEBUG_FILTER	0x0020
+#define LDAP_DEBUG_CONFIG	0x0040
+#define LDAP_DEBUG_ACL		0x0080
+#define LDAP_DEBUG_STATS	0x0100
+#define LDAP_DEBUG_STATS2	0x0200
+#define LDAP_DEBUG_SHELL	0x0400
+#define LDAP_DEBUG_PARSE	0x0800
+
+#define LDAP_DEBUG_NONE		0x8000
+#define LDAP_DEBUG_ANY		-1
 
 /* this doesn't below as part of ldap.h */
 #ifdef LDAP_SYSLOG
diff --git a/include/ldif.h b/include/ldif.h
index d89b7da8cc..3a2aad4027 100644
--- a/include/ldif.h
+++ b/include/ldif.h
@@ -17,6 +17,8 @@
 
 LDAP_BEGIN_DECL
 
+extern int ldif_debug;
+
 #define LINE_WIDTH      76      /* maximum length of LDIF lines */
 
 /*
diff --git a/libraries/liblber/Makefile.in b/libraries/liblber/Makefile.in
index 1c0bfcb79b..4cd14eef67 100644
--- a/libraries/liblber/Makefile.in
+++ b/libraries/liblber/Makefile.in
@@ -5,8 +5,8 @@
 LIBRARY = liblber.la
 XLIBRARY = ../liblber.a
 
-SRCS= decode.c encode.c io.c bprint.c
-OBJS= decode.lo encode.lo io.lo bprint.lo
+SRCS= decode.c encode.c io.c bprint.c options.c
+OBJS= decode.lo encode.lo io.lo bprint.lo options.lo
 XSRCS= version.c
 
 PROGRAMS= dtest etest idtest
diff --git a/libraries/liblber/bprint.c b/libraries/liblber/bprint.c
index 099c61bbe8..6c59c3a677 100644
--- a/libraries/liblber/bprint.c
+++ b/libraries/liblber/bprint.c
@@ -3,9 +3,8 @@
 
 #include <stdio.h>
 
-#if defined( LDAP_DEBUG ) && defined( LDAP_LIBUI )
 #include <ac/ctype.h>
-#endif /* LDAP_DEBUG && LDAP_LIBUI  */
+#include <ac/stdarg.h>
 #include <ac/string.h>
 
 #include "lber-int.h"
@@ -13,35 +12,109 @@
 /*
  * Print stuff
  */
-void
-ber_print_error( char *data)
+static void
+lber_print_error( char *data )
 {
 	fputs( data, stderr );
 	fflush( stderr );
 }
 
+/*
+ * lber log 
+ */
+
+static int lber_log_check( int errlvl, int loglvl )
+{
+	return errlvl & loglvl ? 1 : 0;
+}
+
+int lber_log_printf
+#ifdef HAVE_STDARG
+	(int errlvl, int loglvl, char *fmt, ...)
+#else
+	( va_alist )
+va_dcl
+#endif
+{
+	char buf[ 1024 ];
+	va_list ap;
+
+#ifdef HAVE_STDARG
+	va_start( ap, fmt );
+#else
+	int errlvl, loglvl;
+	char *fmt;
+
+	va_start( ap );
+
+	errlvl = va_arg( ap, int );
+	loglvl = va_arg( ap, int );
+	fmt = va_arg( ap, char * );
+#endif
+
+	if ( !lber_log_check( errlvl, loglvl )) {
+		return 0;
+	}
+
+#ifdef HAVE_VSNPRINTF
+	buf[sizeof(buf) - 1] = '\0';
+	vsnprintf( buf, sizeof(buf)-1, fmt, ap );
+#elif
+	vsprintf( buf, fmt, ap ); /* hope it's not too long */
+#else
+	/* use doprnt() */
+	chokeme = "choke me! I don't have a doprnt manual handy!";
+#endif
+
+	va_end(ap);
+
+	lber_print_error( buf );
+	return 1;
+}
+
+static int lber_log_puts(int errlvl, int loglvl, char *buf)
+{
+	if ( !lber_log_check( errlvl, loglvl )) {
+		return 0;
+	}
+
+	lber_print_error( buf );
+	return 1;
+}
+
 /*
  * Print arbitrary stuff, for debugging.
  */
 
-void
-ber_bprint( char *data, int len )
+int
+lber_log_bprint(int errlvl, int loglvl, char *data, int len )
 {
-#if defined( LDAP_DEBUG ) && defined( LDAP_LIBUI )
-#define BPLEN	48
+	if ( !lber_log_check( errlvl, loglvl )) {
+		return 0;
+	}
 
+	ber_bprint(data, len);
+	return 1;
+}
+
+void
+ber_bprint(char *data, int len )
+{
     static char	hexdig[] = "0123456789abcdef";
+#define BPLEN	48
     char	out[ BPLEN ];
+    char	buf[ BPLEN + sizeof("\t%s\n") ];
     int		i = 0;
 
     memset( out, 0, BPLEN );
     for ( ;; ) {
 	if ( len < 1 ) {
-	    fprintf( stderr, "\t%s\n", ( i == 0 ) ? "(end)" : out );
+	    sprintf( buf, "\t%s\n", ( i == 0 ) ? "(end)" : out );
+		lber_print_error( buf );
 	    break;
 	}
 
-#ifndef HEX
+#ifndef LDAP_HEX
 	if ( isgraph( (unsigned char)*data )) {
 	    out[ i ] = ' ';
 	    out[ i+1 ] = *data;
@@ -49,7 +122,7 @@ ber_bprint( char *data, int len )
 #endif
 	    out[ i ] = hexdig[ ( *data & 0xf0 ) >> 4 ];
 	    out[ i+1 ] = hexdig[ *data & 0x0f ];
-#ifndef HEX
+#ifndef LDAP_HEX
 	}
 #endif
 	i += 2;
@@ -59,14 +132,83 @@ ber_bprint( char *data, int len )
 	if ( i > BPLEN - 2 ) {
 		char data[128 + BPLEN];
 	    sprintf( data, "\t%s\n", out );
-		ber_print_error(data);
+		lber_print_error(data);
 	    memset( out, 0, BPLEN );
 	    i = 0;
 	    continue;
 	}
 	out[ i++ ] = ' ';
     }
+}
+
+int
+lber_log_dump( int errlvl, int loglvl, BerElement *ber, int inout )
+{
+	if ( !lber_log_check( errlvl, loglvl )) {
+		return 0;
+	}
+
+	ber_dump(ber, inout);
+	return 1;
+}
+
+void
+ber_dump( BerElement *ber, int inout )
+{
+	char buf[132];
+
+	sprintf( buf, "ber_dump: buf 0x%lx, ptr 0x%lx, end 0x%lx\n",
+	    (long) ber->ber_buf,
+		(long) ber->ber_ptr,
+		(long) ber->ber_end );
+
+	lber_print_error( buf );
+
+	if ( inout == 1 ) {
+		sprintf( buf, "          current len %ld, contents:\n",
+		    (long) (ber->ber_end - ber->ber_ptr) );
+		ber_bprint( ber->ber_ptr, ber->ber_end - ber->ber_ptr );
+
+	} else {
+		sprintf( buf, "          current len %ld, contents:\n",
+		    (long) (ber->ber_ptr - ber->ber_buf) );
+
+		ber_bprint( ber->ber_buf, ber->ber_ptr - ber->ber_buf );
+	}
+}
+
+int
+lber_log_sos_dump( int errlvl, int loglvl, Seqorset *sos )
+{
+	if ( !lber_log_check( errlvl, loglvl )) {
+		return 0;
+	}
+
+	ber_sos_dump( sos );
+	return 1;
+}
+
+void
+ber_sos_dump( Seqorset *sos )
+{
+	char buf[132];
+
+	lber_print_error( "*** sos dump ***\n" );
+
+	while ( sos != NULLSEQORSET ) {
+		sprintf( buf, "ber_sos_dump: clen %ld first 0x%lx ptr 0x%lx\n",
+		    (long) sos->sos_clen, (long) sos->sos_first, (long) sos->sos_ptr );
+		lber_print_error( buf );
+
+		sprintf( buf, "              current len %ld contents:\n",
+		    (long) (sos->sos_ptr - sos->sos_first) );
+		lber_print_error( buf );
+
+		ber_bprint( sos->sos_first, sos->sos_ptr - sos->sos_first );
+
+		sos = sos->sos_next;
+	}
 
-#endif /* LDAP_DEBUG && LDAP_LIBUI  */
+	lber_print_error( "*** end dump ***\n" );
 }
 
diff --git a/libraries/liblber/decode.c b/libraries/liblber/decode.c
index 4a15d47a38..3b376d7cb6 100644
--- a/libraries/liblber/decode.c
+++ b/libraries/liblber/decode.c
@@ -23,10 +23,6 @@
 
 #include "lber-int.h"
 
-#ifdef LDAP_DEBUG
-int	lber_debug;
-#endif
-
 static int ber_getnint LDAP_P(( BerElement *ber, long *num, int len ));
 
 /* return the tag - LBER_DEFAULT returned means trouble */
@@ -398,12 +394,11 @@ va_dcl
 	fmt = va_arg( ap, char * );
 #endif
 
-#ifdef LDAP_DEBUG
-	if ( lber_debug & 64 ) {
-		fprintf( stderr, "ber_scanf fmt (%s) ber:\n", fmt );
-		ber_dump( ber, 1 );
+	if ( ber->ber_debug ) {
+		lber_log_printf( LDAP_DEBUG_TRACE, ber->ber_debug,
+			"ber_scanf fmt (%s) ber:\n", fmt );
+		lber_log_dump( LDAP_DEBUG_BER, ber->ber_debug, ber, 1 );
 	}
-#endif
 
 	for ( rc = 0; *fmt && rc != LBER_DEFAULT; fmt++ ) {
 		switch ( *fmt ) {
@@ -548,9 +543,10 @@ va_dcl
 			break;
 
 		default:
-#ifdef LDAP_LIBUI
-			fprintf( stderr, "unknown fmt %c\n", *fmt );
-#endif /* LDAP_LIBUI */
+			if( ber->ber_debug ) {
+				lber_log_printf( LDAP_DEBUG_ANY, ber->ber_debug,
+					"ber_scanf: unknown fmt %c\n", *fmt );
+			}
 			rc = LBER_DEFAULT;
 			break;
 		}
diff --git a/libraries/liblber/dtest.c b/libraries/liblber/dtest.c
index a03bb626af..c6b063e74a 100644
--- a/libraries/liblber/dtest.c
+++ b/libraries/liblber/dtest.c
@@ -24,7 +24,7 @@
 #include <console.h>
 #endif /* MACOS */
 
-#include "lber-int.h"
+#include <lber.h>
 
 static void usage( char *name )
 {
@@ -37,29 +37,33 @@ main( int argc, char **argv )
 	long		i;
 	unsigned long	len;
 	int		tag;
-	BerElement	ber;
-	Sockbuf		sb;
+	BerElement	*ber;
+	Sockbuf		*sb;
 
 #ifdef HAVE_CONSOLE_H
 	ccommand( &argv );
 	cshow( stdout );
 #endif /* MACOS */
 
-	memset( &sb, 0, sizeof(sb) );
-	sb.sb_sd = 0;
-	sb.sb_ber.ber_buf = NULL;
+	sb = lber_sockbuf_alloc_fd( fileno(stdin) );
 
-	if ( (tag = ber_get_next( &sb, &len, &ber )) == -1 ) {
+	if( (ber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
+		perror( "ber_alloc_t" );
+		exit( 1 );
+	}
+
+	if ( (tag = ber_get_next( sb, &len, ber )) == -1 ) {
 		perror( "ber_get_next" );
 		exit( 1 );
 	}
 	printf( "message has tag 0x%x and length %ld\n", tag, len );
 
-	if ( ber_scanf( &ber, "i", &i ) == -1 ) {
+	if ( ber_scanf( ber, "i", &i ) == -1 ) {
 		fprintf( stderr, "ber_scanf returns -1\n" );
 		exit( 1 );
 	}
 	printf( "got int %ld\n", i );
 
+	lber_sockbuf_free( sb );
 	return( 0 );
 }
diff --git a/libraries/liblber/encode.c b/libraries/liblber/encode.c
index 37a0a44971..4f2b738365 100644
--- a/libraries/liblber/encode.c
+++ b/libraries/liblber/encode.c
@@ -609,9 +609,10 @@ va_dcl
 			break;
 
 		default:
-#ifdef LDAP_LIBUI
-			fprintf( stderr, "unknown fmt %c\n", *fmt );
-#endif /* LDAP_LIBUI */
+			if( ber->ber_debug ) {
+				lber_log_printf( LDAP_DEBUG_ANY, ber->ber_debug,
+					"ber_printf: unknown fmt %c\n", *fmt );
+			}
 			rc = -1;
 			break;
 		}
diff --git a/libraries/liblber/etest.c b/libraries/liblber/etest.c
index 6c407ddb59..266262cd0b 100644
--- a/libraries/liblber/etest.c
+++ b/libraries/liblber/etest.c
@@ -16,7 +16,7 @@
 #include <console.h>
 #endif /* HAVE_CONSOLE_H */
 
-#include "lber-int.h"
+#include <lber.h>
 
 static void usage( char *name )
 {
@@ -30,31 +30,32 @@ main( int argc, char **argv )
 	int		i, len;
 	char	*s, *p;
 #endif
-	int		num;
+	int			fd, num;
 	Seqorset	*sos = NULLSEQORSET;
 	BerElement	*ber;
-	Sockbuf		sb;
+	Sockbuf		*sb;
 
 	if ( argc < 2 ) {
 		usage( argv[0] );
 		exit( 1 );
 	}
 
-	memset( &sb, 0, sizeof(sb) );
-	sb.sb_sd = 1;
-	sb.sb_ber.ber_buf = NULL;
 
 #ifdef HAVE_CONSOLE_H
 	ccommand( &argv );
 	cshow( stdout );
 
-       if (( sb.sb_sd = open( "lber-test", O_WRONLY|O_CREAT|O_TRUNC|O_BINARY ))
+	if (( fd = open( "lber-test", O_WRONLY|O_CREAT|O_TRUNC|O_BINARY ))
 		< 0 ) {
 	    perror( "open" );
 	    exit( 1 );
 	}
+#else
+	fd = fileno(stdout);
 #endif /* MACOS */
 
+	sb = lber_sockbuf_alloc_fd( fd );
+
 	if ( (ber = ber_alloc()) == NULLBER ) {
 		perror( "ber_alloc" );
 		exit( 1 );
@@ -66,7 +67,7 @@ main( int argc, char **argv )
 		exit( 1 );
 	}
 
-	if ( ber_flush( &sb, ber, 1 ) == -1 ) {
+	if ( ber_flush( sb, ber, 1 ) == -1 ) {
 		perror( "ber_flush" );
 		exit( 1 );
 	}
@@ -166,5 +167,6 @@ main( int argc, char **argv )
 
 #endif
 
+	lber_sockbuf_free( sb );
 	return( 0 );
 }
diff --git a/libraries/liblber/io.c b/libraries/liblber/io.c
index d54047750d..968e635b4e 100644
--- a/libraries/liblber/io.c
+++ b/libraries/liblber/io.c
@@ -124,14 +124,15 @@ ber_filbuf( Sockbuf *sb, long len )
 	if ( sb->sb_naddr > 0 ) {
 #ifdef LDAP_CONNECTIONLESS
 		rc = udp_read(sb, sb->sb_ber.ber_buf, READBUFSIZ, addrlen );
-#ifdef LDAP_DEBUG
-		if ( lber_debug ) {
-			fprintf( stderr, "ber_filbuf udp_read %d bytes\n",
-				rc );
-			if ( lber_debug > 1 && rc > 0 )
-				lber_bprint( sb->sb_ber.ber_buf, rc );
+
+		if ( sb->sb_debug ) {
+			lber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
+				"ber_filbuf udp_read %d bytes\n",
+					rc );
+			if ( rc > 0 )
+				lber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
+					sb->sb_ber.ber_buf, rc );
 		}
-#endif /* LDAP_DEBUG */
 #else /* LDAP_CONNECTIONLESS */
 		rc = -1;
 #endif /* LDAP_CONNECTIONLESS */
@@ -272,15 +273,15 @@ ber_flush( Sockbuf *sb, BerElement *ber, int freeit )
 	}
 	towrite = ber->ber_ptr - ber->ber_rwptr;
 
-#ifdef LDAP_DEBUG
-	if ( lber_debug ) {
-		fprintf( stderr, "ber_flush: %ld bytes to sd %ld%s\n", towrite,
+	if ( sb->sb_debug ) {
+		lber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
+			"ber_flush: %ld bytes to sd %ld%s\n", towrite,
 		    (long) sb->sb_sd, ber->ber_rwptr != ber->ber_buf ? " (re-flush)"
 		    : "" );
-		if ( lber_debug > 1 )
-			lber_bprint( ber->ber_rwptr, towrite );
+		lber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
+			ber->ber_rwptr, towrite );
 	}
-#endif
+
 #if !defined(MACOS) && !defined(DOS)
 	if ( sb->sb_options & (LBER_TO_FILE | LBER_TO_FILE_ONLY) ) {
 		rc = write( sb->sb_fd, ber->ber_buf, towrite );
@@ -334,7 +335,8 @@ ber_alloc_t( int options )
 	if ( (ber = (BerElement *) calloc( 1, sizeof(BerElement) )) == NULLBER )
 		return( NULLBER );
 	ber->ber_tag = LBER_DEFAULT;
-	ber->ber_options = (char) options;
+	ber->ber_options = options;
+	ber->ber_debug = lber_int_debug;
 
 	return( ber );
 }
@@ -461,45 +463,6 @@ ber_reset( BerElement *ber, int was_writing )
 	ber->ber_rwptr = NULL;
 }
 
-
-#ifdef LDAP_DEBUG
-
-void
-ber_dump( BerElement *ber, int inout )
-{
-	fprintf( stderr, "ber_dump: buf 0x%lx, ptr 0x%lx, end 0x%lx\n",
-	    (long) ber->ber_buf,
-		(long) ber->ber_ptr,
-		(long) ber->ber_end );
-	if ( inout == 1 ) {
-		fprintf( stderr, "          current len %ld, contents:\n",
-		    (long) (ber->ber_end - ber->ber_ptr) );
-		lber_bprint( ber->ber_ptr, ber->ber_end - ber->ber_ptr );
-	} else {
-		fprintf( stderr, "          current len %ld, contents:\n",
-		    (long) (ber->ber_ptr - ber->ber_buf) );
-		lber_bprint( ber->ber_buf, ber->ber_ptr - ber->ber_buf );
-	}
-}
-
-void
-ber_sos_dump( Seqorset *sos )
-{
-	fprintf( stderr, "*** sos dump ***\n" );
-	while ( sos != NULLSEQORSET ) {
-		fprintf( stderr, "ber_sos_dump: clen %ld first 0x%lx ptr 0x%lx\n",
-		    (long) sos->sos_clen, (long) sos->sos_first, (long) sos->sos_ptr );
-		fprintf( stderr, "              current len %ld contents:\n",
-		    (long) (sos->sos_ptr - sos->sos_first) );
-		lber_bprint( sos->sos_first, sos->sos_ptr - sos->sos_first );
-
-		sos = sos->sos_next;
-	}
-	fprintf( stderr, "*** end dump ***\n" );
-}
-
-#endif
-
 /* return the tag - LBER_DEFAULT returned means trouble */
 static unsigned long
 get_tag( Sockbuf *sb )
@@ -544,10 +507,10 @@ ber_get_next( Sockbuf *sb, unsigned long *len, BerElement *ber )
 	long		noctets;
 	unsigned int	diff;
 
-#ifdef LDAP_DEBUG
-	if ( lber_debug )
-		fprintf( stderr, "ber_get_next\n" );
-#endif
+	if ( ber->ber_debug ) {
+		lber_log_printf( LDAP_DEBUG_TRACE, ber->ber_debug,
+			"ber_get_next\n" );
+	}
 
 	/*
 	 * Any ber element looks like this: tag length contents.
@@ -638,16 +601,47 @@ ber_get_next( Sockbuf *sb, unsigned long *len, BerElement *ber )
 		ber->ber_rwptr += rc;
 	} while ( toread > 0 );
 
-#ifdef LDAP_DEBUG
-	if ( lber_debug ) {
-		fprintf( stderr, "ber_get_next: tag 0x%lx len %ld contents:\n",
+	if ( ber->ber_debug ) {
+		lber_log_printf( LDAP_DEBUG_TRACE, ber->ber_debug,
+			"ber_get_next: tag 0x%lx len %ld contents:\n",
 		    tag, ber->ber_len );
-		if ( lber_debug > 1 )
-			ber_dump( ber, 1 );
+
+		lber_log_dump( LDAP_DEBUG_BER, ber->ber_debug, ber, 1 );
 	}
-#endif
 
 	*len = ber->ber_len;
 	ber->ber_rwptr = NULL;
 	return( ber->ber_tag );
 }
+
+Sockbuf *lber_sockbuf_alloc( void )
+{
+	Sockbuf *sb = calloc(1, sizeof(Sockbuf));
+	sb->sb_debug = lber_int_debug;
+	return sb;
+}
+
+Sockbuf *lber_sockbuf_alloc_fd( int fd )
+{
+	Sockbuf *sb = lber_sockbuf_alloc();
+	sb->sb_sd = fd;
+
+	return sb;
+}
+
+void lber_sockbuf_free( Sockbuf *sb )
+{
+	if(sb == NULL) return;
+
+	free(sb);
+}
+
+int lber_sockbuf_get_option( Sockbuf *sb, int opt, void *outvalue )
+{
+	return LBER_OPT_ERROR;
+}
+
+int lber_sockbuf_set_option( Sockbuf *sb, int opt, void *invalue )
+{
+	return LBER_OPT_ERROR;
+}
diff --git a/libraries/liblber/lber-int.h b/libraries/liblber/lber-int.h
index 66e5084d84..81def4b974 100644
--- a/libraries/liblber/lber-int.h
+++ b/libraries/liblber/lber-int.h
@@ -14,21 +14,30 @@
 #define _LBER_INT_H
 
 #include "lber.h"
+#include "ldap_log.h"
 
 LDAP_BEGIN_DECL
 
+#define LBER_ITEM_BERELEMENT 1
+#define LBER_ITEM_SOCKBUF 2
+
+extern int lber_int_debug;
+
 struct berelement {
+	short		ber_item_type; 	/* always LBER_ITEM_BERELEMENT */
+	short		ber_options;
+	int			ber_debug;
+
+	int			ber_usertag;
+
+	unsigned long	ber_tag;
+	unsigned long	ber_len;
+
 	char		*ber_buf;
 	char		*ber_ptr;
 	char		*ber_end;
+
 	struct seqorset	*ber_sos;
-	unsigned long	ber_tag;
-	unsigned long	ber_len;
-	int		ber_usertag;
-	char		ber_options;
-#define LBER_USE_DER		0x01
-#define LBER_USE_INDEFINITE_LEN	0x02
-#define LBER_TRANSLATE_STRINGS	0x04
 	char		*ber_rwptr;
 	BERTranslateProc ber_encode_translate_proc;
 	BERTranslateProc ber_decode_translate_proc;
@@ -36,26 +45,26 @@ struct berelement {
 #define NULLBER	((BerElement *) 0)
 
 struct sockbuf {
+	short		sb_item_type; 	/* always LBER_ITEM_SOCKBUF */
+	short		sb_options;	/* to support copying ber elements */
+	int			sb_debug;
+
+	int			sb_fd;
 #ifndef MACOS
 	int		sb_sd;
 #else /* MACOS */
 	void		*sb_sd;
 #endif /* MACOS */
+
+	long		sb_max_incoming;
+
 	BerElement	sb_ber;
 
-	int		sb_naddr;	/* > 0 implies using CLDAP (UDP) */
+	int			sb_naddr;	/* > 0 implies using CLDAP (UDP) */
 	void		*sb_useaddr;	/* pointer to sockaddr to use next */
 	void		*sb_fromaddr;	/* pointer to message source sockaddr */
 	void		**sb_addrs;	/* actually an array of pointers to
 						sockaddrs */
-
-	int		sb_options;	/* to support copying ber elements */
-#define LBER_TO_FILE		0x01	/* to a file referenced by sb_fd   */
-#define LBER_TO_FILE_ONLY	0x02	/* only write to file, not network */
-#define LBER_MAX_INCOMING_SIZE	0x04	/* impose limit on incoming stuff  */
-#define LBER_NO_READ_AHEAD	0x08	/* read only as much as requested  */
-	int		sb_fd;
-	long		sb_max_incoming;
 };
 #define READBUFSIZ	8192
 
@@ -69,4 +78,30 @@ struct seqorset {
 };
 #define NULLSEQORSET	((Seqorset *) 0)
 
+/*
+ * bprint.c
+ */
+LDAP_F int lber_log_printf LDAP_P((
+	int errlvl,
+	int loglvl,
+	char *fmt,
+	... ));
+
+LDAP_F int lber_log_bprint LDAP_P((
+	int errlvl,
+	int loglvl,
+	char *data,
+	int len ));
+
+LDAP_F int lber_log_dump LDAP_P((
+	int errlvl,
+	int loglvl,
+	BerElement *ber,
+	int inout ));
+
+LDAP_F int lber_log_sos_dump LDAP_P((
+	int errlvl,
+	int loglvl,
+	Seqorset *sos ));
+
 #endif /* _LBER_INT_H */
diff --git a/libraries/liblber/options.c b/libraries/liblber/options.c
new file mode 100644
index 0000000000..c6e976c80e
--- /dev/null
+++ b/libraries/liblber/options.c
@@ -0,0 +1,93 @@
+#include "portable.h"
+
+#include <stdlib.h>
+
+#include "lber-int.h"
+
+int lber_int_debug = 0;
+
+int
+lber_get_option(
+	void	*item,
+	int		option,
+	void	*outvalue)
+{
+	BerElement *ber;
+	Sockbuf *sb;
+
+	if(outvalue == NULL) {
+		/* no place to get to */
+		return LBER_OPT_ERROR;
+	}
+
+	if(item == NULL) {
+		if(option == LBER_OPT_BER_DEBUG) {
+			* (int *) outvalue = lber_int_debug;
+			return LBER_OPT_SUCCESS;
+		}
+
+		return LBER_OPT_ERROR;
+	}
+
+	ber = (BerElement *) item;
+	sb = (Sockbuf *) item;
+
+	switch(option) {
+	case LBER_OPT_BER_OPTIONS:
+		* (int *) outvalue = ber->ber_options;
+		return LBER_OPT_SUCCESS;
+
+	case LBER_OPT_BER_DEBUG:
+		* (int *) outvalue = ber->ber_debug;
+		return LBER_OPT_SUCCESS;
+
+	default:
+		/* bad param */
+		break;
+	}
+
+	return LBER_OPT_ERROR;
+}
+
+int
+lber_set_option(
+	void	*item,
+	int		option,
+	void	*invalue)
+{
+	BerElement *ber;
+	Sockbuf *sb;
+
+	if(invalue == NULL) {
+		/* no place to set from */
+		return LBER_OPT_ERROR;
+	}
+
+	if(item == NULL) {
+		if(option == LBER_OPT_BER_DEBUG) {
+			lber_int_debug = * (int *) invalue;
+			return LBER_OPT_SUCCESS;
+		}
+
+		return LBER_OPT_ERROR;
+	}
+
+	ber = (BerElement *) item;
+	sb = (Sockbuf *) item;
+
+	switch(option) {
+	case LBER_OPT_BER_OPTIONS:
+		ber->ber_options = * (int *) invalue;
+		return LBER_OPT_SUCCESS;
+
+	case LBER_OPT_BER_DEBUG:
+		ber->ber_debug = * (int *) invalue;
+		return LBER_OPT_SUCCESS;
+
+	default:
+		/* bad param */
+		break;
+	}
+
+	return LBER_OPT_ERROR;
+}
diff --git a/libraries/libldap/cldap.c b/libraries/libldap/cldap.c
index 1ed8693a15..36e2a03447 100644
--- a/libraries/libldap/cldap.c
+++ b/libraries/libldap/cldap.c
@@ -487,7 +487,7 @@ cldap_parsemsg( LDAP *ld, int msgid, BerElement *ber,
 	if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
 	    fprintf( stderr, "cldap_parsemsg add message id %d type %d:\n",
 		    ldm->lm_msgid, ldm->lm_msgtype  );
-	    ber_dump( ldm->lm_ber, 1 );
+	    lber_log_dump( LDAP_DEBUG_BER, ldap_debug, ldm->lm_ber, 1 );
 	}
 #endif /* LDAP_DEBUG */
 
diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c
index c79bdb93cf..13316a4d91 100644
--- a/libraries/libldap/init.c
+++ b/libraries/libldap/init.c
@@ -286,6 +286,8 @@ void openldap_ldap_initialize( void )
 	gopts.ldo_timelimit = LDAP_NO_LIMIT;
 	gopts.ldo_sizelimit = LDAP_NO_LIMIT;
 
+	gopts.ldo_debug = 0;
+
 	gopts.ldo_defhost = ldap_strdup("localhost");
 	gopts.ldo_defport = LDAP_PORT;
 
diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
index 7948578895..b8e8fc273c 100644
--- a/libraries/libldap/ldap-int.h
+++ b/libraries/libldap/ldap-int.h
@@ -13,7 +13,11 @@
 #endif
 
 #include "../liblber/lber-int.h"
+
+#define ldap_debug	(openldap_ldap_global_options.ldo_debug)
+
 #include "ldap_log.h"
+
 #include "ldap.h"
 
 LDAP_BEGIN_DECL
@@ -71,6 +75,8 @@ struct ldapoptions {
 	int		ldo_timelimit;
 	int		ldo_sizelimit;
 
+	int		ldo_debug;
+
 	char*	ldo_defbase;
 	char*	ldo_defhost;
 	int		ldo_defport;
diff --git a/libraries/libldap/open.c b/libraries/libldap/open.c
index f66b8dba3f..3aaf339144 100644
--- a/libraries/libldap/open.c
+++ b/libraries/libldap/open.c
@@ -24,11 +24,6 @@ static char copyright[] = "@(#) Copyright (c) 1995 Regents of the University of
 
 #include "ldap-int.h"
 
-#ifdef LDAP_DEBUG
-int	ldap_debug;
-#endif
-
-
 /*
  * ldap_open - initialize and connect to an ldap server.  A magic cookie to
  * be used for future communication is returned on success, NULL on failure.
diff --git a/libraries/libldap/options.c b/libraries/libldap/options.c
index c595972bc2..c047f5a814 100644
--- a/libraries/libldap/options.c
+++ b/libraries/libldap/options.c
@@ -178,6 +178,10 @@ ldap_get_option(
 		}
 		break;
 
+	case LDAP_OPT_DEBUG_LEVEL:
+		* (int *) outvalue = lo->ldo_debug;
+		break;
+
 	default:
 		/* bad param */
 		break;
@@ -321,6 +325,10 @@ ldap_set_option(
 			ld->ld_error = err;
 		} return 0;
 
+	case LDAP_OPT_DEBUG_LEVEL:
+		lo->ldo_debug = * (int *) invalue;
+		return 0;
+
 	default:
 		/* bad param */
 		break;
diff --git a/libraries/libldap/request.c b/libraries/libldap/request.c
index 245c73b948..c3885e6a7d 100644
--- a/libraries/libldap/request.c
+++ b/libraries/libldap/request.c
@@ -834,7 +834,7 @@ re_encode_request( LDAP *ld, BerElement *origber, int msgid, char **dnp )
 	if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
 		Debug( LDAP_DEBUG_ANY, "re_encode_request new request is:\n",
 		    0, 0, 0 );
-		ber_dump( ber, 0 );
+		lber_log_dump( LDAP_DEBUG_BER, ldap_debug, ber, 0 );
 	}
 #endif /* LDAP_DEBUG */
 
diff --git a/libraries/libldap/test.c b/libraries/libldap/test.c
index ad50e483ca..013942aa52 100644
--- a/libraries/libldap/test.c
+++ b/libraries/libldap/test.c
@@ -295,9 +295,11 @@ main( int argc, char **argv )
 		case 'd':
 #ifdef LDAP_DEBUG
 			ldap_debug = atoi( optarg );
+#ifdef LBER_DEBUG
 			if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
 				lber_debug = ldap_debug;
 			}
+#endif
 #else
 			printf( "Compile with -DLDAP_DEBUG for debugging\n" );
 #endif
@@ -477,9 +479,11 @@ main( int argc, char **argv )
 #ifdef LDAP_DEBUG
 			getline( line, sizeof(line), stdin, "debug level? " );
 			ldap_debug = atoi( line );
+#ifdef LBER_DEBUG
 			if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
 				lber_debug = ldap_debug;
 			}
+#endif
 #else
 			printf( "Compile with -DLDAP_DEBUG for debugging\n" );
 #endif
diff --git a/libraries/libldif/line64.c b/libraries/libldif/line64.c
index 14037b5379..fba438c67e 100644
--- a/libraries/libldif/line64.c
+++ b/libraries/libldif/line64.c
@@ -10,10 +10,12 @@
 #include <ac/socket.h>
 #include <ac/time.h>
 
+int ldif_debug = 0;
+
+#define ldap_debug	ldif_debug
 #include "ldap_log.h"
 #include "ldif.h"
 
-
 #define RIGHT2			0x03
 #define RIGHT4			0x0f
 #define CONTINUED_LINE_MARKER	'\001'
diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c
index c2f4656d74..45ce3150d8 100644
--- a/servers/slapd/backend.c
+++ b/servers/slapd/backend.c
@@ -201,7 +201,8 @@ be_isroot( Backend *be, char *dn )
 		return( 0 );
 	}
 
-	return( be->be_rootdn ? strcasecmp( be->be_rootdn, dn ) == 0
+	return( be->be_rootdn != NULL
+		? strcasecmp( be->be_rootdn, dn ) == 0
 	    : 0 );
 }
 
diff --git a/servers/slapd/main.c b/servers/slapd/main.c
index f81df898c3..e17b7c2f76 100644
--- a/servers/slapd/main.c
+++ b/servers/slapd/main.c
@@ -16,12 +16,14 @@
  * read-only global variables or variables only written by the listener
  * thread (after they are initialized) - no need to protect them with a mutex.
  */
-int		ldap_debug = 0;
+int		slap_debug = 0;
+
 #ifdef LDAP_DEBUG
 int		ldap_syslog = LDAP_DEBUG_STATS;
 #else
 int		ldap_syslog;
 #endif
+
 int		ldap_syslog_level = LOG_DEBUG;
 int		udp;
 char		*default_referral;
@@ -107,8 +109,7 @@ main( int argc, char **argv )
 				    LDAP_DEBUG_ANY );
 				exit( 0 );
 			} else {
-				ldap_debug |= atoi( optarg );
-				lber_debug = (ldap_debug & LDAP_DEBUG_BER);
+				slap_debug |= atoi( optarg );
 			}
 			break;
 #else
@@ -144,6 +145,10 @@ main( int argc, char **argv )
 		}
 	}
 
+	lber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug);
+	ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &slap_debug);
+	ldif_debug = slap_debug;
+
 	Debug( LDAP_DEBUG_TRACE, "%s", Versionstr, 0, 0 );
 
 	if ( (myname = strrchr( argv[0], '/' )) == NULL ) {
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index e7c2dd2ffd..fbce7eba8e 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -17,9 +17,15 @@
 #include <assert.h>
 
 #include "avl.h"
+
+#ifndef ldap_debug
+#define ldap_debug slap_debug
+#endif
+
+#include "ldap_log.h"
+
 #include "../../libraries/liblber/lber-int.h"
 #include "ldap.h"
-#include "ldap_log.h"
 
 #include "lthread.h"
 #include "lthread_rdwr.h"
@@ -39,6 +45,8 @@
 
 LDAP_BEGIN_DECL
 
+extern int slap_debug;
+
 struct op;
 struct conn;
 
diff --git a/servers/slurpd/args.c b/servers/slurpd/args.c
index c3b202065c..57b80c111c 100644
--- a/servers/slurpd/args.c
+++ b/servers/slurpd/args.c
@@ -65,8 +65,8 @@ doargs(
 
     while ( (i = getopt( argc, argv, "hd:f:r:t:k:o" )) != EOF ) {
 	switch ( i ) {
-#ifdef LDAP_DEBUG
 	case 'd':	/* turn on debugging */
+#ifdef LDAP_DEBUG
 	    if ( optarg[0] == '?' ) {
 		printf( "Debug levels:\n" );
 		printf( "\tLDAP_DEBUG_TRACE\t%d\n",
@@ -89,14 +89,13 @@ doargs(
 			LDAP_DEBUG_ANY );
 		return( -1 );
 	    } else {
-		ldap_debug = atoi( optarg );
+		ldap_debug |= atoi( optarg );
 	    }
-	    break;
 #else /* LDAP_DEBUG */
-	case 'd':	/* can't enable debugging - not built with debug code */
+		/* can't enable debugging - not built with debug code */
 	    fprintf( stderr, "must compile with LDAP_DEBUG for debugging\n" );
-	    break;
 #endif /* LDAP_DEBUG */
+	    break;
 	case 'f':	/* slapd config file */
 	    g->slapd_configfile = strdup( optarg );
 	    break;
@@ -140,6 +139,10 @@ doargs(
     sprintf( g->slurpd_status_file, "%s/%s", g->slurpd_rdir,
 	    DEFAULT_SLURPD_STATUS_FILE );
 
+	lber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &ldap_debug);
+	ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &ldap_debug);
+	ldif_debug = ldap_debug;
+
 #ifdef LOG_LOCAL4
     openlog( g->myname, OPENLOG_OPTIONS, LOG_LOCAL4 );
 #else
diff --git a/servers/slurpd/re.c b/servers/slurpd/re.c
index 02e558116b..f44601c1ac 100644
--- a/servers/slurpd/re.c
+++ b/servers/slurpd/re.c
@@ -27,10 +27,11 @@
 #include <ac/string.h>
 #include <ac/ctype.h>
 
-#include "../slapd/slap.h"
 #include "slurp.h"
 #include "globals.h"
 
+#include "../slapd/slap.h"
+
 /* Forward references */
 static Rh 	*get_repl_hosts LDAP_P(( char *, int *, char ** ));
 static int	gettype LDAP_P(( char * ));
diff --git a/servers/slurpd/slurp.h b/servers/slurpd/slurp.h
index 445e48d62a..4e1e96ab2c 100644
--- a/servers/slurpd/slurp.h
+++ b/servers/slurpd/slurp.h
@@ -19,13 +19,15 @@
 #define LDAP_SYSLOG 1
 #endif
 
-#include <ac/syslog.h>
 #include <ac/errno.h>
+#include <ac/syslog.h>
 
 #include <sys/param.h>
 
 #include "lber.h"
 #include "ldap.h"
+
+#define ldap_debug slurp_debug
 #include "ldap_log.h"
 
 #include "lthread.h"
-- 
GitLab