The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 080
MANIFEST 05
META.json 13
Makefile.PL 04
README 04
SIGNATURE 4651
contrib/README 11
contrib/dot.tklkup 1414
contrib/isMember.pl 99
contrib/jpegDisplay.pl 8990
contrib/jpegLoad.pl 2020
contrib/ldapmodify.pl 33
contrib/ldifdiff.pl 2222
contrib/ldifsort.pl 55
contrib/ldifuniq.pl 55
contrib/printMembers.pl 1515
contrib/recursive-ldap-delete.pl 11
contrib/simple-proxy.pl 88
contrib/tklkup 995995
data/10-in.ldif 095
data/postalAddress.txt 01
lib/Net/LDAP/Bind.pm 26
lib/Net/LDAP/Control/Paged.pm 22
lib/Net/LDAP/Control/ProxyAuth.pm 55
lib/Net/LDAP/Control.pm 2737
lib/Net/LDAP/Entry.pm 33
lib/Net/LDAP/Entry.pod 22
lib/Net/LDAP/FAQ.pod 1423
lib/Net/LDAP/Filter.pm 45
lib/Net/LDAP/LDIF.pm 210278
lib/Net/LDAP/LDIF.pod 632
lib/Net/LDAP/Message.pod 74
lib/Net/LDAP/Util.pm 1115
lib/Net/LDAP.pm 1231
lib/Net/LDAP.pod 1133
t/00ldif-entry.t 33
t/08time.t 0122
t/09ldif-http-url.t 039
t/10ldif-controls.t 061
t/40connect.t 23
t/60cancel.t 12
t/common.pl 11
test.cfg 211
43 files changed (This is a version diff) 15592149
@@ -1,3 +1,83 @@
+0.64 -- Thu Jun 19 17:48:08 CEST 2014
+
+Bug Fixes:
+* LDAP.pm: set SSL_cipher_list correctly
+* RT#96203: LDAP.pm: use correct length for syswrite
+* LDIF.pm: fix next outside loop in _write_one_entry
+* Entry.pod: fix typo
+
+0.63 -- Sun Jun  1 12:42:59 CEST 2014
+
+Enhancements:
+* Entry.pm: accept options for update() in the LDIF case
+* LDIF.pm:
+  - implement writing controls
+  - refactor _write_entry
+  - check for decoding errors in LWP-based URLs
+
+Bug Fixes:
+* RT#95001: Do not set SSL_ciphers to ALL by default
+* Entry.pm: delete(): return $self if called w/o args
+
+0.62 -- Sun Apr  6 11:25:05 CEST 2014
+
+Enhancements:
+Util.pm: remove superfluous space from POD
+FAQ.pm: update perl-ldap & Perl version numbers
+
+Bug Fixes:
+RT#94357: t/08time.t: skip tests on too old Perl versions
+RT#94341: FAQ.pm: fix incorrect instruction
+jpegDisplay.pl: overhaul to make it work again
+
+0.61 -- Sat Mar 29 17:21:45 CET 2014
+
+Enhancements:
+* {LDAP,LDIF}.pod: update documentation of raw => REGEX
+* support LWP-supproted URLs when reading LDIFs (incl. tests)
+* add test for Net::LDAP::Util's time functions
+* tests: set default OpenLDAP DB type to mdb
+
+Bug Fixes:
+* RT#94047: Control.pm: add missing word in POD
+* RT#93945: Util.pm: make sure $dec is defined
+* LDIF.pm: when reading LDIFs, allow control values to be absent
+* Control/ProxyAuth.pm: fix initialization using value => ...
+* Util.pm: fix corner cases in time conversion functions
+
+0.60 -- Sat Mar  8 14:00:02 CET 2014
+
+Enhancements:
+* IO::Socket::IP support
+  - if installed in version 0.20 or higher, prefer it over IO::Socket::INET*
+  - use IO::Socket::INET* as fallback if it isn't installed
+  - this solves RT#93122, which IMHO is not really a bug of perl-ldap
+* remove trailing whitespace in contrib/*
+
+0.59 -- Tue Mar  4 16:21:15 CET 2014
+
+Bug Fixes:
+* Handle SASL security layers correctly on rebind
+  Thanks Ben Morrow <ben@morrow.me.uk>
+* Control/Paged.pm: fix typo in POD sample code
+
+Enhancements:
+* t/60cancel.t: add explanation about potential cause of failure
+* LDAP.pm: accessor method sasl for Authen::SASL object
+* LDAP.pm: adapt socket() to support SASL layers
+* Message.pod: consolidate dcwocumentation of control()
+* Control.pm: documentation update
+* LDAP.pod: add note about IO::Socket::IP and Timeout
+* LDIF.pm: overhaul
+  - set error when write fails
+  - simplify _read_entry
+  - simplify _write_entry
+  - coding style harmonization
+  - error checks when reading changetype: delete
+  - make _error() return undef/empty list, adapt callers
+  - refactor handling DNs when reading
+  - new method _read_attribute_value()
+
 0.58 -- Mon Dec 23 17:35:53 CET 2013
 
 Bug Fixes:
@@ -22,6 +22,7 @@ data/00-cmp.ldif
 data/00-cmp2.ldif
 data/00-in.ldif
 data/05-cmp.dsml
+data/10-in.ldif
 data/40-cmp.ldif
 data/40-in.ldif
 data/41-in.ldif
@@ -40,6 +41,7 @@ data/key.pem
 data/man.jpg
 data/openldap.schema
 data/openssl.cnf
+data/postalAddress.txt
 data/regenerate_cert.sh
 data/schema.in
 data/slapd.conf.in
@@ -132,6 +134,9 @@ t/04refloop.t
 t/05dsml.t
 t/06constant.t
 t/07filtermatch.t
+t/08time.t
+t/09ldif-http-url.t
+t/10ldif-controls.t
 t/40connect.t
 t/41populate.t
 t/42search.t
@@ -1,6 +1,6 @@
 {
    "name" : "perl-ldap",
-   "version" : "0.58",
+   "version" : "0.64",
    "abstract" : "LDAP client library",
    "author" : [
       "Graham Barr <gbarr@cpan.org>"
@@ -52,8 +52,10 @@
             "Time::Local" : "0"
          },
          "suggests" : {
+            "IO::Socket::IP" : "0.20",
             "XML::SAX::Writer" : "0",
             "XML::SAX::Base" : "0",
+            "LWP" : "0",
             "LWP::Protocol" : "0",
             "LWP::MediaTypes" : "0",
             "HTTP::Negotiate" : "0",
@@ -59,6 +59,10 @@ features
 		'XML::SAX::Writer' => 0,
 		'XML::SAX::Base'   => 0,
 	],
+	'Extended URL support when reading LDIFs' => [
+		-default => 0,
+		'LWP' => 0,
+	],
 	'LWP support for the LDAP protocol family' => [
 		-default => 0,
 		'LWP::Protocol'   => 0,
@@ -28,6 +28,7 @@ QUICK START GUIDE:
 	Convert::ASN1     - required
 	IO::Socket::SSL   - optional, for LDAPS / start_tls support
 	IO::Socket::INET6 - optional, for IPv6 support
+	IO::Socket::IP    - optional, for IPv6 support
 	Authen::SASL      - optional, for SASL authentication
 	Digest::MD5       - optional, for SASL DIGEST-MD5 mechanism
 	GSSAPI            - optional, for SASL GSSAPI mechanism
@@ -35,6 +36,9 @@ QUICK START GUIDE:
 	XML::SAX::Writer  - optional, for Net::LDAP::DSML
 	Time::Local       - optional, for Net::LDAP::Util's time conversion functions
 
+    If IO::Socket::IP 0.20 or higher is installed, it is dynamically (at runtime)
+    preferred over IO::Socket::INET6.
+
     First ensure the above modules/distributions are installed then
     build/test/install Net::LDAP by doing
 
@@ -12,39 +12,40 @@ the distribution may already have been compromised, and you should
 not run its Makefile.PL or Build.PL.
 
 -----BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA256
+Hash: SHA512
 
 SHA1 b3d7b971ea6fc7fbb96cdf4cea3d1cdf68f4d24f CREDITS
-SHA1 a7ea3169fdca82c009202386976e4ad4cb2af17c Changes
+SHA1 36c60ba36b93dc72f4648d86689d2441c57c3935 Changes
 SHA1 18422f27b2f17b10e9d18b4e482d7bfc95c8df86 INSTALL
-SHA1 037d70bd2535dc79bda1bafca57dad7682851ffc MANIFEST
+SHA1 d0cf6f1c5a385cf66d2cd9e8d137a841f3ed3541 MANIFEST
 SHA1 b1dde8d68f20d9f0353c7a891f4efbaa20882305 MANIFEST.SKIP
-SHA1 bcfb597c5fda0cbcfb967043c159c59812659a44 META.json
-SHA1 ffe82367f16b332f397246be40203027297afc34 Makefile.PL
-SHA1 dcc1167f3a731aa88d036f282bad68b23e5c2ac1 README
+SHA1 fab71b334cb7eff7074037849b256048e24df8b2 META.json
+SHA1 0f1365258da52746c8ac8c22a7c654841c821700 Makefile.PL
+SHA1 9336db57bbd198e5e91b51d8140f287b6ad75e3c README
 SHA1 45d3c0297db0a7e960a2456ece90ea3e37242919 TODO
 SHA1 8e15e7abefa826736358685aa1115810baaa9b4a bin/ldapdelete
 SHA1 fb042e706fb1f873b39138c95b8f362a8f1bea8d bin/ldapmodrdn
 SHA1 212b83f5dae352596008329dc6bfac445a3ab4ac bin/ldapsearch
 SHA1 0820488b025a7d48333e6f8ec640993be155d3cd contrib/LWPsearch.pl
-SHA1 4fe62673c3d2d30fcf6ce320ed303695e5cba078 contrib/README
-SHA1 a74eca9ed266c3bf2280744a3c05aecaaf0c222a contrib/dot.tklkup
-SHA1 c1528100aa9eae5d5e98f778820e83af7c584fa2 contrib/isMember.pl
-SHA1 1b11ae1f3e5cde0d577988fd8936c4895e0c6096 contrib/jpegDisplay.pl
-SHA1 45be5e0f79345b5e55e8b1b97c25615c8b43d547 contrib/jpegLoad.pl
-SHA1 848646da05eed8b27cb7d498cfb421ed1a67a5c5 contrib/ldapmodify.pl
-SHA1 7543799f405159a69f4394c59f35617efa1478d8 contrib/ldifdiff.pl
-SHA1 eb6932a765ae6f1ba47f75b1919dd1335cbb82f8 contrib/ldifsort.pl
-SHA1 9823ffdc3c2d75d0d4af5f3c1ec60bf6e8c5e037 contrib/ldifuniq.pl
-SHA1 eacb3515921f5843240603f949c83e3b1c1f725e contrib/printMembers.pl
-SHA1 6950da15067e5b7c27bfb29158ebdbd503eb3485 contrib/recursive-ldap-delete.pl
+SHA1 9a79b09a78fbf359ed819cded02a71154ef8e2b3 contrib/README
+SHA1 15c559d9d501ec4664ef420f97ec958a841d266f contrib/dot.tklkup
+SHA1 af504d7e6af5cad90fedcfa0df87fecb69cf37a7 contrib/isMember.pl
+SHA1 59784e0c0ac4a30d5d61618f72b9a3c7db0d7a40 contrib/jpegDisplay.pl
+SHA1 91dae5879db27450eae4fc50870671851c67e9e4 contrib/jpegLoad.pl
+SHA1 2235c04837a9f561b69717aebd1659fca71d87d0 contrib/ldapmodify.pl
+SHA1 2bcf4acae2198af5ced3985f20a123ada5c3a813 contrib/ldifdiff.pl
+SHA1 3dd34852187944c11277b272084decfdc7b39f74 contrib/ldifsort.pl
+SHA1 a47c2edbf920151e3761488a8baa1bead3b2ff57 contrib/ldifuniq.pl
+SHA1 af68dac3af68b1db44c6221056cb227c34a8c54a contrib/printMembers.pl
+SHA1 027a8921bdda837a060e24c2572992507605894e contrib/recursive-ldap-delete.pl
 SHA1 3b6aac6e5e237307efa3506a6c8e0ca7d60208a0 contrib/schema2ad.pl
-SHA1 df87a8de85e4952f48325c4d8d218b7ec46ccb6b contrib/simple-proxy.pl
-SHA1 ba3288445bdf161914b9632f20c81c09c0800bf5 contrib/tklkup
+SHA1 884c491c55195e60b448d5a1ba62c3c27be5c339 contrib/simple-proxy.pl
+SHA1 77e6ef6dc78cd1ac173b4827f5657232c1372c4b contrib/tklkup
 SHA1 6294227b00010f90afc17c2c6f114a0ef7610c15 data/00-cmp.ldif
 SHA1 1739c30b959c46cf0402447f79a555235b7992e7 data/00-cmp2.ldif
 SHA1 25488cd6943fc31cdce5dcc57e2ab0e71b0af6fa data/00-in.ldif
 SHA1 cbe464de69d6ce8cdd685a6c974cadefa30f59e4 data/05-cmp.dsml
+SHA1 77a0d97d36237917818f2adb162558ac0b31d580 data/10-in.ldif
 SHA1 b09b216730801f2e87ac6477209b9880d01760e2 data/40-cmp.ldif
 SHA1 cb80f6c7512155ef78e088c2bc646c060e6b28a6 data/40-in.ldif
 SHA1 75ead7bee1a193df0d85b1213ce7598b8f9ceebf data/41-in.ldif
@@ -63,6 +64,7 @@ SHA1 33947f5584a583ecd2fc87782ea6fb4b0c6fbbf4 data/key.pem
 SHA1 725bddda1e67a25aa2ad26bc7dcbdf1c292ec85d data/man.jpg
 SHA1 7897801051b6437fd96f79b1a001a31c8ebd4e6b data/openldap.schema
 SHA1 9cbcaaf738631b82bb02a602e91377b26f3858c0 data/openssl.cnf
+SHA1 43711d6620d869315a409963db83790e8b032f19 data/postalAddress.txt
 SHA1 a9ef9a3261b37bf32d810a879d77165512ca45c6 data/regenerate_cert.sh
 SHA1 7efb3a704a09e1981312fc10430959f8553f7dfc data/schema.in
 SHA1 948d7db5102d58a3ea2a04dd401b40e3ba082cd8 data/slapd.conf.in
@@ -83,22 +85,22 @@ SHA1 ae47bafae19103063a8903d071843e4276cfbb02 lib/Bundle/Net/LDAP.pm
 SHA1 e3ae35cf39741a7fa85f11671b6c12cbcf8ffbd4 lib/LWP/Protocol/ldap.pm
 SHA1 4c0725acda3f08370b63824a62a9cca2dc52b858 lib/LWP/Protocol/ldapi.pm
 SHA1 1cb4c54544fda3f59b11470c3e21c8d2022b40b9 lib/LWP/Protocol/ldaps.pm
-SHA1 769f02810910cdd8bc3b7b356014b18d1072498b lib/Net/LDAP.pm
-SHA1 bba287f34fbebdf1915c645154ab3ea4bd484ab1 lib/Net/LDAP.pod
+SHA1 d26e8f3069d48045795a6ed1d42355cf4a2cd81b lib/Net/LDAP.pm
+SHA1 0ed492170aaf5f2d690d0212f78bc29e6c119f2b lib/Net/LDAP.pod
 SHA1 4cf74c0f17bd8bd684e1775bbc361f0eba5fd829 lib/Net/LDAP/ASN.pm
-SHA1 941fb60d0aade9b827cf1df3ed37c8ec9d9d70ab lib/Net/LDAP/Bind.pm
+SHA1 423e93cc380a526311bb91aa500d97d5fa4eb6da lib/Net/LDAP/Bind.pm
 SHA1 72208c59c57b8d687ca5541ed981195795105bb4 lib/Net/LDAP/Constant.pm
-SHA1 6c8135c8b886bf58dff0da6dfa37a7c55f0ace5a lib/Net/LDAP/Control.pm
+SHA1 c5ea13c5cd7bdd0eaed85928e9aef94b14538973 lib/Net/LDAP/Control.pm
 SHA1 8d9e40e9d0bb94f9b2cdb865b10c4bd7db5b96b0 lib/Net/LDAP/Control/Assertion.pm
 SHA1 132de095e47c3937e46e40061f4589780bb913ca lib/Net/LDAP/Control/EntryChange.pm
 SHA1 cd635c78479d2d9550147633e81d0a55ced85050 lib/Net/LDAP/Control/ManageDsaIT.pm
 SHA1 dec36f3e05b369725ba4c10ee41924a5742c68e9 lib/Net/LDAP/Control/MatchedValues.pm
-SHA1 4ef5d292b78bc8fbdd83501fc1247da1e8820a61 lib/Net/LDAP/Control/Paged.pm
+SHA1 5b224d684da21e504c3738d7671d7972444d93d2 lib/Net/LDAP/Control/Paged.pm
 SHA1 5def1a80ac4f2d4d54a7e58eeaabc709809ba056 lib/Net/LDAP/Control/PasswordPolicy.pm
 SHA1 7c35ec08c53f6d91696e96d8a8dad24131f34f23 lib/Net/LDAP/Control/PersistentSearch.pm
 SHA1 66b21ddd57d5d609510bc1bc1f5e65c1c3ddb6b2 lib/Net/LDAP/Control/PostRead.pm
 SHA1 f4344e69b392a0aed91b77cfe478bc3b58b9ae36 lib/Net/LDAP/Control/PreRead.pm
-SHA1 c440e1cf6334da809e038f3c03377ae199a1c1f8 lib/Net/LDAP/Control/ProxyAuth.pm
+SHA1 e914fd0f0d07044c968ec7b3a49fb28fa6b67495 lib/Net/LDAP/Control/ProxyAuth.pm
 SHA1 d192ab5e04c2ca9aa56af0920c9006ee84cb86e9 lib/Net/LDAP/Control/Relax.pm
 SHA1 1a7e82c52c01348a3b7b6c8e5e573832506e59e3 lib/Net/LDAP/Control/Sort.pm
 SHA1 cfba44f46dfd51d479f63c1c258f90788dd32b6b lib/Net/LDAP/Control/SortResult.pm
@@ -108,8 +110,8 @@ SHA1 4e3b116d79176b0fb2a2be3b04a5afff32763552 lib/Net/LDAP/Control/SyncState.pm
 SHA1 15b15d592c41098431679c42d1795a717e5b1414 lib/Net/LDAP/Control/VLV.pm
 SHA1 a895fb1e2a244c3adb312e9efb1ee40b89dabe58 lib/Net/LDAP/Control/VLVResponse.pm
 SHA1 684fac988baf21bce4323fa97577f07f9ad095ba lib/Net/LDAP/DSML.pm
-SHA1 c0076ece64d05984c24b5e4ab652bc09aa751bab lib/Net/LDAP/Entry.pm
-SHA1 28fd0ab9cc3ccac1d3e568a9d75804e1b31144ea lib/Net/LDAP/Entry.pod
+SHA1 378acefdb1e1e2bffb3e73ff0e97d59d0b2a2b30 lib/Net/LDAP/Entry.pm
+SHA1 de238a95dd2bd0b8b73c79f1d4b66ac0bc92ff53 lib/Net/LDAP/Entry.pod
 SHA1 2a20c984e7ff49a53a95d2233374ba18a446e5dc lib/Net/LDAP/Examples.pod
 SHA1 0195e6ab43507bceb5fe0797c751e85f9cbf4fbf lib/Net/LDAP/Extension.pm
 SHA1 94a97cdb53a2437d8fca5805f679626ea66e9cf6 lib/Net/LDAP/Extension/Cancel.pm
@@ -119,16 +121,16 @@ SHA1 9a6ba9fc53dcb41f216f277b3b89fbbbf29417c8 lib/Net/LDAP/Extension/WhoAmI.pm
 SHA1 f8a69d8a6c086fdf38c12a72816bcd3d624ac261 lib/Net/LDAP/Extra.pm
 SHA1 21863d25b0bff03ef279e10efe707539c7cd448c lib/Net/LDAP/Extra/AD.pm
 SHA1 e8f760369f662f5b36cb1812282fb657f026bb18 lib/Net/LDAP/Extra/eDirectory.pm
-SHA1 d8300b672ec5ca1023ec157998bdd6009e875a5e lib/Net/LDAP/FAQ.pod
-SHA1 37174a971d6ffa5283b508f3c8fc657c624558c9 lib/Net/LDAP/Filter.pm
+SHA1 f7377019e5046571e966d491b2981284e03815da lib/Net/LDAP/FAQ.pod
+SHA1 b3be6c23ac12314a7c2c5cedfabf68591303692b lib/Net/LDAP/Filter.pm
 SHA1 0209a4d3c52a6cb2330a15fc9db2a6d686f42c0e lib/Net/LDAP/Filter.pod
 SHA1 5bf16183794a235f2b7929ce350fe9032a8a1636 lib/Net/LDAP/FilterMatch.pm
 SHA1 a1ae96a07309aeb49f0025a536d9074ae55b43c1 lib/Net/LDAP/Intermediate.pm
 SHA1 4a2cbf16a0436782db19f126d587c17799823714 lib/Net/LDAP/Intermediate/SyncInfo.pm
-SHA1 e18033b45f28fae9777638cf463e1cbaa90ec74a lib/Net/LDAP/LDIF.pm
-SHA1 f4c6fa55228cab320d79db6732edebadc176a420 lib/Net/LDAP/LDIF.pod
+SHA1 addc67b75dd5e44913eb47adbd2e3eee8618bcb3 lib/Net/LDAP/LDIF.pm
+SHA1 a8ecab7277098bb6b2d657b9e16960b0738b0cde lib/Net/LDAP/LDIF.pod
 SHA1 70255d10236d45ee645be63f51257f283af4db67 lib/Net/LDAP/Message.pm
-SHA1 6a8b2d30a43d6295de37771c2576cb66c7f10bfd lib/Net/LDAP/Message.pod
+SHA1 b2023e232032c111473f8addc802f37d40cd0482 lib/Net/LDAP/Message.pod
 SHA1 76961fd1aa4b78c8c7ad6f9638c2cf0a3aefb281 lib/Net/LDAP/RFC.pod
 SHA1 4921a9eb85f595aaa4c5c2bf7261feae54440763 lib/Net/LDAP/Reference.pod
 SHA1 f8e82f88b6d0160d57730f7a38845060cdfb9e8a lib/Net/LDAP/RootDSE.pm
@@ -137,10 +139,10 @@ SHA1 e3af23701aa0c14b21cc85e8fd9f50337ef908d1 lib/Net/LDAP/Schema.pod
 SHA1 1835813ea3a15daadd224a70bdc6d99afc2f37ed lib/Net/LDAP/Search.pm
 SHA1 7c982f3ea575be892eabe7a4bdbc83fa3d341530 lib/Net/LDAP/Search.pod
 SHA1 4b26cf51ff535d6e5bda888dded5962d59a7ce4a lib/Net/LDAP/Security.pod
-SHA1 9ed1928343dd69152520cd50409818ba55375955 lib/Net/LDAP/Util.pm
+SHA1 82dd8987a33e5cc289819f88e5309a0bff3e4d6c lib/Net/LDAP/Util.pm
 SHA1 b69e822e4f2a2e6bf1f1a46febd64c38581f6b7d lib/Net/LDAPI.pm
 SHA1 e53f9b7b96c9a31d9a5a83309301c4a0b6b7400c lib/Net/LDAPS.pm
-SHA1 597ef9192f4a32a125393baa8afea48b17d88166 t/00ldif-entry.t
+SHA1 58316abac720f453c71fdceeb7d7e01432a03c08 t/00ldif-entry.t
 SHA1 f38c4d5745741f309e19cd37403e89ab8ebc9813 t/01canon_dn.t
 SHA1 f273242b84a55fd1b5650cfcb1b0fe5f6585bf19 t/02filter.t
 SHA1 597ad626d087446f18a971c89e4597abd48acc3c t/03schema.t
@@ -148,7 +150,10 @@ SHA1 a37b37639de26666dc11a16492a86f82b620a34d t/04refloop.t
 SHA1 55afdcc98524242dc92abb13e1c651dffa3efef6 t/05dsml.t
 SHA1 3af9d72c25bb5092d2a6779cf086eb82bd5244f3 t/06constant.t
 SHA1 4304acd9b08ecdeb0d7ba40f429f39df3670d670 t/07filtermatch.t
-SHA1 2d7028cb0e5b6c0012855f922a0e9116e5bed30b t/40connect.t
+SHA1 5cbf1f8c4f72d894b4b0b79fbab33856a1ee2c7d t/08time.t
+SHA1 5fd23e68f1761dfb52a851290ea2f4ccfbfb8a6d t/09ldif-http-url.t
+SHA1 94f91ea8ed70fa0c3ebc0a9af2bcce229a2440d2 t/10ldif-controls.t
+SHA1 85a17949f57c0c011a10be1cc84040f7cb0ead3a t/40connect.t
 SHA1 475e5cea559d71ad95e9b170faa82b4bc9f4eeb1 t/41populate.t
 SHA1 b555a519acb877d5d0192de19aa728f94b0256bb t/42search.t
 SHA1 a667c625b689452cc243256a2090e4093853cda8 t/43modify.t
@@ -158,22 +163,22 @@ SHA1 f34b6a3a7b20a76ca112a7c990bdfd2539e82c51 t/46ssl.t
 SHA1 a215528c8720051c3618f13b438bd0fe7c7f66a7 t/47ipc.t
 SHA1 59209bd86fdc61e75eb56e4562c273fdc8417144 t/48url.t
 SHA1 21223e1cdc91f16e3e11f21a7ffda8da54102599 t/49lwp.t
-SHA1 ed31642a61c9e8eabdc5512dca26fc03d093db0a t/60cancel.t
+SHA1 80046c992edf36dd20d349ddfbf77acf9dc27ad2 t/60cancel.t
 SHA1 7937fb8aa1eac68e8bb80e45e2513edcd2c19b22 t/70sortctrl.t
 SHA1 804d275b50505b33bbdd604ac82699ef49358923 t/71preread.t
 SHA1 243db5ee07aac845c98edcd5cfcca9f29c4a9863 t/72postread.t
 SHA1 c18ddb5404354a7da445d65efe85a9129abff6ac t/73assert.t
 SHA1 e0370c941f4e8d54f1dc309256341d70c5952082 t/74matchedvalues.t
-SHA1 1632a66cb14d4d3fb446a36bd9098b42616ce19a t/common.pl
-SHA1 ea5c5379848a59de0912fbb9f65ae2e86b735b6e test.cfg
+SHA1 7ada7e0dfb856f0ca2ca53654e7c83d33e751e3c t/common.pl
+SHA1 ceee4437567d85d44529c521391b00e1c751420e test.cfg
 -----BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.15 (GNU/Linux)
+Version: GnuPG v1
 
-iQEcBAEBCAAGBQJSuGh4AAoJEEp47DaHHvaSo+UH/jHHBVndhYsm5QurfIisdELZ
-rCv3Mei/eY8xE2i4eJSLIlvP9PZew1sm19Gn+sPUF7Ut4iJpyDTUkNfBvLMTYwy0
-o+qXnGPc8u8XC4C56eTlZrS4HwnnjCoCO5mFMBKJspRXKetvw3LML0fGLzcehLwE
-gsFEwjPap2HaVNtkGpagTcr1Wn4RjIfz8yJ5s9w9hW6bJip51yCGV0zsm6rUSbg5
-Z6IBea7kAqqsColK76+ABsQNR5WtPSsNDs15uo0t+XSz9shxWVXBo1MD89xo1mOD
-j6kS2bVxWSfsLUZ2fMhJMV5jxz42XhMIRjx28n/q3SnPZgd+5p+rUWUlkzd3JFs=
-=wtUl
+iQEcBAEBCgAGBQJTowbWAAoJEEp47DaHHvaSqFUH/0UjNpOa2FXnYq2Ema4hr46d
+e3zsEhWIdOcDROLgemBZLyCNL96JCtZhJsNn9nPKiY6PB8Fyuqv6SLaY1G1cPgUs
+PFllzgBd4RRzR6BZkVJVRhWyF4MVrRqBbLHnvdTsn22bBCR2IiyvimDdOThgck2w
+6KGYc9GO507EQ/5amLN/YkaZMal9AyTbwDz3zPyzv7Cc18ktdSy3II0AWiugOW1Q
+fKMozPeCseKnaT1+wUezcKcmCfpC7UFY0k8vwoQOIEusoblcU4ke+lkWj94nHAXb
+M4km4RX1CS2lxwx/GxrqDEq0r9xwEVaEWTgSqW6B9eCFdR5eCXRX2R6dDNJMq+k=
+=g1AH
 -----END PGP SIGNATURE-----
@@ -12,7 +12,7 @@ The files in this directory are
   jpegLoad.pl     Load JPEG photos into an LDAP directory entry
   ldapmodify.pl   A (simplified) ldapmodify clone written in Perl
   ldifdiff.pl     Generate LDIF change diff between two sorted LDIF files
-  ldifsort.pl	  Sort an LDIF file by the specified key attribute. 
+  ldifsort.pl	  Sort an LDIF file by the specified key attribute.
   ldifuniq.pl	  Cull unique entries from a reference file with
                   respect to a comparison file.
   LWPsearch.pl    A sample application to show the usage of LWP::Protocol::LDAP
@@ -5,15 +5,15 @@
 #
 # Uncomment and setup the bind DN line if you want to pre-populate
 # the bind DN value.
-# binddn: cn=directory manager, dc=dummy, dc=com 
+# binddn: cn=directory manager, dc=dummy, dc=com
 #
 #
 # Uncomment the followref line if you wish to automatically follow
 # referrals on entry modification.  No value is needed after the
 # colon.
 #
-# followref: 
-# 
+# followref:
+#
 #
 # Default main window width, user may need to adjust
 # Sun systems seem to do best on 600.
@@ -57,20 +57,20 @@ sslport: 636
 # Set up the search attributes you want listed on
 # the Attribute and Select Additional Attributes button.
 #
-attribute: uid 
-attribute: cn 
-attribute: sn 
-attribute: rfc822mailbox 
-attribute: uidNumber 
-attribute: gidNumber 
-attribute: telephonenumber 
-attribute: facsimiletelephonenumber 
-attribute: givenname 
-attribute: fullname 
+attribute: uid
+attribute: cn
+attribute: sn
+attribute: rfc822mailbox
+attribute: uidNumber
+attribute: gidNumber
+attribute: telephonenumber
+attribute: facsimiletelephonenumber
+attribute: givenname
+attribute: fullname
 attribute: firstname
 #
 # Set up the Directory Servers you want listed on
 # the Select Directory Server button.
 #
 server: directory.ucalgary.ca: ou=People,o=ucalgary.ca
-server: www.uark.edu: o=University of Arkansas, c=US 
+server: www.uark.edu: o=University of Arkansas, c=US
@@ -1,7 +1,7 @@
 #!/usr/local/bin/perl
 
-#isMember.pl 
-#pass the common name of a group entry (assuming groupOfUniqueNames objectclass) and 
+#isMember.pl
+#pass the common name of a group entry (assuming groupOfUniqueNames objectclass) and
 #a uid, the script will tell you if the uid is a member of the group or not.
 
 $version = 3.0_01;
@@ -52,7 +52,7 @@ my $isMember = 0; # by default you are not a member
 my $ldap = new Net::LDAP ($opt_h, port=> $opt_p);
 
 #will bind as specific user if specified else will be binded anonymously
-$ldap->bind($opt_D, password=> $opt_p) || die "failed to bind as $opt_D"; 
+$ldap->bind($opt_D, password=> $opt_p) || die "failed to bind as $opt_D";
 
 
 #get user DN first
@@ -87,7 +87,7 @@ eval
 
    &getIsMember($groupDN,$userDN);
 
-}; 
+};
 
 
 die $mesg->error if $mesg->code;
@@ -170,9 +170,9 @@ sub getIsMember
 
         #if we find an entry it returns true
 	#else keep searching
-	
+
         eval
-	{ 
+	{
           my $entry = $mesg->pop_entry();
 	  print "ldapurl",$entry->dn,"\n" if $DEBUG;
 
@@ -185,7 +185,7 @@ sub getIsMember
 
 
       my $membervalues = $entry->get_value("uniquemember", asref => 1);
-    
+
      foreach my $val (@{$membervalues})
      {
        my $return= &getIsMember($val,$userDN);
@@ -193,13 +193,13 @@ sub getIsMember
        #stop as soon as we have a winner
        last if $isMember;
      }
-     
+
 
      die $mesg->error if $mesg->code;
 
 
      #if make it this far then you must be a member
-  
+
    };
 
    return $0;
@@ -1,5 +1,5 @@
 #!/usr/local/bin/perl
-#  
+#
 #----------------------------------------------------------------------------
 #
 # This program was written by Clif Harden.
@@ -10,7 +10,7 @@
 # $Id: jpegDisplay.pl,v 1.2 2003/06/18 18:23:31 gbarr Exp $
 #
 # Purpose: This program is designed to retrieve jpeg photo data
-#          from a LDAP directory.
+#          from an LDAP directory.
 #
 #
 # Revisions:
@@ -28,8 +28,6 @@
 use Getopt::Std;
 use Net::LDAP;
 use Net::LDAP::Filter;
-use Net::LDAP;
-use Net::LDAP::Util qw(ldap_error_name ldap_error_text); 
 use Tk;
 use Tk::JPEG;
 
@@ -38,101 +36,104 @@ use Tk::JPEG;
 # You can change the defaults to match your setup.
 # This can eliminate the need for many of the input
 # options on the command line.
-# 
+#
 my %opt = (
-  'b' => 'dc=harden,dc=org',
-  'h' => 'localhost',
-  'd' => 0,
-  'D' => 'cn=manager',
-  'w' => 'password',
-  'V' => '3',
-  'a' => 'cn',
-  'v' => 'commonName'
+  b => 'dc=harden,dc=org',
+  h => 'localhost',
+  d => 0,
+  D => 'cn=manager',
+  w => 'password',
+  V => 3,
+  a => 'cn',
+  v => 'commonName'
 );
 
-if ( @ARGV == 0 ) 
-{
+if (@ARGV == 0) {
 #
 # print usage message.
 #
-Usage();
+  Usage();
 }
 
 #
 # Get command line options.
-# 
+#
 
-getopts('b:h:d:D:w:V:a:v:',\%opt);
+getopts('b:h:d:D:w:V:a:v:Z',\%opt);
 
 #
 # build filter string
 #
-my $match = "( $opt{'a'}=$opt{'v'}  )";
+my $match = "( $opt{a}=$opt{v}  )";
 
-$jpegFile = "./$opt{'a'}=$opt{'v'}.jpg";
+my $jpegFile = "./$opt{a}=$opt{v}.jpg";
 
 #
 # create filter object
 #
-my $f = Net::LDAP::Filter->new($match) or die "Bad filter '$match'";
+my $filter = Net::LDAP::Filter->new($match)
+  or die "Bad filter '$match'";
 
 #
 # make ldap connection to directory.
 #
-my $ldap = new Net::LDAP($opt{'h'},
+my $ldap = new Net::LDAP($opt{h},
                          timeout => 10,
-                         debug => $opt{'d'},
-                        ) or die $@;
+                         debug => $opt{d},
+                         version => $opt{V})
+  or die $@;
 
 #
-# Bind to directory.
+# call start_tls
 #
-$ldap->bind($opt{'D'}, password => "$opt{'w'}", version => $opt{'V'}) or die $@;
+if ($opt{Z}) {
+  $ldap->start_tls();
+}
 
 #
-# Search directory for record that matches filter 
+# Bind to directory.
 #
-$mesg = $ldap->search(
-  base   => $opt{b},
-  filter => $f,
-  attrs  => ["jpegPhoto"],
-) or die $@;
+my $mesg = $ldap->bind($opt{D}, password => "$opt{w}");
+die $mesg->error,$mesg->code
+  if $mesg->code;
 
+#
+# Search directory for record that matches filter
+#
+$mesg = $ldap->search(base   => $opt{b},
+                      filter => $filter,
+                      attrs  => ['jpegPhoto']);
 die $mesg->error,$mesg->code
-	if $mesg->code;
+  if $mesg->code;
 
 #
 # get record entry object
 #
 $entry = $mesg->entry();
 
-if ( !defined($entry) )
-{
-    print "\n";
-    print "No data for filter $match.\n" if ($mesg->count == 0) ;
-    print "\n";
+if ( !defined($entry) ) {
+  print "\n";
+  print "No data for filter $match.\n" if ($mesg->count == 0) ;
+  print "\n";
 }
-else
-{
+else {
   my @attrs = sort $entry->attributes;
   my $max = 0;
 
   $dn = $entry->dn();
 
-    my $attr = $entry->get_value("jpegPhoto");
-    if(ref($attr)) 
-      {
-      $picture = @$attr[0];
-      }
-    else
-     {
-      print "\n";
-      print "No jpegPhoto attribute for DN\n";
-      print "$dn\n";
-      print "\n";
-      $ldap->unbind;
-      exit;
-     } 
+  my @pictures = $entry->get_value('jpegPhoto');
+  if(@pictures) {
+    $picture = $pictures[0];
+  }
+  else {
+    print "\n";
+    print "No jpegPhoto attribute for DN\n";
+    print "$dn\n";
+    print "\n";
+    $ldap->unbind;
+    exit;
+  }
 }
 
 #
@@ -145,13 +146,12 @@ $| = 1;
 print TMP $picture;
 close(TMP);
 
-if ( !-e "$jpegFile" )
-{
-print "\n";
-print "Could not create temporary jpeg file $jpegFile\n";
-print "\n";
-$ldap->unbind;
-exit(1);
+if ( !-e "$jpegFile" ) {
+  print "\n";
+  print "Could not create temporary jpeg file $jpegFile\n";
+  print "\n";
+  $ldap->unbind;
+  exit(1);
 }
 
 $ldap->unbind;
@@ -161,10 +161,10 @@ $ldap->unbind;
 #
 my $mw  = MainWindow->new();
 
-my $list = $mw ->Listbox( -height => 1, width => length($dn)  );  
-$list->pack( -side => "top" );  
-$list->insert("end", $dn);                                                                                 
-my $image = $mw->Photo(-file => $jpegFile, -format => "jpeg" );
+my $list = $mw->Listbox(-height => 1, -width => length($dn));
+$list->pack(-side => 'top');
+$list->insert('end', $dn);
+my $image = $mw->Photo(-file => $jpegFile, -format => 'jpeg');
 
 print "\n";
 print "Displaying jpegPhoto for\n";
@@ -182,39 +182,40 @@ unlink $jpegFile;
 #----------------------------------------#
 sub Usage
 {
-   print( "Usage: [-b] <base> | [-h] <host> | [-d] <number> | [-D] <DN> | [-w] <password> | [-a] <attribute> | [-v] <data>\n" );
-   print( "\t-b    Search base.\n" );
-   print( "\t-d    Debug mode.  Display debug messages to stdout.\n" );
-   print( "\t-D    Authenication Distingushed Name.\n" );
-   print( "\t-h    LDAP directory host computer.\n" );
-   print( "\t-w    Authenication password.\n" );
-   print( "\t-a    Attribute that will be incorporated into the search filter.\n" );
-   print( "\t-v    Data that will be incorporated into the search filter.\n" );
-   print( "\t-V    LDAP version of the LDAP directory.\n" );
-   print( "\n" );
-   print( "\t      Perldoc pod documentation is included in this script.\n" );
-   print( "\t      To read the pod documentation do the following;\n" );
-   print( "\t      perldoc <script name>\n" );
-   print( "\n" );
-   print( "\n" );
-   exit( 1 );
-}                                                                               
+  print( "Usage: [-Z] [-b <base>] [-h <host>] [-d <number>] [-D <DN>] [-w <password>] [-a <attribute>] [-v <data>]\n" );
+  print( "\t-b    Search base.\n" );
+  print( "\t-d    Debug mode.  Display debug messages to stdout.\n" );
+  print( "\t-D    Authenication Distingushed Name.\n" );
+  print( "\t-h    LDAP directory host computer.\n" );
+  print( "\t-w    Authenication password.\n" );
+  print( "\t-a    Attribute that will be incorporated into the search filter.\n" );
+  print( "\t-v    Data that will be incorporated into the search filter.\n" );
+  print( "\t-V    LDAP version of the LDAP directory.\n" );
+  print( "\t-Z    start SSL encryption using start_tls.\n" );
+  print( "\n" );
+  print( "\t      Perldoc pod documentation is included in this script.\n" );
+  print( "\t      To read the pod documentation do the following;\n" );
+  print( "\t      perldoc <script name>\n" );
+  print( "\n" );
+  print( "\n" );
+  exit( 1 );
+}
 
 __END__
 
 =head1 NAME
 
-jpegDisplay.pl  -  A script to display a jpeg picture from jpegPhoto attribute of a LDAP directory entry.
+jpegDisplay.pl  -  A script to display a jpeg picture from jpegPhoto attribute of an LDAP directory entry.
 
 =head1 SYNOPSIS
 
 The intent of this script is to show the user how to retrieve and
-display a jpeg photo from a LDAP directory entry.
+display a jpeg photo from an LDAP directory entry.
 
-This script has been tested on a OpenLDAP 2.0.7 directory server
+This script has been tested on OpenLDAP 2.0.7 & 2.4.39 directory servers
 and a Netscape 4.x LDAP directory server.
 
-You may need to change the first line of the PERL jpegDisplay.pl script
+You may need to change the first line of the Perl jpegDisplay.pl script
 to point to your file pathname of perl.
 
 =head1 Input options.
@@ -227,13 +228,13 @@ to point to your file pathname of perl.
  -a    Attribute that will be incorporated into the search filter.
  -v    Data that will be incorporated into the search filter.
  -V    LDAP version of the LDAP directory.
-
+ -Z    start SSL encryption using start_tls
 
  Usage: jpegDisplay.pl -b <base> -h <host> -d <number> -D <DN> \
                     -w <password> -a <attribute> -v <data>
 
-Inside the script is a opt hash that can be initialized to 
-default values that can elminate the need for many of the 
+Inside the script is a opt hash that can be initialized to
+default values that can eliminate the need for many of the
 input options on the command line.
 
 -------------------------------------------------------------------
@@ -1,5 +1,5 @@
 #!/usr/local/bin/perl
-#  
+#
 #----------------------------------------------------------------------------
 #
 # This program was written by Clif Harden.
@@ -38,13 +38,13 @@ my $errstr = 0;
 my $errmsg = "";
 
 $errmsg = ldap_error_text($errstr);
-   
+
 #
 # Initialize opt hash.
 # You can change the defaults to match your setup.
 # This can eliminate the need for many of the input
 # options on the command line.
-# 
+#
 my %opt = (
   'b' => 'dc=harden,dc=org',
   'h' => 'localhost',
@@ -56,7 +56,7 @@ my %opt = (
   'v' => 'commonName'
 );
 
-if ( @ARGV == 0 ) 
+if ( @ARGV == 0 )
 {
 #
 # print usage message.
@@ -66,14 +66,14 @@ Usage();
 
 #
 # Get command line options.
-# 
+#
 
 getopts('b:f:h:d:D:w:V:a:v:',\%opt);
 
 
-if ( !defined( $opt{'f'}) || !-e $opt{'f'} ) 
+if ( !defined( $opt{'f'}) || !-e $opt{'f'} )
 {
-# 
+#
 # No jpeg file specified or the file does not exist.
 #
 print "$opt{'f'}\n";
@@ -89,8 +89,8 @@ $, = undef;
 #
 open(IN, "<$opt{'f'}");
 binmode(IN);
-$_ = <IN>;   
-close(IN); 
+$_ = <IN>;
+close(IN);
 
 #
 # build filter string
@@ -116,7 +116,7 @@ my $ldap = new Net::LDAP($opt{'h'},
 $ldap->bind($opt{'D'}, password => "$opt{'w'}", version => $opt{'V'}) or die $@;
 
 #
-# Search directory for record that matches filter 
+# Search directory for record that matches filter
 #
 my $mesg = $ldap->search(
   base   => $opt{'b'},
@@ -164,7 +164,7 @@ if(ref($attr))
   # Entry already has a jpegPhoto, replace it.
   #
   push( @memberChange, "replace" );     # ldap replace operation
-  push( @memberChange, \@addMember );     # ldap data to add 
+  push( @memberChange, \@addMember );     # ldap data to add
 }
 else
 {
@@ -172,18 +172,18 @@ else
   # Entry does not have a jpegPhoto, add it.
   #
   push( @memberChange, "add" );     # ldap add operation
-  push( @memberChange, \@addMember );     # ldap data to add 
-}                                                                          
+  push( @memberChange, \@addMember );     # ldap data to add
+}
 
 $mesg = $ldap->modify( $dn, changes => [ @memberChange ] ) or die $@;
 
-if ( $mesg->code ) 
+if ( $mesg->code )
 {
    $errstr = $mesg->code;
    print "Error code:  $errstr\n";
    $errmsg = ldap_error_text($errstr);
    print "$errmsg\n";
-   
+
 }
 
 $ldap->unbind;
@@ -211,7 +211,7 @@ sub Usage
    print( "\n" );
    print( "\n" );
    exit( 1 );
-}                                                                               
+}
 
 __END__
 
@@ -221,8 +221,8 @@ jpegLoad.pl -  A script to load a jpeg picture into the jpegPhoto attribute of a
 
 =head1 SYNOPSIS
 
-The intent of this script is to show the user how to load a 
-picture that is in jpeg format into the jpegPhoto attribute of 
+The intent of this script is to show the user how to load a
+picture that is in jpeg format into the jpegPhoto attribute of
 a directory entry.
 The entry in question must have the schema defined to
 allow the loading of the jpegPhoto attribute.
@@ -251,8 +251,8 @@ to point to your file pathname of perl.
                     -w <password> -a <attribute> -v <data> \
                     -f <jpeg file>
 
-Inside the script is a opt hash that can be initialized to 
-default values that can eliminate the need for many of the 
+Inside the script is a opt hash that can be initialized to
+default values that can eliminate the need for many of the
 input options on the command line.
 
 -------------------------------------------------------------------
@@ -2,7 +2,7 @@
 
 # $Id: ldapmodify.pl,v 1.1 2001/10/23 15:07:41 gbarr Exp $
 
-=head1 NAME 
+=head1 NAME
 
 ldapmodify.pl - A (simplified) ldapmodify clone written in Perl.
 
@@ -12,7 +12,7 @@ ldapmodify.pl is a simplified ldapmodify clone written in Perl.
 
 =head1 SYNOPSIS
 
-ldapmodify.pl [B<-a>] [B<-c>] [B<-e errors>] [B<-f file>] [B<-D binddn>] 
+ldapmodify.pl [B<-a>] [B<-c>] [B<-e errors>] [B<-f file>] [B<-D binddn>]
 [B<-w passwd>] [B<-h ldaphost>] [B<-p port>]
 
 The options have the same meaning as those for the standard ldapmodify command.
@@ -44,7 +44,7 @@ while (my $change = $ldif->read_entry()) {
 		print STDERR "ldapmodify: ", $result->error, "\n";
 		if ($opt{e}) {
 			if (!$ldiferr) {
-				$ldiferr = Net::LDAP::LDIF->new($opt{e}, 'a', change => 1) 
+				$ldiferr = Net::LDAP::LDIF->new($opt{e}, 'a', change => 1)
 					or die "$opt{e}: $!\n";
 			}
 			print { $ldiferr->{fh} } "# Error: ", $result->error;
@@ -6,8 +6,8 @@ ldifdiff.pl -- Generates LDIF change diff between two sorted LDIF files.
 
 =head1 DESCRIPTION
 
-ldifdiff.pl takes as input two sorted LDIF files, source and target, and 
-generates on standard output the LDIF changes needed to transform the target 
+ldifdiff.pl takes as input two sorted LDIF files, source and target, and
+generates on standard output the LDIF changes needed to transform the target
 into the source.
 
 =head1 SYNOPSIS
@@ -20,9 +20,9 @@ ldifdiff.pl B<-k|--keyattr keyattr> [B<-a|--sourceattrs attr1,attr2,...>] [B<-c|
 
 =item B<-k|--keyattr> keyattr
 
-Specifies the key attribute to use when comparing source and target entries. 
-Entries in both LDIF files must be sorted by this attribute for comparisons to 
-be meaningful. F<ldifsort.pl> can be used to sort LDIF files by a given 
+Specifies the key attribute to use when comparing source and target entries.
+Entries in both LDIF files must be sorted by this attribute for comparisons to
+be meaningful. F<ldifsort.pl> can be used to sort LDIF files by a given
 attribute.
 
 =item B<-a|--sourceattrs attr1,attr2,...>
@@ -32,12 +32,12 @@ source and target entries. By default, all attributes are considered.
 
 =item B<-c|--ciscmp attr1,...>
 
-(Optional) Compare values of the specified attributes case-insensitively. The 
+(Optional) Compare values of the specified attributes case-insensitively. The
 default set is: mail manager member objectclass owner uid uniqueMember
 
 =item B<-n|--numcmp attr1,...>
 
-(Optional) Compare values of the specified attributes numerically. The 
+(Optional) Compare values of the specified attributes numerically. The
 default set is: employeeNumber
 
 =item B<--dnattrs attr1,...>
@@ -49,7 +49,7 @@ compared. The default set is: manager member owner uniqueMember
 
 (Optional) Specifies a list of attribues to be treated as "shared" attributes,
 where the source may not be a sole authoritative source. When modifying
-these attributes, separate "delete" and "add" LDIF changes are generated, 
+these attributes, separate "delete" and "add" LDIF changes are generated,
 instead of a single "replace" change. The default set is objectClass.
 
 =item B<sourcefile>
@@ -129,7 +129,7 @@ sub dnsuperior { my $rv = ($_[0] =~ /^.*?(?<!\\),(.*)/)[0]; $rv }
 sub cmpDNs
 {
 	my ($adn, $bdn) = @_;
-	my $cadn = canonical_dn($adn, casefold => 'lower'); 
+	my $cadn = canonical_dn($adn, casefold => 'lower');
 	my $cbdn = canonical_dn($bdn, casefold => 'lower');
 	my $rdnattr = lc rdnattr($cadn);
 	if ($ciscmp{$rdnattr}) { $cadn = lc($cadn), $cbdn = lc($cbdn) }
@@ -138,14 +138,14 @@ sub cmpDNs
 }
 
 sub cmpEntries
-{ 
+{
 	my ($a, $b) = @_;
 	my $dncmp = cmpDNs($a->dn, $b->dn);
 
-	if (lc($keyattr) eq 'dn') { 
+	if (lc($keyattr) eq 'dn') {
 		return ($dncmp, $dncmp);
 	}
-	else { 
+	else {
 		my $aval = $a->get_value($keyattr);
 		my $bval = $b->get_value($keyattr);
 		if ($ciscmp{$keyattr}) {
@@ -159,7 +159,7 @@ sub cmpEntries
 
 # Diffs two LDIF data sources
 sub diff
-{ 
+{
 	my ($source, $target) = @_;
 	my ($sourceentry, $targetentry, $incr_source, $incr_target, @ldifchanges);
 
@@ -185,15 +185,15 @@ sub diff
 
 		my ($entrycmp, $dncmp) = cmpEntries($sourceentry, $targetentry);
 
-		# Check if the current source entry has a higher sort position than 
-		# the current target. If so, we interpret this to mean that the 
+		# Check if the current source entry has a higher sort position than
+		# the current target. If so, we interpret this to mean that the
 		# target entry no longer exists on the source. Issue a delete to LDAP.
 		if ($entrycmp > 0) {
 			$targetentry->delete;
 			$ldifout->write_entry($targetentry);
             $incr_target = 1, next;
 		}
-		# Check if the current source entry has a lower sort position than 
+		# Check if the current source entry has a lower sort position than
 		# the current target entry. If so, we interpret this to mean that the
 		# source entry doesn't exist on the target. Issue an add to LDAP.
 		elsif ($entrycmp < 0) {
@@ -210,7 +210,7 @@ sub diff
 			my $rdnval = rdnval($sourceentry->dn);
 			my $newsuperior = dnsuperior($sourceentry->dn);
 			my $oldsuperior = dnsuperior($targetentry->dn);
-			my $changetype; 
+			my $changetype;
 
 			if (cmpDNs($oldsuperior, $newsuperior)) {
 				$changetype = 'moddn';
@@ -225,7 +225,7 @@ sub diff
 			$targetentry->delete('deleteoldrdn');
 			$targetentry->delete('newsuperior') if $changetype eq 'moddn';
 			delete($targetentry->{changetype});
-			
+
 			$targetentry->dn($sourceentry->dn);
 			$targetentry->replace($rdnattr, $sourceentry->get_value($rdnattr))
 				if $sourceentry->exists($rdnattr);
@@ -257,8 +257,8 @@ sub updateFromEntry
 		# add all source entry attributes
 		@attrs = $source->attributes;
 		# add any other attributes we haven't seen from the target entry
-		foreach my $tattr ($target->attributes) { 
-			push(@attrs, $tattr) unless grep(/^$tattr$/i, @attrs) 
+		foreach my $tattr ($target->attributes) {
+			push(@attrs, $tattr) unless grep(/^$tattr$/i, @attrs)
 		}
 	}
 
@@ -299,8 +299,8 @@ sub updateFromEntry
 
 		# Make changes as appropriate
 		if ($sharedattrs{$lcattr}) {
-			# For 'shared' attributes (e.g. objectclass) where $source may not 
-			# be a sole authoritative source, we issue separate delete and 
+			# For 'shared' attributes (e.g. objectclass) where $source may not
+			# be a sole authoritative source, we issue separate delete and
 			# add modifications instead of a single replace.
 			$target->delete($attr => [ values(%targetuniqvals) ])
 				if keys(%targetuniqvals);
@@ -8,7 +8,7 @@ version is written to standard output.
 
 =head1 DESCRIPTION
 
-Sorts an LDIF file by the specified key attribute. 
+Sorts an LDIF file by the specified key attribute.
 
 =head1 SYNOPSIS
 
@@ -19,13 +19,13 @@ ldifsort.pl B<-k keyattr> [B<-andc>] file.ldif
 =item B<-k>
 
 Specifies the key attribute for making sort comparisons. If 'dn' is
-specified, sorting is done by the full DN string, which can be composed of 
+specified, sorting is done by the full DN string, which can be composed of
 different attributes for different entries.
 
 =item B<-a>
 
 Specifies that attributes within a given entry should also be sorted. This
-has the side effect of removing all comments and line continuations in the 
+has the side effect of removing all comments and line continuations in the
 LDIF file.
 
 =item B<-n>
@@ -36,7 +36,7 @@ comparisons are done.
 =item B<-d>
 
 Specifies that the key attribute is a DN. Comparisons are done on a
-DN-normalized version of attribute values. This is the default 
+DN-normalized version of attribute values. This is the default
 behavior if 'dn' is passed as the argument to B<-k>.
 
 =item B<-c>
@@ -92,7 +92,7 @@ while (<LDIFH>) {
 sub cmpattr { $a->[0] cmp $b->[0] }
 sub cmpattrnum { $a->[0] <=> $b->[0] }
 my %canonicaldns;
-sub cmpdn { 
+sub cmpdn {
 	my $cadn = ($canonicaldns{$a->[0]} ||= lc(canonical_dn($a->[0])));
 	my $cbdn = ($canonicaldns{$b->[0]} ||= lc(canonical_dn($b->[0])));
 	$cadn cmp $cbdn;
@@ -10,10 +10,10 @@ comparison file.
 =head1 DESCRIPTION
 
 ldifuniq.pl takes as input two LDIF files, a reference file and a comparison
-file. Each entry in the reference file is compared to its counterpart in the 
-comparison file. If it does not have a counterpart, or if the counterpart is 
-not identical, the reference entry is printed to standard output. Otherwise no 
-output is generated. This behavior is analogous to the -u option of the uniq 
+file. Each entry in the reference file is compared to its counterpart in the
+comparison file. If it does not have a counterpart, or if the counterpart is
+not identical, the reference entry is printed to standard output. Otherwise no
+output is generated. This behavior is analogous to the -u option of the uniq
 command.
 
 =head1 SYNOPSIS
@@ -66,7 +66,7 @@ while (<REFFH>) {
 	my $refrec = $_; $refrec .= "\n" if $refrec !~ /\n\n$/;
 	my $dn = getdn($refrec);
 	my $pos = $cmpdnpos{$dn};
-	if ($pos eq undef) { 
+	if ($pos eq undef) {
 		print $refrec; next; # Not in cmpfile, print the entry.
 	}
 	seek(CMPFH, $pos, 0);
@@ -1,16 +1,16 @@
 #!/usr/local/bin/perl
 
-#printMembers.pl 
+#printMembers.pl
 #given the name of a group (assume object class is groupOfUniqueNames) will
 #display the members of the group including members of any groups that may be a member
 #of the original group
 
 #*Now Handles Netscape Dynamic Groups*
 #
-#By default it will display the DN of the member entries, you can specify a particular 
+#By default it will display the DN of the member entries, you can specify a particular
 #attribute you wish to display instead (e.g. mail attribute)
 
-#example: printMembers.pl -n "Accounting Managers" 
+#example: printMembers.pl -n "Accounting Managers"
 
 
 #optionally you can also specify the host, port, binded search and search base.
@@ -48,7 +48,7 @@ my $isGroup = 0; #checks for group or not
 my $ldap = new Net::LDAP ($opt_h, port=> $opt_p);
 
 #will bind as specific user if specified else will be binded anonymously
-$ldap->bind($opt_D, password=> $opt_p) || die "failed to bind as $opt_D"; 
+$ldap->bind($opt_D, password=> $opt_p) || die "failed to bind as $opt_D";
 
 
 #get the group DN
@@ -112,7 +112,7 @@ sub printMembers
 
        #now get entry of each member
        #is a bit more efficient since we use the DN of the member
-       #as our search base, greatly reducing the number of entries we 
+       #as our search base, greatly reducing the number of entries we
        #must search through for a match to 1 :)
 
        my @entryAttrs = ["objectclass","memberurl",$attr];
@@ -147,14 +147,14 @@ sub printMembers
 
         my $values = $entry->get_value("objectclass", asref => 1);
 
-        # This value is also a group, print the members of it as well  
+        # This value is also a group, print the members of it as well
 
 
         &printMembers($entry->dn(),$attr) if (grep /groupOfUniqueNames/i, @{$values});
      };
-   } 
+   }
         my $urls = $entry->get_value("memberurl", asref => 1);
-	&printDynamicMembers($entry->dn(),$urls,$attr) if ($urls); 
+	&printDynamicMembers($entry->dn(),$urls,$attr) if ($urls);
  };
     return 0;
   }
@@ -164,9 +164,9 @@ sub printMembers
 #prints out a search results
 #for members of dynamic group (as supported by the Netscape Directory Server)
 
-#*Note this may or may not return all of the resulting members and their attribute values 
+#*Note this may or may not return all of the resulting members and their attribute values
 #depending on how the LDAP connection is binded. Normally users who are not binded as the Directory Manager
-#are restricted to 2000 or less total search results. 
+#are restricted to 2000 or less total search results.
 
 #In theory a dynamic group could have a million or more entries
 sub printDynamicMembers
@@ -190,7 +190,7 @@ sub printDynamicMembers
      my $base = $uri->dn();
 
      print "base is $base\n" if $DEBUG;
-     my $scope = $uri->scope(); 
+     my $scope = $uri->scope();
 
      my $filter = $uri->filter();
 
@@ -202,12 +202,12 @@ sub printDynamicMembers
 	       filter => $filter,
 	       attrs => @attrs
 	       );
- 
+
      #print results
 
      my $entry;
      while ($entry = $mesg->pop_entry())
-     { 
+     {
 
         if ($attr)
 	{
@@ -221,12 +221,12 @@ sub printDynamicMembers
         else
 	{
            print $entry->dn(),"\n";
-	} 
+	}
      }
 
     }
   return 0;
-} 
+}
 
 
 
@@ -27,6 +27,6 @@ my $search      = $ldap->search( base   => $delbranch,
 # trick for the sorting: tr/,// returns number of , (see perlfaq4 for details)
 foreach my $e (sort { $b->dn =~ tr/,// <=> $a->dn =~ tr/,// } $search->entries()) {
   $ldap->delete($e);
-}  
+}
 
 $ldap->unbind();
@@ -24,10 +24,10 @@ sub handle($$)
   # read from client
   asn_read($clientsocket, my $reqpdu);
   log_request($reqpdu);
-  
+
   # send to server
   print $serversocket $reqpdu or die "Could not send PDU to server\n";
-  
+
   # read from server
   my $ready;
   my $sel = IO::Select->new($serversocket);
@@ -74,7 +74,7 @@ sub run_proxy($$)
   my $targetsock = shift;
 
   return unless ($listenersock && $targetsock);
-  
+
   my $sel = IO::Select->new($listenersock);
   my %Handlers;
   while (my @ready = $sel->can_read) {
@@ -102,7 +102,7 @@ my $listenersock = IO::Socket::INET->new(
 	Proto => 'tcp',
 	Reuse => 1,
 	LocalPort => 7070 )
-  or  die "Could not create listener socket: $!\n";	
+  or  die "Could not create listener socket: $!\n";
 
 
 my $targetsock = IO::Socket::INET->new(
@@ -120,17 +120,17 @@ __END__
 
 Hi,
 
-I noticed in the TODO that there was a request for a simple proxy which 
+I noticed in the TODO that there was a request for a simple proxy which
 can act as a man-in-the-middle.
 
-Well, the attached script provides such a proxy, it is really a simple 
-proxy as it can currently handle only one client at the time, it will 
+Well, the attached script provides such a proxy, it is really a simple
+proxy as it can currently handle only one client at the time, it will
 dump requests and responses to STDOUT both in ASN1 and as perl structure.
 
 Cheers,
 
 Hans
-ps. If you need a little more power like returning entries on a query I 
+ps. If you need a little more power like returning entries on a query I
 suggest to have a look at Net::LDAP::Server on CPAN.
 
 # EOF
@@ -55,13 +55,13 @@ my %Tree   = ();
 $Global{'jpeg'}   = 1;
 eval 'require Tk::JPEG';
 $Global{'jpeg'}   = 0 if ( $@ );
- 
+
 $Global{'splash'}   = 1;
 eval { require Tk::Splashscreen;
        require Tie::Watch;
       };
 $Global{'splash'}   = 0 if ( $@ );
- 
+
 #
 # Window roots
 #
@@ -70,9 +70,9 @@ $Global{'schemaWindow'} = undef();
 $Global{'histWindow'}   = undef();
 $Global{'portWindow'}   = undef();
 $Global{'bindWindow'}   = undef();
- 
+
 my %schemaHash = ();
- 
+
 &init_schemaHash;
 
 $Global{'LDAP_SERVER'} = "";
@@ -118,13 +118,13 @@ my $sepChar          = "\f";       # formfeed separator
 #--------------------------------------------------------
 # Handle the command line parameter(s)
 #--------------------------------------------------------
- 
+
 getopts( 'hnrd:i:' );
- 
+
 Usage() if ( $opt_h );
 
 my $debug  = $opt_n ? 1 : 0;
- 
+
 # Fork this process on start up.
 #
 # If not in debug mode;
@@ -134,9 +134,9 @@ my $debug  = $opt_n ? 1 : 0;
 
 if ( !$debug && $Global{'platform'} eq 'unix' ) {
 
- 
+
         FORK: {
- 
+
                 if ( $pid = fork ) {
                         # this is parent process, so DIE
                         #
@@ -146,12 +146,12 @@ if ( !$debug && $Global{'platform'} eq 'unix' ) {
                         # this is the child process, so keep on running
                         #
                         &MAIN_PROCESS();
- 
+
                         } # End of elsif in FORK.
- 
+
         } # End of FORK block.
- 
- 
+
+
 } # End of if.
 else {
         #
@@ -159,9 +159,9 @@ else {
         #
         &MAIN_PROCESS();
         } # End of else
- 
- 
-sub MAIN_PROCESS { 
+
+
+sub MAIN_PROCESS {
 
 $Global{'mainWindow'} = MainWindow->new;
 $splash = $Global{'mainWindow'}->Splashscreen(-milliseconds => 0)
@@ -169,7 +169,7 @@ $splash = $Global{'mainWindow'}->Splashscreen(-milliseconds => 0)
 $splframe = $splash->LabFrame(-label => "TKLKUP SPLASH SCREEN",
       -labelside => "acrosstop")
       ->pack() if ( $Global{splash} );
- 
+
 $splashList = $splframe->Listbox( -height => 2, -width => 40  )
         if ( $Global{splash} );
 $splashList->pack()
@@ -196,22 +196,22 @@ $splashList->insert("0", "Setting tklkup GUI.")
         if ( $Global{splash} );
 $splash->update()
         if ( $Global{splash} );
- 
+
 $Global{'mainWindow'}->title("TKLKUP");
 #
 # Create the Menubar
 #
- 
+
 $Global{'mainWindow'}->configure(-menu => $Global{'menubar'} = $Global{'mainWindow'}->Menu);
- 
+
 $Global{'menubar'}->cascade(-label => "Directory ~OPS",
                   -menuitems => ops_items);
 $Global{'menubar'}->command(-label => "Set ~Bind Credentials",
                   -command => \&BIND );
 $Global{'menubar'}->command(-label => "Set DSA ~Port",
-                  -command => \&PORT ); 
+                  -command => \&PORT );
 $Global{'menubar'}->command(-label => "E~XIT PROGRAM",
-                  -command => sub{exit;} ); 
+                  -command => sub{exit;} );
 
 #
 # Create process Exit button
@@ -220,17 +220,17 @@ $mwf = $Global{'mainWindow'} -> Frame() -> pack(-side => "top");
 
 $mwf ->Label( -text => "DIRECTORY SERVER") ->pack (-side =>"left");
 $Global{'slist'} = $mwf ->Listbox( -height => 1  );
- 
+
 $Global{'slist'}->pack( -side => "left", -padx => 2, -pady => 5  );
- 
+
 $Global{'slist'}->insert("end", $Global{'LDAP_SERVER'});
- 
+
 #
 # Create directory server selection button
 # This is where the user will select the directory server to
 # query.
 #
- 
+
 $smenu = $mwf -> Menubutton(-text => "SELECT SERVER",
                   -relief => "raised", -font => $Global{'Font'},
                   -borderwidth => 3 )
@@ -239,7 +239,7 @@ $smenu = $mwf -> Menubutton(-text => "SELECT SERVER",
 #
 # Create a LDAP version status label
 #
- 
+
 $Versionstatus = $mwf -> Label -> pack(-side => "left", -anchor => "center" );
 
 if ( $Global{setVersion} == 3 )
@@ -250,7 +250,7 @@ else
 {
  $Versionstatus->configure( -text => "LDAP V2", -font => $Global{Font});
 }
- 
+
 #
 # Create a SSL status label
 #
@@ -259,7 +259,7 @@ $SSLstatus = $mwf -> Label -> pack(-side => "left", -anchor => "center" );
 if ( $Global{setSSL} )
 {
  $SSLstatus->configure( -text => "SSL", -font => $Global{Font});
-} 
+}
 else
 {
  $SSLstatus->configure( -text => "NON-SSL", -font => $Global{Font});
@@ -269,11 +269,11 @@ else
 # Create a REF status label
 #
 $FRstatus = $mwf -> Label -> pack(-side => "left", -anchor => "center" );
- 
+
 if ( $Global{fref} )
 {
  $FRstatus->configure( -text => "REF", -font => $Global{Font});
-} 
+}
 else
 {
  $FRstatus->configure( -text => "   ", -font => $Global{Font});
@@ -310,13 +310,13 @@ $Global{p1} = $Global{nb}->add('INFO',-label => 'INFO');
 &initializeP1;
 
 $splash->Destroy() if ( $Global{splash} );
- 
+
 $splash = undef();
 
 $Global{schema_timer} = $Global{mainWindow}->repeat(1000, \&update_schema);
 #
 # Run the Main loop looking for events.
-# 
+#
 
 MainLoop;
 
@@ -324,9 +324,9 @@ MainLoop;
 
 sub ops_items
 {
- 
+
 [
- 
+
 [ 'command', 'Explore ~Root DSE', -accelerator => "Ctrl-r", -command => \&rootDse ],
 "",
 [ 'command', 'Set ~SSL', -accelerator => "Ctrl-s", -command => \&setSSL ],
@@ -338,9 +338,9 @@ sub ops_items
 [ 'command', 'Toggle ~Follow Referral', -accelerator => "Ctrl-f", -command => \&toggleRef ],
 "",
 [ 'command', 'E~xit', -accelerator => "Ctrl-x", -command => sub { exit;} ],
- 
+
 ];
- 
+
 }# End of subroutine ops_items
 
 sub update_schema
@@ -350,12 +350,12 @@ if ( $Global{schemaServer} ne $Global{CORE_SERVER} )
 {
 $Global{mainWindow} -> Busy(-recurse => 1);  # window is busy
 $Global{schema_timer}->cancel;
-if ( $Global{schemaServer} ne $Global{CORE_SERVER} ) 
+if ( $Global{schemaServer} ne $Global{CORE_SERVER} )
 {
 $currentPanel = $Global{nb} -> raised();
 $Global{nb} -> raise('INFO');
 
-&schema; 
+&schema;
 
 $Global{nb} -> raise($currentPanel);
 }
@@ -363,16 +363,16 @@ $Global{schemaServer} = $Global{LDAP_SERVER};
 $Global{schema_timer} = $Global{mainWindow}->repeat(1000, \&update_schema);
 $Global{mainWindow} -> Unbusy;  # window is not busy
 }
- 
+
 } # End of subroutine update_schema
 
 sub init_schemaHash
 {
- 
+
  $schemaHash{ 'schema' } = undef();
  $schemaHash{ 'obj' }  = {};
  $schemaHash{ 'tree' } = {};
- 
+
  $schemaHash{ 'atts' } = [];
  $schemaHash{ 'ocs' }  = [];
  $schemaHash{ 'mrs' }  = [];
@@ -381,7 +381,7 @@ sub init_schemaHash
  $schemaHash{ 'dits' } = [];
  $schemaHash{ 'ditc' } = [];
  $schemaHash{ 'mru' }  = [];
- 
+
 } # End of subroutine init_schemaHash
 
 sub setSSL
@@ -400,7 +400,7 @@ sub nonSSL
 
 sub toggleVersion
 {
- 
+
 if ( $Global{setVersion} == 2 )
 {
  $Global{setVersion} = 3;
@@ -416,7 +416,7 @@ else
 
 sub toggleRef
 {
- 
+
 if ( $Global{fref} == 0 )
 {
  $Global{fref} = 1;
@@ -427,7 +427,7 @@ else
  $Global{fref} = 0;
  $FRstatus->configure( -text => "   ", -font => $Global{Font});
 }
- 
+
 } # End of subroutine toggleRef
 
 sub saveLdif
@@ -447,7 +447,7 @@ sub initializeProgram
 #
 # Check for dot file, use it to configure program.
 #
- 
+
 if ( $Global{'platform'} eq 'unix' )
 {
  $ENV{'TMP'} = "/tmp";
@@ -457,24 +457,24 @@ else
  $ENV{'TMP'} = "./";
 }
 
-@dotfile = (); 
+@dotfile = ();
 push(@dotfile,$opt_i) if $opt_i;
 
 #
 #  Active State Perl does not always set ENV HOME.
 #
- 
+
 if ( !$ENV{HOME} )
 {
  $ENV{"HOME"} = ".";
 }
 
- 
+
 if ( !$ENV{PWD} )
 {
  $ENV{PWD} = ".";
 }
- 
+
 push( @dotfile, "$ENV{HOME}/.tklkup");
 push( @dotfile, "$ENV{PWD}/.tklkup");
 
@@ -492,34 +492,34 @@ foreach (@dotfile)
 
 if ( -e $dotfile && -r $dotfile )
 {
- 
+
 open(DOT, "<$dotfile");
- 
+
 @Input = <DOT>;
- 
+
 foreach (@Input)
 {
- 
+
 my @data = ();
- 
+
 if ( /^#/ || /^\s+$/ ) { next; }
- 
+
 chomp();
 @data = split(/:/);
- 
+
 $data[1] =~ s/^\s*//;
 $data[1] =~ s/\s+$//;
 $data[2] =~ s/^\s*// if ( defined($data[2]) );
 $data[2] =~ s/\s+$// if ( defined($data[2]) );
- 
-$_ = $data[0]; 
+
+$_ = $data[0];
 
 TYPE: {
 
     /^followref/i && do {
                      $Global{fref} = 1;
                      last TYPE; };
- 
+
     /^binddn/i && do {
                      $Global{binddn} = $data[1];
                      last TYPE; };
@@ -527,16 +527,16 @@ TYPE: {
     /^hand/i && do {
                      $Global{'hand'} = $data[1];
                      last TYPE; };
- 
+
     /^port/i && do {
                      $Global{port} = $data[1];
                      $Global{nsslport} = $data[1];
                      last TYPE; };
- 
+
     /^sslport/i && do {
                      $Global{sslport} = $data[1];
                      last TYPE; };
- 
+
     /^limit/i && do {
                      if (defined($data[1]) )
                      {
@@ -547,23 +547,23 @@ TYPE: {
                       $Global{'limit'} = 100;
                      }
                      last TYPE; };
- 
+
     /^attribute/i && do {
                      push(@attribute, $data[1]);
                      last TYPE; };
- 
+
     /^server/i && do {
                      push(@server, $data[1]);
                      if ( defined($data[2]) )
                      {
                      $server{$data[1]} = $data[2];
                      }
-                     last TYPE; }; 
+                     last TYPE; };
 
     /^font/i && do {
                      $Global{'Font'} = $data[1];
                      last TYPE; };
- 
+
     /^nismapname/i && do {
                      $Global{'nismapname'} = 1;
                      last TYPE; };
@@ -575,32 +575,32 @@ TYPE: {
     /^mwwidth/i && do {
                      $Global{'mwwidth'} = $data[1];
                      last TYPE; };
- 
+
     /^mwheight/i && do {
                      $Global{'mwheight'} = $data[1];
                      last TYPE; };
- 
+
                      my $error =  "Parsing configuration file found an undefined type:  $_";
                      ERROR(\$error);
- 
+
     } # End of case TYPE
- 
+
 }
- 
+
 close(DOT);
- 
-}                                                                                
+
+}
 #
 # Default is for left hand people!
 # Over ride the dot file if the -r command line
 # option is used.
 #
- 
+
 if ( defined($opt_r) ) {
- 
+
 $Global{'hand'}   = $opt_r ? 'right' : 'left';
 # my $Global{'hand'}   = $opt_r ? 'left' : 'right'; # uncomment this for right hand def.
- 
+
 }
 
 #
@@ -633,16 +633,16 @@ $Global{'CORE_SERVER'} = $Global{'LDAP_SERVER'};
 # Default directory search base.
 #
 $error = &dirConn();  # connect and bind to the directory.
- 
+
 if ( !$error )
 {
 #
 # Find the branches of the directory.
 #
- 
+
 if ( !$error || $Global{setVersion} )
 {
- 
+
  if ( defined($server{$server[0]}) )
  {
  # user defined base
@@ -658,7 +658,7 @@ if ( !$error || $Global{setVersion} )
  my $entry;
  my $mesg;
  # use root_dse to find the bases
- 
+
  @base = ();
  $entry = $Global{ldap}->root_dse();
  if ( defined($entry) )
@@ -680,7 +680,7 @@ if ( !$error || $Global{setVersion} )
     }
    }
  }
- 
+
  }
  }
 
@@ -697,10 +697,10 @@ else
   {
    ERROR($error);
   }
- 
+
 }
 
- @NcKeys = sort(keys(%Tree)); 
+ @NcKeys = sort(keys(%Tree));
  if ( @NcKeys )
  {
  $LDAP_SEARCH_BASE = $NcKeys[0];
@@ -722,16 +722,16 @@ sub initializeP1
 {
 $dsaframe = $Global{p1}->Frame()
       ->pack( -fill => "both", -side => "top" );
- 
+
 #
 # Set up the select directory server radio buttons.
 #
- 
+
 foreach (@server)
 {
    $smenu->radiobutton( -label => $_, -variable => \$Global{'LDAP_SERVER'},
          -value => $_, -command => \&server, -font => $Global{'Font'} );
- 
+
 }
 
 $dsads = $dsaframe ->LabFrame( -labelside => "acrosstop",
@@ -754,20 +754,20 @@ $Global{dsaptls}->insert("end", $Global{port});
 
 $attframe = $Global{p1}->Frame()
       ->pack( -fill => "both", -side => "bottom");
- 
+
 $msgframe = $attframe->LabFrame(-label => "Process Messages",
       -labelside => "acrosstop" )
       ->pack( -fill => "both", -side => "top", -padx => 1, -pady => 1 );
- 
- 
+
+
 $splashList->insert("0", "Creating root dse and attribute buttons.")
         if ( $Global{splash} );
 $splash->update()
         if ( $Global{splash} );
- 
+
 $msgbox = $msgframe ->Scrolled('Listbox', -scrollbars => 's',
         -width => 50, -height => 10 );
- 
+
 $msgbox->pack( -side => "left" );
 
 #
@@ -792,7 +792,7 @@ $hlframe = $tpframe ->Frame(-borderwidth => 2,-relief => "raised") ->pack( -side
 #
 # Create search base list box.
 #
- 
+
 $sbbframe = $hlframe->LabFrame(-label => "DIRECTORY SEARCH BASE",
       -labelside => "acrosstop")
       ->pack( -side => "top", -anchor => "e");
@@ -801,7 +801,7 @@ $sbbframe = $hlframe->LabFrame(-label => "DIRECTORY SEARCH BASE",
 # Create the Attributes and Save to frame
 #
 
-$ltframe = $tpframe ->Frame() 
+$ltframe = $tpframe ->Frame()
           ->pack( -side => "left", -fill => "both");
 
 #
@@ -810,7 +810,7 @@ $ltframe = $tpframe ->Frame()
 
 $aframe = $ltframe ->LabFrame(-label => "FILTER\nATTRIBUTES",
           -labelside => "acrosstop",
-          -relief => "raised") 
+          -relief => "raised")
           ->pack( -side => "top", -fill => "both");
 
 #
@@ -819,14 +819,14 @@ $aframe = $ltframe ->LabFrame(-label => "FILTER\nATTRIBUTES",
 
 $fmtframe = $ltframe ->LabFrame( -label => "SAVE FORMAT",
           -labelside => "acrosstop",
-          -relief => "raised") 
+          -relief => "raised")
           ->pack( -side => "top", -fill => "both");
 
 #
 # Create a ldif Checkbutton that will set up  a ldif variable
-# 
 #
- 
+#
+
 $Global{saveLdifck} = $fmtframe -> Checkbutton(
                        -text => "LDIF", -command => \&saveLdif,
                        -variable =>  \$Global{ldif}, -onvalue => 1,
@@ -837,9 +837,9 @@ $Global{saveLdifck}->select();
 
 #
 # Create a ldif Checkbutton that will set up  a ldif variable
-# 
 #
- 
+#
+
 $Global{saveXmlck} = $fmtframe -> Checkbutton(
                        -text => "XML", -command => \&saveXml,
                        -variable =>  \$Global{xml}, -onvalue => 1,
@@ -849,7 +849,7 @@ $Global{saveXmlck} = $fmtframe -> Checkbutton(
 $Global{saveXmlck} -> deselect;
 
 $btframe = $tpframe ->Frame(-borderwidth => 2,
-           -relief => "raised") 
+           -relief => "raised")
            ->pack( -side => "left", -fill => "both");
 
 #
@@ -858,9 +858,9 @@ $btframe = $tpframe ->Frame(-borderwidth => 2,
 
 $sbblist = $sbbframe ->Listbox( -width => 40, -font => $Global{'Font'},
                                 -height => 1  );
- 
+
 $sbblist->pack(-side => $Global{hand});
- 
+
 $sbblist->insert("end", $LDAP_SEARCH_BASE);
 $Global{dsasbls}->insert(0, $LDAP_SEARCH_BASE)
    if ( $Global{dsasbls} );
@@ -870,7 +870,7 @@ $Global{dsasbls}->insert(0, $LDAP_SEARCH_BASE)
 # This is the point from which the search operation
 # will start from.
 #
- 
+
 $sbmenu = $sbbframe->Button( -text => " SELECT\nBASE",
                  -command => \&sbHlist, -font => $Global{'Font'},
                  -borderwidth => 3 )
@@ -883,10 +883,10 @@ $sbmenu = $sbbframe->Button( -text => " SELECT\nBASE",
 # tree will be displayed.
 #
 
-$Global{'searchHList'} = $hlframe ->Scrolled('HList', 
+$Global{'searchHList'} = $hlframe ->Scrolled('HList',
             -font       => $Global{'Font'},
             -scrollbars => 'se',
-            -width      => 50, 
+            -width      => 50,
             -height     => 13,
             -itemtype   => 'text',
             -separator  => $sepChar,
@@ -901,7 +901,7 @@ $Global{'searchHList'} = $hlframe ->Scrolled('HList',
 
    );  # End of Scrolled HList.
 
-#$Global{'searchHList'}->add($LDAP_SEARCH_BASE, -text=>$LDAP_SEARCH_BASE);  
+#$Global{'searchHList'}->add($LDAP_SEARCH_BASE, -text=>$LDAP_SEARCH_BASE);
 
 $Global{'searchHList'}->pack(-side => "right");
 
@@ -910,12 +910,12 @@ $Global{'searchHList'}->pack(-side => "right");
 # This is where the user will select any special attribute to
 # search on.
 #
- 
+
 $amenu = $aframe -> Menubutton(-text => " SELECT\n ADDITIONAL\n ATTRIBUTES",
                  -relief => "raised", -font => $Global{'Font'},
                  -borderwidth => 3 )
                  -> pack( -side => "top", -anchor => "w" );
- 
+
 #
 # First set up the 4 main attribute Radio buttons.
 #
@@ -930,14 +930,14 @@ my $sptr = 0;
 while ( $sptr <= 3 )
 {
 $_ = shift(@attribute);
- 
+
 $rbsn   = $aframe -> Radiobutton(-text =>   "$_", -variable => \$Global{'info'},         -value => "$_", -font => $Global{'Font'} )
          -> pack( -side => "top", -anchor => 'w');
- 
-if ( !$sptr ) { $rbsn->select(); } # select first attribute                      
+
+if ( !$sptr ) { $rbsn->select(); } # select first attribute
 ++$sptr;
 }
- 
+
 } # End of if ( $#attribute > 4 )
 else
 {
@@ -949,92 +949,92 @@ my $sptr = 0;
 while ( @attribute )
 {
 $_ = shift(@attribute);
- 
+
 $rbsn   = $aframe -> Radiobutton(-text =>   "$_",
                   -variable => \$Global{'info'},
                   -value => "$_", -font => $Global{'Font'} )
                   -> pack( -side => "top", -anchor => "w");
- 
+
 if ( !$sptr ) { $rbsn->select(); } # select first attribute
- 
+
 ++$sptr;
 }
- 
+
 }
- 
+
 #
 # Create radio buttons in attributes selection box.
 #
 #
- 
+
 foreach (@attribute)
 {
    $amenu->radiobutton( -label => $_, -variable => \$Global{'info'},
           -value => $_, -font => $Global{'Font'});
 } # End of foreach (@attribute)
- 
+
 #
 # Create ldap display button
 #
-$Global{actionDisplay} = $btframe->Button( -text => "DISPLAY", 
-           -command => \&ldapActionDisplay, 
+$Global{actionDisplay} = $btframe->Button( -text => "DISPLAY",
+           -command => \&ldapActionDisplay,
            -font => $Global{'Font'}, -borderwidth => 3 )
-           -> pack(-side => "top", -anchor => "w", -padx => 1, -pady => 1 ) 
+           -> pack(-side => "top", -anchor => "w", -padx => 1, -pady => 1 )
            if ( !Exists($Global{actionDisplay}));
- 
+
 #
 # Create save to ldif button
 #
-$Global{actionLdif} = $btframe->Button(-text => "SAVE TO", 
+$Global{actionLdif} = $btframe->Button(-text => "SAVE TO",
            -command => \&ldapActionSaveToLdif,
            -font => $Global{'Font'}, -borderwidth => 3)
-           -> pack(-side => "top", -anchor => "w", -padx => 1 ) 
+           -> pack(-side => "top", -anchor => "w", -padx => 1 )
            if ( !Exists($Global{actionLdif}));
- 
+
 #
 # Create ldap rename button
 #
-$Global{actionRename} = $btframe->Button( -text => "RENAME ", 
-           -command => \&getRenameData, 
+$Global{actionRename} = $btframe->Button( -text => "RENAME ",
+           -command => \&getRenameData,
            -font => $Global{'Font'}, -borderwidth => 3 )
-           -> pack(-side => "top", -anchor => "w", -padx => 1, -pady => 1 ) 
+           -> pack(-side => "top", -anchor => "w", -padx => 1, -pady => 1 )
            if ( !Exists($Global{actionRename}));
- 
+
 #
 # Create ldap edit button
 #
-$Global{actionEdit} = $btframe->Button(-text => " EDIT  ", 
+$Global{actionEdit} = $btframe->Button(-text => " EDIT  ",
            -command => \&ldapActionEdit,
            -font => $Global{'Font'}, -borderwidth => 3)
-           -> pack(-side => "top", -anchor => "w", -padx => 1 ) 
+           -> pack(-side => "top", -anchor => "w", -padx => 1 )
            if ( !Exists($Global{actionEdit}));
- 
+
 #
 # Create ldap delete button
 #
-$Global{actionDelete} = $btframe->Button(-text => "DELETE ", 
+$Global{actionDelete} = $btframe->Button(-text => "DELETE ",
            -command => \&questionAction,
            -font => $Global{'Font'}, -borderwidth => 3,
            -activeforeground => 'red')
-           -> pack(-side => "top", -anchor => "w", -padx => 1, -pady => 1 ) 
+           -> pack(-side => "top", -anchor => "w", -padx => 1, -pady => 1 )
            if ( !Exists($Global{actionDelete}));
- 
+
 #
 # Create process cancel button
 #
-$Global{actionCancel} = $btframe->Button(-text => "CANCEL ", 
+$Global{actionCancel} = $btframe->Button(-text => "CANCEL ",
            -command => \&ldapActionCancel,
            -font => $Global{'Font'}, -borderwidth => 3)
-           -> pack(-side => "top", -anchor => "w", -padx => 1 ) 
+           -> pack(-side => "top", -anchor => "w", -padx => 1 )
            if ( !Exists($Global{actionCancel}));
 
 #
 # Create save all to ldif button
 #
-$Global{actionLdifAll} = $btframe->Button( -text => "SAVE ALL\nTO", 
-           -command => \&ldapActionMultiSaveToLdif, 
+$Global{actionLdifAll} = $btframe->Button( -text => "SAVE ALL\nTO",
+           -command => \&ldapActionMultiSaveToLdif,
            -font => $Global{'Font'}, -borderwidth => 3 )
-           -> pack(-side => "left", -anchor => "w", -padx => 1 ) 
+           -> pack(-side => "left", -anchor => "w", -padx => 1 )
            if ( !Exists($Global{actionLdifAll}));
 
 $bmlframe = $bmframe ->LabFrame(-label => "File Name",
@@ -1044,73 +1044,73 @@ $bmlframe = $bmframe ->LabFrame(-label => "File Name",
 # Create Text Entry list box.
 #
 
-$bmlframe->Entry(-textvariable => \$Global{'ldifFile'}, 
-           -width => 40 ) 
+$bmlframe->Entry(-textvariable => \$Global{'ldifFile'},
+           -width => 40 )
            -> pack(-side => "left", -anchor => "w", -fill => 'x');
 $splashList->insert("0", "Creating cascading search base menus.")
         if ( $Global{splash} );
 $splash->update()
         if ( $Global{splash} );
- 
+
 #
 # Create Bottom Attribute frame.
 # This is where the user will enter data to be
 # searched for.
 #
- 
+
 $tframe = $bmframe->LabFrame(-label => "FILTER DATA",
       -labelside => "acrosstop")
       ->pack( -fill => "both", -side => "bottom" , -anchor => "w");
- 
+
 #
 # Create Text Entry list box.
 #
- 
+
 $tframe_text = $tframe->Entry(-textvariable => \$Global{'adata'}, -width => 27 )
       -> pack(-side => "left",-anchor => "w", );
 
 $tframe_text->bind('<Key-Return>' => \&search );
- 
+
 #
 # Create Clear Attribute Data and Search Directory buttons
 #
 $tframe -> Button(-text => "CLEAR FILTER DATA", -command =>  \&AClear,
         -font => $Global{'Font'}, -borderwidth => 5 )
         -> pack( -side => "left", -anchor => "w", -pady => 2, -padx => 2 );
- 
+
 #
 # Create get Filter selection menu button.
 #
- 
+
 $sfcmenu = $tframe -> Menubutton(-text => "SET FILTER\nCONDITON",
                  -relief => "raised", -font => $Global{'Font'},
                  -borderwidth => 5 )
-                 -> pack(-side => "left", -anchor => "w", 
+                 -> pack(-side => "left", -anchor => "w",
                  -pady => 2, -padx => 2 );
- 
+
 $flclist = $tframe ->Listbox( -width => 11, -height => 1  );
- 
+
 $flclist->pack(-side => 'top', -anchor => "w" );
- 
+
 $flclist->insert(0, $Global{'infoFilter'});
 
 #
 # Set up the filter type radio buttons.
 #
- 
+
 $rbsf   = $sfcmenu -> radiobutton(-label =>   "equal",
                   -variable => \$Global{'infoFilter'},
                   -value => "equal", -command => \&setFilter );
- 
+
 $rbsf   = $sfcmenu -> radiobutton(-label =>   "begins with",
                   -variable => \$Global{'infoFilter'},
                   -value => "begins with", -command => \&setFilter );
- 
- 
+
+
 $rbsf   = $sfcmenu -> radiobutton(-label =>   "ends with",
                   -variable => \$Global{'infoFilter'},
                   -value => "ends with", -command => \&setFilter );
- 
+
                                                                                 $rbsf   = $sfcmenu -> radiobutton(-label =>   "contains",
                   -variable => \$Global{'infoFilter'},
                   -value => "contains", -command => \&setFilter );
@@ -1118,13 +1118,13 @@ $rbsf   = $sfcmenu -> radiobutton(-label =>   "ends with",
 #
 # Create Search Directory button
 #
- 
+
 $bmframe -> Button(-text => "SEARCH THE DIRECTORY",
         -command =>  \&search,
         -font => $Global{'Font'}, -borderwidth => 5 )
         -> pack( -side => "bottom", -fill => "both");
- 
-#$Global{'searchHList'}->delete('all');  
+
+#$Global{'searchHList'}->delete('all');
 $Global{actionDelete}->configure( -state => 'disable');
 $Global{actionDisplay}->configure( -state => 'disable');
 $Global{actionEdit}->configure( -state => 'disable');
@@ -1161,9 +1161,9 @@ $cframe = $Global{p3}->Frame()
 # Create Clear Data
 #
 
-$cframe -> Button(-text => "     CLEAR DATA     ", 
+$cframe -> Button(-text => "     CLEAR DATA     ",
      -command =>  \&display_clear, -font => $Global{'Font'},
-     -borderwidth => 3 ) 
+     -borderwidth => 3 )
      ->pack( -fill => 'both' );
 
 #
@@ -1181,19 +1181,19 @@ $lframe = $Global{p3}->LabFrame(-label => "DIRECTORY DATA",
 #
 
 $rbclear = $lframe -> Checkbutton(-text => "CLEAR DIRECTORY DATA ON EACH QUERY",
-      -variable =>  \$display_clear, -onvalue => 1, -offvalue => 0, 
+      -variable =>  \$display_clear, -onvalue => 1, -offvalue => 0,
       -font => $Global{'Font'} )
       -> pack(-anchor => 'sw' );
 
 $rbclear->select();
 
 #
-# Create a ROText Box that will actually contain the 
+# Create a ROText Box that will actually contain the
 # returned directory data.
 #
 
 $list = $lframe ->Scrolled('ROText', -scrollbars => 'se',
-        -width => 80, -height => 20, -wrap => 'none', 
+        -width => 80, -height => 20, -wrap => 'none',
         -font => $Global{'Font'}  );
 
 $list->pack(-fill => "both", -expand => 1 );
@@ -1231,16 +1231,16 @@ my $sbframe;
 # Create bottom Search Directory frame
 #
 
-$sbframe = $Global{'p4'}->Frame( -borderwidth => 2, 
+$sbframe = $Global{'p4'}->Frame( -borderwidth => 2,
                         -relief => "raised")->pack(
-                        -fill => "both", -side => "bottom", 
+                        -fill => "both", -side => "bottom",
                         -padx => 2);
 
 #
 # Create Search Directory button
 #
 
-$sbframe -> Button(-text => "RETRIEVE DIRECTORY SCHEMA", 
+$sbframe -> Button(-text => "RETRIEVE DIRECTORY SCHEMA",
          -command =>  \&schema, -font => $Global{'Font'}, -borderwidth => 3 )
          -> pack( -fill => "both");
 
@@ -1248,13 +1248,13 @@ $srbfilelabel = $Global{'p4'}->LabFrame(-label => "SCHEMA DUMP TO FILE",
       -labelside => "acrosstop")
       ->pack( -fill => "both", -anchor => "w", -padx => 2);
 
-$srbfile = $srbfilelabel -> Checkbutton( 
+$srbfile = $srbfilelabel -> Checkbutton(
           -text => "Write schema data to file, enter file name in text box below this line.   ",
           -variable =>  \$Global{'sfile'}, -onvalue => 1, -offvalue => 0,
           -font => $Global{'Font'} )
           -> pack(-anchor => "w" );
 
-$srbfilelabel -> Checkbutton( 
+$srbfilelabel -> Checkbutton(
           -text => "Write schema data to file in DSML XML format.",
           -variable =>  \$Global{'xml'}, -onvalue => 1, -offvalue => 0,
           -font => $Global{'Font'} )
@@ -1264,7 +1264,7 @@ $srbfilelabel -> Checkbutton(
 # Create Text Entry list box.
 #
 
-$srbfilelabel->Entry(-textvariable => \$Global{'fdata'}, -width => 25 ) 
+$srbfilelabel->Entry(-textvariable => \$Global{'fdata'}, -width => 25 )
       -> pack(-fill => 'x');
 
 #
@@ -1283,58 +1283,58 @@ $slframe = $Global{'p4'}->LabFrame(-label => "DIRECTORY SCHEMA DATA",
 
 $selframe = $slframe -> LabFrame(-label => "DISPLAY SELECTED OBJECTS",
                                  -labelside => "acrosstop" )
-                                 ->pack( -side => $Global{'hand'}, 
+                                 ->pack( -side => $Global{'hand'},
                                  -expand => 1, -fill => "both" );
 
-$sellframe = $selframe->Frame( -borderwidth => 0, 
+$sellframe = $selframe->Frame( -borderwidth => 0,
                         -relief => "raised")->pack(
-                        -fill => "both", -side => "top", 
+                        -fill => "both", -side => "top",
                         -padx => 0, -pady => 0);
 
 $sellAll = $sellframe -> Checkbutton(-text => "ALL",
-      -variable =>  \$selectAll, -onvalue => 1, -offvalue => 0, 
+      -variable =>  \$selectAll, -onvalue => 1, -offvalue => 0,
       -font => $Global{'Font'} )
       -> pack(-side => "top", -anchor => 'w' );
 
 $sellAll->select();
 
 $sellObj = $sellframe -> Checkbutton(-text => "objectClasses",
-      -variable =>  \$selectObj, -onvalue => 1, -offvalue => 0, 
+      -variable =>  \$selectObj, -onvalue => 1, -offvalue => 0,
       -font => $Global{'Font'} )
       -> pack(-side => "top", -anchor => 'w' );
 
 $sellMatch = $sellframe -> Checkbutton(-text => "matchingRules",
-      -variable =>  \$selectMatch, -onvalue => 1, -offvalue => 0, 
+      -variable =>  \$selectMatch, -onvalue => 1, -offvalue => 0,
       -font => $Global{'Font'} )
       -> pack(-side => "top", -anchor => 'w' );
 
 $sellAtt = $sellframe -> Checkbutton(-text => "attributeType",
-      -variable =>  \$selectAtt, -onvalue => 1, -offvalue => 0, 
+      -variable =>  \$selectAtt, -onvalue => 1, -offvalue => 0,
       -font => $Global{'Font'} )
       -> pack(-side => "top", -anchor => 'w' );
 
 $sellsyn = $sellframe -> Checkbutton(-text => "ldapsyntaxes",
-      -variable =>  \$selectSyn, -onvalue => 1, -offvalue => 0, 
+      -variable =>  \$selectSyn, -onvalue => 1, -offvalue => 0,
       -font => $Global{'Font'} )
       -> pack(-side => "top", -anchor => 'w' );
 
 $sellnf = $sellframe -> Checkbutton(-text => "nameforms",
-      -variable =>  \$selectNf, -onvalue => 1, -offvalue => 0, 
+      -variable =>  \$selectNf, -onvalue => 1, -offvalue => 0,
       -font => $Global{'Font'} )
       -> pack(-side => "top", -anchor => 'w' );
 
 $selldsr = $sellframe -> Checkbutton(-text => "ditstructurerules",
-      -variable =>  \$selectDsr, -onvalue => 1, -offvalue => 0, 
+      -variable =>  \$selectDsr, -onvalue => 1, -offvalue => 0,
       -font => $Global{'Font'} )
       -> pack(-side => "top", -anchor => 'w' );
 
 $selldcr = $sellframe -> Checkbutton(-text => "ditcontentrules",
-      -variable =>  \$selectDcr, -onvalue => 1, -offvalue => 0, 
+      -variable =>  \$selectDcr, -onvalue => 1, -offvalue => 0,
       -font => $Global{'Font'} )
       -> pack(-side => "top", -anchor => 'w' );
 
 $sellmru = $sellframe -> Checkbutton(-text => "matchingruleuse",
-      -variable =>  \$selectMru, -onvalue => 1, -offvalue => 0, 
+      -variable =>  \$selectMru, -onvalue => 1, -offvalue => 0,
       -font => $Global{'Font'} )
       -> pack(-side => "top", -anchor => 'w' );
 
@@ -1349,15 +1349,15 @@ $sellmru = $sellframe -> Checkbutton(-text => "matchingruleuse",
 
 $slframe ->Button(-text => "     CLEAR DATA     ",
      -command =>  \&schema_clear, -font => $Global{'Font'},
-     -borderwidth => 3 ) 
+     -borderwidth => 3 )
      -> pack(-side => "bottom", -fill => "both",  -padx => 5 );
 #
-# Create a ROText Box that will actually contain the 
+# Create a ROText Box that will actually contain the
 # returned directory data.
 #
 
 $schema_list = $slframe ->Scrolled('ROText', -scrollbars => 'se',
-        -width => 50, -height => 20, -wrap => 'none', 
+        -width => 50, -height => 20, -wrap => 'none',
         -font => $Global{'Font'}  );
 
 $schema_list->pack( -side => "bottom" );
@@ -1376,32 +1376,32 @@ $Global{'mainWindow'}->update;
 
 sub initializeP5
 {
- 
-$ldifframe = $Global{p5} ->LabFrame(-label => "LDIF FILE NAME") 
+
+$ldifframe = $Global{p5} ->LabFrame(-label => "LDIF FILE NAME")
            ->pack(-side => "top", -fill => "x");
 
 #
 # Create Text Entry list box.
 #
 
-$ldifframe->Entry(-textvariable => \$Global{'createLdifFile'}, 
-           -width => 25 ) 
+$ldifframe->Entry(-textvariable => \$Global{'createLdifFile'},
+           -width => 25 )
            -> pack(-fill => 'x');
 
 #
 # Create Create Ldif Entry button
 #
-$Global{createLdifEntry} = $ldifframe->Button( 
-           -text => "CREATE/MODIFY ENTRY FROM LDIF FILE", 
-           -command => \&ldapActionCreateLdifEntry, 
+$Global{createLdifEntry} = $ldifframe->Button(
+           -text => "CREATE/MODIFY ENTRY FROM LDIF FILE",
+           -command => \&ldapActionCreateLdifEntry,
            -font => $Global{'Font'}, -borderwidth => 3 )
-           -> pack(-side => "top", -anchor => "w", -padx => 5, -pady => 5 ) 
+           -> pack(-side => "top", -anchor => "w", -padx => 5, -pady => 5 )
            if ( !Exists($Global{createLdifEntry}));
 
-$eframe = $Global{p5} ->Frame(-borderwidth => 2,-relief => "raised") 
+$eframe = $Global{p5} ->Frame(-borderwidth => 2,-relief => "raised")
            ->pack(-side => "top", -anchor => 'e');
 
-$cteframe = $eframe ->LabFrame(-label => "MANUALLY CREATE ENTRY") 
+$cteframe = $eframe ->LabFrame(-label => "MANUALLY CREATE ENTRY")
            ->pack(-side => "top", -anchor => 'e');
 
 #
@@ -1420,9 +1420,9 @@ $dnmenu = $cteframe->Button( -text => " SELECT\nDN BASE",
 
 $dnblist = $cteframe ->Listbox( -width => 40, -font => $Global{'Font'},
                                 -height => 1  );
- 
+
 $dnblist->pack(-side => "right", -anchor => 'e',  -padx => 5, -pady => 5 );
- 
+
 $dnblist->insert("end", $DN_BASE);
 
 #
@@ -1458,10 +1458,10 @@ my $optr = 0;
 # tree will be displayed.
 #
 
-$Global{'olist'} = $eframe->Scrolled('HList', 
+$Global{'olist'} = $eframe->Scrolled('HList',
             -font       => $Global{'Font'},
             -scrollbars => 'se',
-            -width      => $Global{'max'}, 
+            -width      => $Global{'max'},
             -height     => 20,
             -itemtype   => 'text',
             -separator  => $sepChar,
@@ -1487,7 +1487,7 @@ $Global{'olist'} = $eframe->Scrolled('HList',
             my $var = $$objectclasses[-1];
 
 #            foreach my $var (@var)
-#            { 
+#            {
 
                if ( !(exists($Global{ceObject}->{$var})) )
                {
@@ -1504,14 +1504,14 @@ $Global{'olist'} = $eframe->Scrolled('HList',
                $Global{ceObject}->{$var}->[1] = $objects;
 
                $colist->windowCreate("end", -window => $ab );
- 
+
                $ab->configure( -command => [ \&deleteObjectclass, \$ab, $var ] );
- 
+
                # position to the next row.
                $colist->insert("end", "\n");
                }
 #            }
-             
+
             } # End of subroutine browsecmd
 
             ) -> pack( -side => "top", -anchor => 'e')
@@ -1521,10 +1521,10 @@ $Global{'olist'} = $eframe->Scrolled('HList',
 # Create a ROText Box that will contain the selected objectclass(s)
 # for the new entry.
 #
- 
+
 $Global{'colist'} = $eframe ->Scrolled('Text', -scrollbars => 'se',
         -width => $Global{'max'}, -height => 20, -wrap => 'none',
-        -font => $Global{'Font'}  ) 
+        -font => $Global{'Font'}  )
         ->pack( -side => "top", -anchor => 'e' )
         if ( !Tk::Exists($Global{'colist'}) ) ;  # End of Scrolled HList.
 
@@ -1533,7 +1533,7 @@ $Global{'colist'} = $eframe ->Scrolled('Text', -scrollbars => 'se',
 # tree will be displayed.
 #
 #
-#$Global{'colist'} = $eframe ->Listbox( -width => $Global{'max'}, 
+#$Global{'colist'} = $eframe ->Listbox( -width => $Global{'max'},
 #                    -height => 20  )
 #                    -> pack( -side => "top", -anchor => 'e')
 #            if ( !Tk::Exists($Global{'colist'}) ) ;  # End of Scrolled HList.
@@ -1543,20 +1543,20 @@ my $base;
 $base = "";
 
 #
-# Create Hierarchial list box data tree, 
+# Create Hierarchial list box data tree,
 # and display data.
 #
 
 eval{
- foreach ( @tmpKeys ) 
+ foreach ( @tmpKeys )
  {
-    if ( $$tree{$_} ->[0] == 0 ) 
+    if ( $$tree{$_} ->[0] == 0 )
     {
       $$tree{$_} ->[0] = 1;
       $Global{'olist'}->add($_, -text=>$_);  # do the base.
     }
 
-    $base = $_; 
+    $base = $_;
     $array = $$tree{$_};
     $ptr = 0;
     foreach my $var ( @$array )
@@ -1566,12 +1566,12 @@ eval{
         $ptr = 1;
         next;
       }
-      $_ = $base . $sepChar . $var; 
+      $_ = $base . $sepChar . $var;
       $Global{'olist'}->add($_, -text => $var);
       if ( defined($$tree{$_}) )
       {
         $$tree{$_}->[0] = 1;
-      } 
+      }
     }
 
  }
@@ -1585,12 +1585,12 @@ print "$@" if ( defined($@));
 # Reset objectClass array.
 #
 
-foreach ( @tmpKeys ) 
+foreach ( @tmpKeys )
 {
  if ( defined($$tree{$_}) )
  {
   $$tree{$_}->[0] = 0;
- } 
+ }
 }
 
 } # End of subroutine initializeP5a
@@ -1604,7 +1604,7 @@ sub histSearch_clear {
 $Global{'searchList'}->delete("1.0", "end");
 
 } # End of clear subroutine
- 
+
 sub histSearch_cancel{
 
 $Global{'searchList'}->destroy if Tk::Exists($Global{'searchList'});
@@ -1620,7 +1620,7 @@ $ab = $Global{ceObject}->{$var}->[0];
 $ab->destroy;
 delete($Global{ceObject}->{$var});
 #
-# if no objects, clear the ROTEXT box. 
+# if no objects, clear the ROTEXT box.
 #
 $Global{colist}->delete("1.0","end")
        if ( !(keys(%{$Global{ceObject}})) );
@@ -1633,18 +1633,18 @@ $Global{colist}->delete("1.0","end")
 sub createSearchBaseWindow
 {
 &globalPos();
- 
+
 my $x = $Global{'horz'} + 150;
 my $y = $Global{'vert'} + 150;
- 
+
 #
 # Create Main Bind Window
 #
- 
+
 $Global{'sbWindow'} = MainWindow->new;
- 
+
 $Global{'sbWindow'}->title("Select Search Base");
- 
+
 $Global{'sbWindow'}->geometry("+$x+$y");
 #
 # Create process accept button
@@ -1652,7 +1652,7 @@ $Global{'sbWindow'}->geometry("+$x+$y");
 $Global{'sbWindow'}->Button( -text => "ACCEPT SELECTED DN", -command => \&sbaccept,
            -font => $Global{'Font'}, -borderwidth => 3 )
            -> pack(-side => "bottom", -padx => 5, -pady => 5 ) ;
- 
+
 #
 # Create process cancel button
 #
@@ -1660,7 +1660,7 @@ $Global{'sbWindow'}->Button(-text => "CANCEL BASE CHANGE",
            -command => \&sbcancel,
            -font => $Global{'Font'}, -borderwidth => 3)
            -> pack(-side => "top", -padx => 5, -pady => 5 ) ;
- 
+
 my $sbdnframe = $Global{'sbWindow'}->Frame()
       ->pack( -fill => "both", -side => "top", -padx => 5, -pady => 5 );
 
@@ -1682,7 +1682,7 @@ sub sbcancel
 {
  $Global{'sbWindow'}->withdraw if Tk::Exists($Global{'sbWindow'});
 } # End of cancel subroutine
- 
+
 sub sbaccept
 {
  if ( exists($Global{SelectedDN}) )
@@ -1738,7 +1738,7 @@ foreach $nvar (@keys)
   $onvar = $nvar;
   $t1v = $Tree{$nvar};
 #  print "t1 : " ,Dumper($t1v), "\n";
- 
+
   $Global{sbtree}->add($nvar, -text => $nvar);
   foreach $bvar (@$t1v)
   {
@@ -1781,13 +1781,13 @@ foreach $nvar (@keys)
   $path .= $text;
 #  print "path == $path\n";
 #  print "text == $text\n";
- 
+
   $path = $text if ( !length($path)) ;
   $BASEDN{$path} = $adn;
- 
+
   $Global{sbtree}->add($path, -text => $text);
   }
- 
+
   $Global{sbtree}->setmode($onvar,'close');
   $Global{sbtree}->close($onvar);
 }
@@ -1803,7 +1803,7 @@ sub destroyTree
 
 #
 # Get the attributes of the selected objectClasses
-# 
+#
 
 sub getObjectAttributes
 {
@@ -1818,9 +1818,9 @@ sub getObjectAttributes
 
  foreach my $hvar ( @hashKeys)
  {
- 
+
   @tmp = split(/$sepChar/,$Global{ceObject}->{$hvar}->[1]);
-  
+
   foreach my $nvar (@tmp)
   {
     if ( !(grep(/$nvar/,@objectclasses)) )
@@ -1832,7 +1832,7 @@ sub getObjectAttributes
 
  }
 
- return if (!@objectclasses); # can not create an entry with no objectclass. 
+ return if (!@objectclasses); # can not create an entry with no objectclass.
 
 #
 # If this is a posixAccount or shadowAccount, automatically put
@@ -1840,16 +1840,16 @@ sub getObjectAttributes
 # the new entry.
 #
 
- push(@objectclasses, "posixAccount") 
-     if ( grep(/shadowAccount/,@objectclasses) && 
+ push(@objectclasses, "posixAccount")
+     if ( grep(/shadowAccount/,@objectclasses) &&
           !( grep(/posixAccount/,@objectclasses) ) );
 
- push(@objectclasses, "shadowAccount") 
+ push(@objectclasses, "shadowAccount")
      if ( grep(/posixAccount/,@objectclasses) &&
           !( grep(/shadowAccount/,@objectclasses) ) );
 
- push(@objectclasses, "account") 
-     if ( grep(/shadowAccount/,@objectclasses) && 
+ push(@objectclasses, "account")
+     if ( grep(/shadowAccount/,@objectclasses) &&
           grep(/posixAccount/,@objectclasses)  &&
           !( grep(/account/,@objectclasses) ) );
 
@@ -1861,7 +1861,7 @@ sub getObjectAttributes
  $Global{entryData}->{must} = [];
 
  foreach my $var (@objectclasses)
- { 
+ {
     $Global{mainWindow}->update;
     $oid = $$obj{$var}->[0];
     #
@@ -1890,7 +1890,7 @@ sub getObjectAttributes
      }
      else
      {
-       push(@{$Global{entryData}->{must}}, $alArray ) 
+       push(@{$Global{entryData}->{must}}, $alArray )
            if ( !(grep(/$alArray/,@{$Global{entryData}})) );
      }
      }
@@ -1911,7 +1911,7 @@ sub getObjectAttributes
      }
      else
      {
-       push(@{$Global{entryData}->{may}}, $alArray )  
+       push(@{$Global{entryData}->{may}}, $alArray )
            if ( !(grep(/$alArray/,@{$Global{entryData}})) );
      }
      }
@@ -1926,7 +1926,7 @@ sub getObjectAttributes
 # Search the directory for data
 #
 
-sub search 
+sub search
 {
 my $mesg;
 my $error;
@@ -1939,7 +1939,7 @@ $Global{mainWindow} -> Busy(-recurse => 1);  # window is busy
 # Destroy the dn history list if it exists.
 #
 $Global{'searchHList'}->delete('all') if Tk::Exists($Global{'searchHList'});
- 
+
 #
 # Parameter(s) to return
 #
@@ -1949,7 +1949,7 @@ if ( $Global{'setVersion'} == 3 )
 #
 # Default to return everything.
 #
-$Global{att_wanted} = [ "*", 
+$Global{att_wanted} = [ "*",
                 "aci",
                 "createTimeStamp",
                 "modifyTimeStamp",
@@ -1960,7 +1960,7 @@ else
 {
 #
 #
-# If you have only version 2 ldap servers you will need to 
+# If you have only version 2 ldap servers you will need to
 # to add the attributes that you want data returned for to
 # this list.
 #
@@ -1975,7 +1975,7 @@ $Global{att_wanted} = [ "cn" ,
 
 #
 # Set Filter options.
-# 
+#
 if (  $Global{'info'} eq "Filter" )
 {
 $match = $Global{'adata'};
@@ -2024,7 +2024,7 @@ $error = dirConn();
 
 if ( $error == 1 )
 {
-  if ( defined($Global{dirConnError}) ) 
+  if ( defined($Global{dirConnError}) )
   {
   $error = "search $Global{dirConnError}";
   ERROR(\$error);
@@ -2053,15 +2053,15 @@ $mesg = $Global{ldap}->search(
   filter => $Global{filter},
   attrs  => $Global{att_wanted},
   callback => \&print_entry,
-); 
-   
-if ( $mesg->code && $mesg->code != 48 ) 
+);
+
+if ( $mesg->code && $mesg->code != 48 )
 {
    ERROR($mesg->code);
 }
 
 #
-# Create Hierarchial DN list box data tree, 
+# Create Hierarchial DN list box data tree,
 # and display data.
 #
 
@@ -2070,7 +2070,7 @@ eval
 #
 # Create the base point.
 #
-$Global{'searchHList'}->add($LDAP_SEARCH_BASE, -text=>$LDAP_SEARCH_BASE);  
+$Global{'searchHList'}->add($LDAP_SEARCH_BASE, -text=>$LDAP_SEARCH_BASE);
 
 $results = $Global{'searchResults'};
 
@@ -2079,7 +2079,7 @@ $results = $Global{'searchResults'};
 #
 # build the hierachical list using the DN
 #
-foreach my $dnvar ( @dnKeys ) 
+foreach my $dnvar ( @dnKeys )
 {
  $var = $$results{$dnvar};  # get entry data array
  $shbase = $LDAP_SEARCH_BASE . $sepChar . $$var[0]; # create new leaf
@@ -2103,16 +2103,16 @@ sub print_entry {
   my $information = {};
 
   if ( !defined($entry) )
-  { 
+  {
     return;
   }
- 
+
   $dn = $entry->dn;           # store the entry dn
   ++$Global{'records'};
-  $msgbox->delete("0.0", "end") 
+  $msgbox->delete("0.0", "end")
            if ( !($Global{'records'} % 10 ));
   $msgbox->update if ( !($Global{'records'} % 10 ));
-  $msgbox->insert("0.0", "Entries found: $Global{'records'}") 
+  $msgbox->insert("0.0", "Entries found: $Global{'records'}")
            if ( !($Global{'records'} % 10 ));
   $msgbox->update if ( !($Global{'records'} % 10 ));
   #
@@ -2133,21 +2133,21 @@ sub print_entry {
   #
   # Get a list of record attributes
   #
-  
+
   my @attrs = sort $entry->attributes;
   $max = 0;
   #
   # Calculate each attribute`s text length.
-  # We use this to create a pretty print out in the 
+  # We use this to create a pretty print out in the
   # List Box
   #
-  
+
   foreach (@attrs) { $max = length($_) if length($_) > $max }
 
   #
   # Get attribute`s data
   #
-  
+
   foreach (@attrs) {
 #    my $attr = $entry->get_value($_, asref => 1);
      my $attr = [];
@@ -2167,7 +2167,7 @@ sub print_entry {
     $$information{$_} = $attr;  # record ldap data
 
     next;
-    
+
   }
  }
 push(@$data, $dn);   # dn of entry
@@ -2180,20 +2180,20 @@ $Global{mainWindow} -> Unbusy;  # window is not busy
 } # End of search subroutine
 
 sub AClear {
- 
+
 #
 # Clear out text in Attribute Box
 #
- 
+
 $Global{'adata'} = "";
- 
+
 } # End of AClear subroutine
 
 #
 # Change to a new directory server.
 #
 
-sub server 
+sub server
 {
 my $widget;
 my $ptr;
@@ -2281,7 +2281,7 @@ elsif ( $Global{setVersion} == 3 )
 }
 else
 {
-  if ( defined($Global{dirConnError}) ) 
+  if ( defined($Global{dirConnError}) )
   {
   ERROR(\$Global{dirConnError});
   $msgbox->insert("1", "$Global{dirConnError}");
@@ -2340,18 +2340,18 @@ $flclist->insert(0 , $Global{'infoFilter'});
 #
 # Make the correction and bind to the directory server.
 #
- 
+
 sub dirConn
 {
 my $error;
 $error = 0;
- 
+
 $Global{dirConnError} = undef();
- 
+
  #
  # Make the connection to the directory server
  #
- 
+
 if ( $Global{port} == 636 || $Global{'setSSL'} )
 {
 
@@ -2377,7 +2377,7 @@ if ( !($Global{ldap}->isa('Net::LDAPS') ) )
 $Global{dirConnError} = "LDAPS connection error to $Global{'LDAP_SERVER'}.";
 return -1;
 }
- 
+
 }
 else
 {
@@ -2391,29 +2391,29 @@ if ( $error )
 $Global{dirConnError} = "LDAP connection error to $Global{'LDAP_SERVER'}.";
 return 1;
 }
- 
+
 }
- 
+
 $mesg = $Global{ldap}->bind( password => "$Global{'bindpw'}",
                        dn => "$Global{'binddn'}",
                        version => $Global{'setVersion'},
                        );
- 
+
 if ( $mesg->code && $mesg->code != 48 )
 {
 #  $errstr = $mesg->code;
 #  ERROR($errstr);
   return $mesg->code;
 }
- 
+
 return 0;
- 
+
 } # End of subroutine dirConn
 
 #
 # Connect and bind to the referral directory server
 #
- 
+
 sub dirRConn
 {
 my ($url) = @_;
@@ -2425,10 +2425,10 @@ $Global{dirConnError} = undef();
  #
  # Make the connection to the directory server
  #
- 
+
 if ( $Global{port} == 636 || $Global{'setSSL'} )
 {
- 
+
 $bindcommand = 'require Net::LDAPS; new Net::LDAPS( $url, timeout => 1, debug => $opt{d} ) ';
 
 
@@ -2438,20 +2438,20 @@ $error = "This program currently does not support SSL on Microsoft Windows syste
 ERROR(\$error);
 return 1;
 }
- 
+
 $Global{rldap} = eval $bindcommand;
 if ($@)
 {
 $msgbox->insert("0.0", $@) if ($@ && Tk::Exists($msgbox)) ;
 return -1;
 }
- 
+
 if ( !($Global{rldap}->isa('Net::LDAPS') ) )
 {
 $Global{dirConnError} = "LDAPS connection error to $url.";
 return -1;
 }
- 
+
 }
 else
 {
@@ -2464,23 +2464,23 @@ if ( $error )
 $Global{dirConnError} = "LDAP connection error to $url.";
 return 1;
 }
- 
+
 }
- 
+
 $mesg = $Global{rldap}->bind( password => "$Global{'bindpw'}",
                        dn => "$Global{'binddn'}",
                        version => $Global{'setVersion'},
                        );
- 
+
 if ( $mesg->code && $mesg->code != 48 )
 {
 #  $errstr = $mesg->code;
 #  ERROR($errstr);
   return $mesg->code;
 }
- 
+
 return 0;
- 
+
 } # End of subroutine dirRConn
 
 #
@@ -2488,15 +2488,15 @@ return 0;
 #
 sub dirRUConn
 {
-$Global{rldap}->disconnect; 
+$Global{rldap}->disconnect;
 delete($Global{rldap});
 return 0;
 } # End of subroutine dirRUConn
- 
+
 #
 # Detect and record the sub-bases, or branches, of the directory.
 #
- 
+
 sub getBases()
 {
 my $mesg;
@@ -2505,7 +2505,7 @@ my @base = ();
 my $ptr;
 my $match;
 my $error = 0;  # initialize error flag.
- 
+
 if ( $Global{'nismapname'} )
 {
  #
@@ -2520,7 +2520,7 @@ else
 }
 
 my $f = Net::LDAP::Filter->new($match) or $error = 1;
- 
+
 if ( $error )
 {
 $error = "getBases subroutine Bad filter $match";
@@ -2528,9 +2528,9 @@ ERROR(\$error);
 return @base;
 }
 
-$base[0] = $base; 
+$base[0] = $base;
 $ptr = 0;
- 
+
 while ( $ptr < @base )
 {
  if ( @base < $Global{'limit'} )
@@ -2550,9 +2550,9 @@ while ( $ptr < @base )
 }
 shift(@base);  # get rid of the namingContext entry
 return @base;
- 
+
 } # End of subroutine getBases()
- 
+
 sub calBase()
 {
 my ( $base, $f ) = @_;
@@ -2561,19 +2561,19 @@ my $entry;
 my $errstr;
 my $error = 0;
 my @new_base = ();
- 
+
 $mesg = $Global{ldap}->search(
   base   => $base,
   filter => $f,
   attrs  => [ "cn","nismapname","automountMapName" ],
   scope  => "one",
 );
- 
+
 #
 # Check for an error on search
 # Search call work, but there was an ldap error.
 #
- 
+
 if ( $mesg->code && $mesg->code != 11 )
 {
    $errstr = $mesg->code;
@@ -2582,21 +2582,21 @@ if ( $mesg->code && $mesg->code != 11 )
 }
 else
  {
- 
+
  $entry = $mesg->entry;
- 
+
  return @new_base unless defined($entry);
  $count = $mesg->count();
- 
+
  for($i = 0 ; $i < $count ; $i++)
  {
  my $entry = $mesg->entry($i);
- 
+
  $dn = $entry->dn;
  $dn = canonical_dn($dn,casefold => "lower");
  $dn =~ tr/[A-Z]/[a-z]/;
  $_ = $dn;
- 
+
 #
 # Record only dn that start with ou=, or in some cases nismapname.
 # Normal entrys can be mixed in with these objects.
@@ -2609,10 +2609,10 @@ else
  {
   push(@new_base, $dn);  # record only dn that start with ou=
  }
- 
+
  }
 return @new_base;
- 
+
 }
 } # End of subroutine calBase()
 
@@ -2621,12 +2621,12 @@ return @new_base;
 #
 sub globalPos
 {
- 
+
 my @pos;
 @pos = split(/\+/,$Global{'mainWindow'}->geometry());
 $Global{'horz'} = $pos[1];
 $Global{'vert'} = $pos[2];
- 
+
 } # End of subrountine globalPos
 
 sub root_cancel
@@ -2646,17 +2646,17 @@ my $jpegFile = $ENV{'TMP'} ."/jpegfile.$$";
 #
 open(TMP, "+>$jpegFile");
 $| = 1;
- 
+
 print TMP $picture;
 close(TMP);
- 
+
 if ( !-e "$jpegFile" )
 {
 my $str = "Could not create temporary jpeg file $jpegFile";
 ERROR( \$str );
 return;
 }
- 
+
 #
 # Create a TK window to display the jpeg picture.
 #
@@ -2667,28 +2667,28 @@ $list->pack( -side => "top" );
 $list->insert("end", $dn);
 
 my $image = $mw->Photo(-file => $jpegFile, -format => "jpeg" );
- 
+
 $mw->Label(-image => $image)->pack(-expand => 1, -fill => 'both');
 $mw->Button(-text => 'CLOSE WINDOW', -command => [destroy => $mw])->pack;
 MainLoop;
- 
+
 unlink $jpegFile;
- 
-} # End of displayPhoto 
+
+} # End of displayPhoto
 
 #
 # Create Main Error Window
 #
- 
+
 sub ERROR {
 my ($errcode ) = @_;
 my $errmsg;
- 
+
 return if ($errcode == 48 && $Global{'setVersion'} == 3 ); # Anonymous bind error, not really an error.
- 
+
 my $x = $Global{'horz'} + 150;
 my $y = $Global{'vert'} + 150;
- 
+
 if ( ref($errcode) )
 {
 $errmsg = $$errcode;
@@ -2696,18 +2696,18 @@ $errmsg = $$errcode;
 else                                                                            {
 $errmsg = ldap_error_text($errcode);
 }
- 
+
 my @errmsg = split(/\n/,$errmsg);
- 
+
 #
 # Create Main Error Window
 #
 if ( ! Exists($Global{'errorWindow'} ) )
 {
 $Global{'errorWindow'} = MainWindow->new;
- 
+
 $Global{'errorWindow'}->title("ERROR MESSAGES");
- 
+
 $Global{'errorWindow'}->geometry("+$x+$y");
 #
 # Create process dismiss button
@@ -2715,13 +2715,13 @@ $Global{'errorWindow'}->geometry("+$x+$y");
 $Global{'errorWindow'}->Button( -text => "DISMISS", -command => \&dismiss,
            -font => $Global{'Font'}, -borderwidth => 3 )
            -> pack(-side => "bottom", -padx => 5, -pady => 5 ) ;
- 
+
 $errlist = $Global{'errorWindow'} ->Scrolled(Listbox, -scrollbars => 'se',
                                   -width => 70, -height => 10  );
- 
+
 $errlist->pack(-fill => "both", -expand => 1 );
 }
- 
+
 $errlist->insert("end", "Error Code: $errcode") if ( !ref($errcode) );
 $errlist->insert("end", "") if ( !ref($errcode) );
 
@@ -2729,33 +2729,33 @@ foreach my $msg ( @errmsg )
 {
 $errlist->insert("end", $msg);
 }
- 
+
 sub dismiss{
- 
+
 $Global{'errorWindow'}->destroy() if Tk::Exists($Global{'errorWindow'});
 $errlist = undef();
- 
+
 } # End of dismiss subroutine
- 
+
 } # End of ERROR subroutine
- 
+
 #
 # LDAP Error check, some return codes are not really errors.
 # You can retry the ldap action after waiting a while.
 #
- 
+
 sub CheckError {
- 
+
 my ( $error ) = @_;
- 
+
 #
 # Check for DSA busy or internal error
 #
- 
+
 if ( $Global{loopCount} > 61 ) {
   return 0;  # return an error condition.
 }
- 
+
 ++$Global{loopCount};    # Increment the loop counter.
 
 if ( $error =~ /too busy/ ||
@@ -2772,17 +2772,17 @@ else {
    # DSA did not return "DSA busy" message
    #
    return 0;  # error
- 
+
    }
- 
+
 } # End of subrountine  CheckError
 
 #
 # Create Main Bind Window
 #
- 
+
 sub BIND {
- 
+
 $dn_data = "";
 $pw_data = "";
 &globalPos();
@@ -2791,78 +2791,78 @@ my $x = $Global{'horz'} + 150;
 my $y = $Global{'vert'} + 150;
 
 if ( !Tk::Exists( $Global{'bindWindow'} ) )
-{ 
+{
 #
 # Create Main Bind Window
 #
- 
+
 $Global{'bindWindow'} = MainWindow->new;
- 
+
 $Global{'bindWindow'}->title("SET BIND CREDENTIALS");
- 
+
 $Global{'bindWindow'}->geometry("+$x+$y");
 #
 # Create process accept button
 #
-$Global{'bindWindow'}->Button( -text => "ACCEPT", -command => \&accept, 
+$Global{'bindWindow'}->Button( -text => "ACCEPT", -command => \&accept,
            -font => $Global{'Font'}, -borderwidth => 3 )
            -> pack(-side => "bottom", -padx => 5, -pady => 5 ) ;
- 
+
 #
 # Create process cancel button
 #
-$Global{'bindWindow'}->Button(-text => "CANCEL", -command => \&cancel, 
+$Global{'bindWindow'}->Button(-text => "CANCEL", -command => \&cancel,
            -font => $Global{'Font'}, -borderwidth => 3)
            -> pack(-side => "top", -padx => 5, -pady => 5 ) ;
- 
+
 my $binddnframe = $Global{'bindWindow'}->LabFrame(-label => "DN",
       -labelside => "acrosstop")
       ->pack( -fill => "both", -side => "top", -padx => 5, -pady => 5 );
- 
+
 #
 # Create DN Entry text box.
 #
 $dn_data = $Global{binddn} if ( length($Global{binddn}) );
- 
+
 $binddnframe->Entry(-textvariable => \$dn_data, -width => 25 )
       -> pack(-fill => 'x');
- 
+
 my $bindpwframe = $Global{'bindWindow'}->LabFrame(-label => "PASSWORD",
       -labelside => "acrosstop")
       ->pack( -fill => "both", -side => "top", -padx => 5, -pady => 5 );
- 
+
 #
 # Create Password Entry text box.
 #
- 
-$bindpwdata = $bindpwframe->Entry(-show => '*', -textvariable => \$pw_data, 
+
+$bindpwdata = $bindpwframe->Entry(-show => '*', -textvariable => \$pw_data,
                     -width => 25, -font => $Global{'Font'} )
                     -> pack(-fill => 'x');
 
 $bindpwdata->bind('<Key-Return>' => \&accept );
 
 sub cancel{
- 
+
 $Global{'bindWindow'}->destroy() if Tk::Exists($Global{'bindWindow'});
-$Global{'bindWindow'} = undef(); 
+$Global{'bindWindow'} = undef();
 } # End of cancel subroutine
- 
-sub accept{ 
+
+sub accept{
 my $mesg;
- 
- 
+
+
 if (defined($Global{ldap}) )
 {
 #
 # Connect to directory server
-# 
+#
 
-$mesg = $Global{ldap}->bind( password => "$pw_data", 
-                     dn => "$dn_data", 
+$mesg = $Global{ldap}->bind( password => "$pw_data",
+                     dn => "$dn_data",
                      version => $Global{'setVersion'},
                    );
-   
-if ( $mesg->code && $mesg->code != 48 ) 
+
+if ( $mesg->code && $mesg->code != 48 )
 {
    $errstr = $mesg->code;
    ERROR($errstr);
@@ -2876,53 +2876,53 @@ $Global{'bindpw'} = $pw_data;
 $Global{'bindWindow'}->Unbusy;
 }
 
-} 
+}
 
 $Global{'bindWindow'}->destroy() if Tk::Exists($Global{'bindWindow'});
-$Global{'bindWindow'} = undef(); 
- 
+$Global{'bindWindow'} = undef();
+
 } # End of accept subroutine
 }
 
 } # End of BIND subroutine
- 
+
 #
 # Create Main Port Window
 #
- 
+
 sub PORT {
- 
+
 $port_data = $Global{port};
 &globalPos();
 my $x = $Global{'horz'} + 150;
 my $y = $Global{'vert'} + 150;
- 
+
 #
 # Create Main Port Window
 #
- 
+
 $Global{'portWindow'} = MainWindow->new;
- 
+
 $Global{'portWindow'}->title("DIRECTORY PORT");
- 
+
 $Global{'portWindow'}->geometry("+$x+$y");
 #
 # Create process accept button
 #
-$Global{'portWindow'}->Button( -text => "ACCEPT", -command => \&portAccept, 
+$Global{'portWindow'}->Button( -text => "ACCEPT", -command => \&portAccept,
            -font => $Global{'Font'}, -borderwidth => 3 )
            -> pack(-side => "bottom", -padx => 5, -pady => 5 ) ;
- 
+
 #
 # Create process cancel button
 #
-$Global{'portWindow'}->Button(-text => "CANCEL", -command => \&portCancel, 
+$Global{'portWindow'}->Button(-text => "CANCEL", -command => \&portCancel,
            -font => $Global{'Font'}, -borderwidth => 3)
            -> pack(-side => "top", -padx => 5, -pady => 5 ) ;
- 
+
 $Global{'portWindow'}->Label(-text => "Port 389 default")
       ->pack( -side => "top", -anchor => 'w', -pady => 1 );
- 
+
 $Global{'portWindow'}->Label(-text => "Port 636 ssl default")
       ->pack( -side => "top", -anchor => 'w', -pady => 1 );
 
@@ -2930,7 +2930,7 @@ $Global{'portWindow'}->Label(-text => "Port 636 ssl default")
 # Create a ssl Checkbutton that will set up ssl variable
 # to set ssl if not port 636.
 #
- 
+
 #$Global{'portWindow'}  -> Checkbutton(
 #                       -text => "SSL connection",
 #                       -variable =>  \$Global{'setSSL'},
@@ -2951,38 +2951,38 @@ else
 my $portframe = $Global{'portWindow'}->LabFrame(-label => "PORT",
       -labelside => "acrosstop")
       ->pack( -fill => "both", -side => "top", -padx => 5, -pady => 5 );
- 
+
 #
 # Create Port Entry text box.
 #
- 
+
 $portframe->Entry(-textvariable => \$port_data, -width => 10 )
       -> pack(-fill => 'x');
- 
- 
+
+
 sub portCancel{
- 
+
 $Global{'portWindow'}->destroy() if Tk::Exists($Global{'portWindow'});
-$Global{'portWindow'} = undef(); 
- 
+$Global{'portWindow'} = undef();
+
 } # End of cancel subroutine
- 
-sub portAccept{ 
- 
+
+sub portAccept{
+
 $Global{port} = $port_data;
 if ( $Global{setSSL} ) { $Global{sslport} = $port_data;}
 else { $Global{nsslport} = $port_data;}
 $Global{dsaptls}->insert(0, $Global{port});
 $Global{'portWindow'}->destroy() if Tk::Exists($Global{'portWindow'});
-$Global{'portWindow'} = undef(); 
- 
+$Global{'portWindow'} = undef();
+
 } # End of accept subroutine
 } # End of PORT subroutine
 
 #
 # Create Schema Display Window
 #
- 
+
 sub print_loop()
 {
 my $list = shift;
@@ -3003,19 +3003,19 @@ foreach $ahash ( @$ocs)
    #
 
    my @hkeys = keys(%$ahash);
- 
+
    foreach $var (@hkeys)
    {
    # Step through the hash keys
-  
+
    next if ( $var =~ /type/);  # do not care about type
 
    $alArray =  $$ahash{$var};
- 
+
    if ( ref($alArray) eq 'ARRAY' )
    {
    # it is a n array pointer so there is probably a list.
- 
+
    my $asize = @$alArray;  # get the size of the list.
    #
    # if the array has size then print the array
@@ -3023,7 +3023,7 @@ foreach $ahash ( @$ocs)
    #
    if ( $asize  )
    {
-   # Okay, there is something in the array. 
+   # Okay, there is something in the array.
 
    $list->insert("end", "\t$var: ");
 
@@ -3038,7 +3038,7 @@ foreach $ahash ( @$ocs)
    {
    # There is not an array
    if ( $alArray ==  1)
-   { 
+   {
    # it is just information attribute for the object
    $list->insert("end", "\t$var\n");
    }
@@ -3047,7 +3047,7 @@ foreach $ahash ( @$ocs)
    $list->insert("end", "\t$var:  $alArray\n");
    }
    }
- 
+
 }
 
 }
@@ -3063,13 +3063,13 @@ sub schema_clear {
 $schema_list->delete("1.0", "end");
 
 } # End of clear subroutine
- 
+
 #
 #
 # Get the directory schema
 #
 
-sub schema 
+sub schema
 {
 my $mesg;
 my $error = 0;
@@ -3090,12 +3090,12 @@ if ( ! defined($Global{ldap}) )
 {
 #
 # Connect to directory server
-# 
+#
 $error = dirConn();
 
 if ( $error == 1 )
 {
-  if ( defined($Global{dirConnError}) ) 
+  if ( defined($Global{dirConnError}) )
   {
   $schema_list->insert("end",  "$Global{dirConnError}\n");
   }
@@ -3106,7 +3106,7 @@ if ( $error == 1 )
    return;
 }
 
-} 
+}
 
 #
 # Get the schema, tries to read rootdse, if unable assumes cn=schema.
@@ -3131,7 +3131,7 @@ if ( $Global{'sfile'} && defined($schemaHash{'schema'}) )
   #
 #    @xml_data = ();
 #    $dsml = Net::LDAP::DSML->new( output => \@xml_data, pretty_print => 1 );
-    open(FXML, ">$Global{'fdata'}");  
+    open(FXML, ">$Global{'fdata'}");
     $dsml = Net::LDAP::DSML->new( output => *FXML, pretty_print => 1 );
     $dsml->write_schema($schemaHash{'schema'});
     $dsml->end_dsml;
@@ -3144,7 +3144,7 @@ if ( $Global{'sfile'} && defined($schemaHash{'schema'}) )
     #
     $schemaHash{'schema'}->dump( $Global{'fdata'} );
   }
- 
+
   $schema_list->insert("end",
                        "Schema data written to file: $Global{'fdata'}\n");
   $Global{'sfile'} = 0;
@@ -3164,16 +3164,16 @@ $ra_atts = [];
 #
 # Get the attributes
 #
-@$ra_atts = $schemaHash{'schema'}->all_attributes(); 
-$schemaHash{'atts'} = $ra_atts; 
+@$ra_atts = $schemaHash{'schema'}->all_attributes();
+$schemaHash{'atts'} = $ra_atts;
 
 #
 # Display the attributes
 #
- 
+
 if ( $selectAll || $selectAtt  )
 {
-&print_loop($schema_list, $schemaHash{'atts'}, "attributeType") 
+&print_loop($schema_list, $schemaHash{'atts'}, "attributeType")
   if ( defined($schemaHash{'atts'}) );
 }
 
@@ -3181,15 +3181,15 @@ $ra_atts = [];
 #
 # Get the schema objectclasses
 #
-@$ra_atts = $schemaHash{'schema'}->all_objectclasses(); 
+@$ra_atts = $schemaHash{'schema'}->all_objectclasses();
 $schemaHash{'ocs'} = $ra_atts;
 
 #
 # Calculate the text length of each objectclass string.
 #
-foreach my $var (@$ra_atts) 
-{ 
-  $Global{'max'} = length($$var{'name'}) 
+foreach my $var (@$ra_atts)
+{
+  $Global{'max'} = length($$var{'name'})
         if length($$var{'name'}) > $Global{'max'} ;
 }
 
@@ -3203,10 +3203,10 @@ $Global{'max'} += 6;
 #
 # Display the objectclasses
 #
- 
+
 if ( $selectAll || $selectObj )
 {
-&print_loop($schema_list, $schemaHash{'ocs'}, "objectClasses") 
+&print_loop($schema_list, $schemaHash{'ocs'}, "objectClasses")
     if ( defined($schemaHash{'ocs'}) );
 }
 
@@ -3214,16 +3214,16 @@ if ( $selectAll || $selectObj )
 # Get the schema matchingrules
 #
 $ra_atts = [];
-@$ra_atts = $schemaHash{'schema'}->all_matchingrules(); 
+@$ra_atts = $schemaHash{'schema'}->all_matchingrules();
 $schemaHash{'mrs'} = $ra_atts;
 
 #
 # Display the matchingrules
 #
- 
+
 if ( $selectAll || $selectMatch )
 {
-&print_loop($schema_list, $schemaHash{'mrs'}, "matchingRules" ) 
+&print_loop($schema_list, $schemaHash{'mrs'}, "matchingRules" )
     if ( defined($schemaHash{'mrs'}) );
 }
 
@@ -3231,16 +3231,16 @@ if ( $selectAll || $selectMatch )
 # Get the schema matchingruleuse
 #
 $ra_atts = [];
-@$ra_atts = $schemaHash{'schema'}->all_matchingruleuses(); 
+@$ra_atts = $schemaHash{'schema'}->all_matchingruleuses();
 $schemaHash{'mru'} = $ra_atts;
 
 #
 # Display the matchingruleuse
 #
- 
+
 if ( $selectAll || $selectMru )
 {
-&print_loop($schema_list, $schemaHash{'mru'}, "matchingRuleUse" ) 
+&print_loop($schema_list, $schemaHash{'mru'}, "matchingRuleUse" )
     if ( defined($schemaHash{'mru'}) );
 }
 
@@ -3248,16 +3248,16 @@ if ( $selectAll || $selectMru )
 # Get the schema ldapsyntaxes
 #
 $ra_atts = [];
-@$ra_atts = $schemaHash{'schema'}->all_syntaxes(); 
+@$ra_atts = $schemaHash{'schema'}->all_syntaxes();
 $schemaHash{'lsyn'} = $ra_atts;
 
 #
 # Display the ldapsyntaxes
 #
- 
+
 if ( $selectAll || $selectSyn )
 {
-&print_loop($schema_list, $schemaHash{'lsyn'}, "ldapSyntax" ) 
+&print_loop($schema_list, $schemaHash{'lsyn'}, "ldapSyntax" )
     if ( defined($schemaHash{'lsyn'}) );
 }
 
@@ -3265,16 +3265,16 @@ if ( $selectAll || $selectSyn )
 # Get the schema nameForms
 #
 $ra_atts = [];
-@$ra_atts = $schemaHash{'schema'}->all_nameforms(); 
+@$ra_atts = $schemaHash{'schema'}->all_nameforms();
 $schemaHash{'nfm'} = $ra_atts;
 
 #
 # Display the nameForms
 #
- 
+
 if ( $selectAll || $selectNf )
 {
-&print_loop($schema_list, $schemaHash{'nfm'}, "nameForms" ) 
+&print_loop($schema_list, $schemaHash{'nfm'}, "nameForms" )
     if ( defined($schemaHash{'nfm'}) );
 }
 
@@ -3282,16 +3282,16 @@ if ( $selectAll || $selectNf )
 # Get the schema ditstructurerules
 #
 $ra_atts = [];
-@$ra_atts = $schemaHash{'schema'}->all_ditstructurerules(); 
+@$ra_atts = $schemaHash{'schema'}->all_ditstructurerules();
 $schemaHash{'dits'} = $ra_atts;
 
 #
 # Display the ditstructurerules
 #
- 
+
 if ( $selectAll || $selectDsr )
 {
-&print_loop($schema_list, $schemaHash{'dits'}, "ditstructurerules" ) 
+&print_loop($schema_list, $schemaHash{'dits'}, "ditstructurerules" )
     if ( defined($schemaHash{'dits'}) );
 }
 
@@ -3299,27 +3299,27 @@ if ( $selectAll || $selectDsr )
 # Get the schema ditcontentrules
 #
 $ra_atts = [];
-@$ra_atts = $schemaHash{'schema'}->all_ditcontentrules(); 
+@$ra_atts = $schemaHash{'schema'}->all_ditcontentrules();
 $schemaHash{'ditc'} = $ra_atts;
 
 #
 # Display the ditcontentrules
 #
- 
+
 if ( $selectAll || $selectDcr )
 {
-&print_loop($schema_list, $schemaHash{'ditc'}, "ditcontentrules" ) 
+&print_loop($schema_list, $schemaHash{'ditc'}, "ditcontentrules" )
     if ( defined($schemaHash{'ditc'}) );
 }
 
-$Global{'max'} = 50 if ( $Global{'max'} > 50 ); 
+$Global{'max'} = 50 if ( $Global{'max'} > 50 );
 &objTree();   # Create the objectClass tree
 $Global{'olist'}->delete('all') if  Tk::Exists($Global{'olist'});
 $Global{mainWindow} -> update;  # Allow Tk to update
 &initializeP5a(); # Finish making panel 5
 
-} # End of if ( defined($schema) ) 
-else 
+} # End of if ( defined($schema) )
+else
 {
   $schema_list->insert("end",  "The schema object was return undefined.\n");
   $schema_list->insert("end",  "There are several problems that can cause\n");
@@ -3339,7 +3339,7 @@ else
 
 } # End of schema subroutine
 
-sub objTree 
+sub objTree
 {
 my $ocs = $schemaHash{'ocs'};
 my $obj = $schemaHash{'obj'};
@@ -3356,7 +3356,7 @@ my $name;
 my $SUP;
 my $array;
 
-if ( !defined($ocs) || !defined($tree) || 
+if ( !defined($ocs) || !defined($tree) ||
      !defined($obj) || !defined($schema) )
 {
    #
@@ -3377,7 +3377,7 @@ foreach my $aobj ( @$ocs)
    #
    my $oid;
    undef($oid);
-   $oid = $$aobj{'oid'}; 
+   $oid = $$aobj{'oid'};
    next if ( !defined($oid) );
     @sup = $$aobj{'sup'}[0];
     @name = $$aobj{'name'};
@@ -3400,7 +3400,7 @@ foreach (@tmpKeys)
 next if ( $_ eq "" || $_ eq "top" );
 
 $done = 0;  # initialize done flag
-$Path = "";  # initialize objectclass Path 
+$Path = "";  # initialize objectclass Path
 
 $name = $_;
 while ( !$done )
@@ -3424,16 +3424,16 @@ $_ = $SUP;  # walk back up the chain
 if ( defined($$tree{$Path}) )
 {
 #
-# Path key has already been initialized, add current objectclass 
+# Path key has already been initialized, add current objectclass
 # to list.
 #
 $array = $$tree{$Path};
 push(@$array,$name);
 }
-else 
+else
 {
 #
-# Path key needs to be initialized, add current objectclass 
+# Path key needs to be initialized, add current objectclass
 # to list.
 #
 $$tree{$Path} = [0, "$name"];
@@ -3449,7 +3449,7 @@ $Global{'mainWindow'}->update;
 
 }
 
-sub Hierarchial 
+sub Hierarchial
 {
 &globalPos();
 my $x = $Global{'horz'};
@@ -3473,28 +3473,28 @@ my $array;
 #
 #
 
-if ( ! Exists($Global{'histWindow'} ) ) 
+if ( ! Exists($Global{'histWindow'} ) )
 {
-  eval 
-     { 
-       $Global{'histWindow'} = MainWindow->new(); 
+  eval
+     {
+       $Global{'histWindow'} = MainWindow->new();
        $Global{'histWindow'}->title("HIERARCHICAL OBJECTCLASS DISPLAY WINDOW");
      };
-  ERROR(\$@) if ( $@ ); 
+  ERROR(\$@) if ( $@ );
 }
-else 
+else
 {
  my $wstate = $Global{'histWindow'}->state();
  if ( $wstate =~ /iconic/ || $wstate =~ /withdrawn/ )
  {
- $Global{'histWindow'}->deiconify() 
-        if Tk::Exists($Global{'histWindow'}); 
- $Global{'histWindow'}->raise() 
-        if Tk::Exists($Global{'histWindow'}); 
+ $Global{'histWindow'}->deiconify()
+        if Tk::Exists($Global{'histWindow'});
+ $Global{'histWindow'}->raise()
+        if Tk::Exists($Global{'histWindow'});
  }
 }
 
-$Global{'histWindow'}->geometry("+$x+$y"); 
+$Global{'histWindow'}->geometry("+$x+$y");
 #
 # Create label box
 #
@@ -3506,11 +3506,11 @@ $Global{'label'} = $Global{'histWindow'}->Label()->pack;
 
 
 $hbutton = $Global{'histWindow'}->Button(
-              -text => "CLOSE HIERARCHICAL DISPLAY WINDOW", 
+              -text => "CLOSE HIERARCHICAL DISPLAY WINDOW",
               -command => \&hist_cancel, -font => $Global{'Font'},
               -borderwidth => 5 )
-              -> pack(-fill => "both", -padx => 2, -pady => 2 ) 
-              if ( Exists($Global{'histWindow'} ) && 
+              -> pack(-fill => "both", -padx => 2, -pady => 2 )
+              if ( Exists($Global{'histWindow'} ) &&
                    !Exists($hbutton ) );
 
 #
@@ -3522,7 +3522,7 @@ if ( !Exists($Global{'list'}) )
 {
 $Global{'list'} = $Global{'histWindow'}->Scrolled('ROText',
             -scrollbars => 'se', -width=>50, -wrap => "none",
-            -font => $Global{'Font'}, -height => 20 ) 
+            -font => $Global{'Font'}, -height => 20 )
             ->pack(-side => "left");
 }
 
@@ -3534,10 +3534,10 @@ $Global{'list'} = $Global{'histWindow'}->Scrolled('ROText',
 
 if ( !Exists($Global{'hlist'}) )
 {
-$Global{'hlist'} = $Global{'histWindow'}->Scrolled('HList', 
+$Global{'hlist'} = $Global{'histWindow'}->Scrolled('HList',
             -font       => $Global{'Font'},
             -scrollbars => 'se',
-            -width      => $Global{'max'}, 
+            -width      => $Global{'max'},
             -height     => 20,
             -itemtype   => 'text',
             -separator  => $sepChar,
@@ -3553,7 +3553,7 @@ $Global{'hlist'} = $Global{'histWindow'}->Scrolled('HList',
             $Global{'list'}->insert("end", " \n");
 
             foreach my $var (@objectclasses)
-            { 
+            {
                $Global{mainWindow}->update;
                $oid = $$obj{$var}->[0];
                #
@@ -3571,16 +3571,16 @@ $Global{'hlist'} = $Global{'histWindow'}->Scrolled('HList',
                foreach $varr (@hkeys)
                {
                 # Step through the hash keys
-  
+
                 next if ( $varr =~ /name/);  # already done name.
                 next if ( $varr =~ /type/);  # do not care about type
 
                 $alArray =  $$ahash{$varr};
- 
+
                 if ( ref($alArray) eq 'ARRAY' )
                 {
                  # it is a n array pointer so there is probably a list.
- 
+
                  my $asize = @$alArray;  # get the size of the list.
                  #
                  # if the array has size then print the array
@@ -3588,10 +3588,10 @@ $Global{'hlist'} = $Global{'histWindow'}->Scrolled('HList',
                  #
                  if ( $asize  )
                  {
-                 # Okay, there is something in the array. 
- 
+                 # Okay, there is something in the array.
+
                   $Global{'list'}->insert("end", "\t$varr: ");
- 
+
                   foreach $a ( @$alArray )
                   {
                    $Global{'list'}->insert("end", "$a ");
@@ -3603,7 +3603,7 @@ $Global{'hlist'} = $Global{'histWindow'}->Scrolled('HList',
                 {
                  # It is not an array
                  if ( $alArray ==  1)
-                 { 
+                 {
                   # it is just and information attribute for the object
                   $Global{'list'}->insert("end", "\t$varr\n");
                  }
@@ -3612,8 +3612,8 @@ $Global{'hlist'} = $Global{'histWindow'}->Scrolled('HList',
                   $Global{'list'}->insert("end", "\t$varr:  $alArray\n");
                  }
                 }
- 
-               } 
+
+               }
 
             $Global{'list'}->insert("end", " \n");
             $Global{'list'}->insert("end", "--------------------------------------------------\n");
@@ -3629,20 +3629,20 @@ my $base;
 $base = "";
 
 #
-# Create Hierarchial list box data tree, 
+# Create Hierarchial list box data tree,
 # and display data.
 #
 
 eval{
- foreach ( @tmpKeys ) 
+ foreach ( @tmpKeys )
  {
-    if ( $$tree{$_} ->[0] == 0 ) 
+    if ( $$tree{$_} ->[0] == 0 )
     {
       $$tree{$_} ->[0] = 1;
       $Global{'hlist'}->add($_, -text=>$_);  # do the base.
     }
 
-    $base = $_; 
+    $base = $_;
     $array = $$tree{$_};
     $ptr = 0;
     foreach my $var ( @$array )
@@ -3652,12 +3652,12 @@ eval{
         $ptr = 1;
         next;
       }
-      $_ = $base . $sepChar . $var; 
+      $_ = $base . $sepChar . $var;
       $Global{'hlist'}->add($_, -text => $var);
       if ( defined($$tree{$_}) )
       {
         $$tree{$_}->[0] = 1;
-      } 
+      }
     }
 
  }
@@ -3671,12 +3671,12 @@ print "$@" if ( defined($@));
 # Reset objectClass array.
 #
 
-foreach ( @tmpKeys ) 
+foreach ( @tmpKeys )
 {
  if ( defined($$tree{$_}) )
  {
   $$tree{$_}->[0] = 0;
- } 
+ }
 }
 
 }
@@ -3690,87 +3690,87 @@ sub hist_clear {
 $Global{'list'}->delete("1.0", "end");
 
 } # End of clear subroutine
- 
+
 sub hist_cancel{
 $Global{'list'}->destroy if Tk::Exists($Global{'list'});
 $Global{'hlist'}->destroy if Tk::Exists($Global{'hlist'});
 $Global{'histWindow'}->destroy if Tk::Exists($Global{'histWindow'});
 } # End of cancel subroutine
 
-} # End of subroutine  Hierarchial 
- 
+} # End of subroutine  Hierarchial
+
 #
 # Create Accept/Cancel Window
 #
- 
+
 sub questionAction {
 &globalPos();
 my $x = $Global{'horz'} + 0;
 my $y = $Global{'vert'} + 50;
- 
+
 #
 # Create Main Window
 #
- 
+
 $Global{'answerWindow'} = MainWindow->new;
- 
+
 $Global{'answerWindow'}->title("CONFIRM DECISION");
- 
+
 $Global{'answerWindow'}->geometry("+$x+$y");
 #
 # Create process accept button
 #
-$Global{'answerWindow'}->Button( -text => "ACCEPT", -command => \&doAction, 
+$Global{'answerWindow'}->Button( -text => "ACCEPT", -command => \&doAction,
            -font => $Global{'Font'}, -borderwidth => 3 )
            -> pack(-side => "bottom", -padx => 5, -pady => 5 ) ;
- 
+
 #
 # Create process cancel button
 #
-$Global{'answerWindow'}->Button(-text => "CANCEL", -command => \&cancelAction, 
+$Global{'answerWindow'}->Button(-text => "CANCEL", -command => \&cancelAction,
            -font => $Global{'Font'}, -borderwidth => 3)
            -> pack(-side => "top", -padx => 5, -pady => 5 ) ;
- 
+
 sub cancelAction{
- 
+
 $Global{'answerWindow'}->destroy() if Tk::Exists($Global{'answerWindow'});
-delete($Global{'answerWindow'}); 
+delete($Global{'answerWindow'});
 } # End of cancel subroutine
- 
-sub doAction{ 
- 
+
+sub doAction{
+
 $Global{'answerWindow'}->destroy() if Tk::Exists($Global{'answerWindow'});
-delete($Global{'answerWindow'}); 
+delete($Global{'answerWindow'});
 $Global{'searchHistWindow'}->destroy if Tk::Exists($Global{'searchHistWindow'});
-$Global{'searchHistWindow'} = undef(); 
+$Global{'searchHistWindow'} = undef();
 
 &ldapActionDelete;   # Delete the entry from the directory
- 
+
 } # End of accept subroutine
 } # End of questionAction subroutine
 
- 
+
 #
 # Create ldapAction Window
 #
- 
-sub ldapAction 
+
+sub ldapAction
 {
 
 $Global{'ldapActionDN'} = shift;
 $Global{actionDelete}->configure( -state => 'normal');
-$Global{actionDisplay}->configure( -state => 'normal'); 
+$Global{actionDisplay}->configure( -state => 'normal');
 $Global{actionEdit}->configure( -state => 'normal');
 $Global{actionRename}->configure( -state => 'normal');
 $Global{actionLdif}->configure( -state => 'normal');
 $Global{actionCancel}->configure( -state => 'normal');
 } # End of ldapAction subroutine
- 
+
 sub ldapActionCancel{
 
 delete($Global{'ldapActionDN'});
 $Global{actionDelete}->configure( -state => 'disable');
-$Global{actionDisplay}->configure( -state => 'disable'); 
+$Global{actionDisplay}->configure( -state => 'disable');
 $Global{actionEdit}->configure( -state => 'disable');
 $Global{actionRename}->configure( -state => 'disable');
 $Global{actionLdif}->configure( -state => 'disable');
@@ -3781,7 +3781,7 @@ $Global{actionCancel}->configure( -state => 'disable');
 sub ldapActionCreateEntry
 {
 
-if ( !Exists($Global{'olist'}) ) 
+if ( !Exists($Global{'olist'}) )
 {
 &initializeP5a(); # Finish making panel 5
 }
@@ -3802,14 +3802,14 @@ my $y = $Global{'vert'} + 100;
 if (!  Exists($Global{'createWindow'}) )
 {
 $Global{'createWindow'} = MainWindow->new;
- 
+
 $Global{'createWindow'}->title("CREATE DIRECTORY ENTRY");
- 
+
 $Global{'createWindow'}->geometry("+$x+$y");
 #
 # Create process Exit button
 #
- 
+
 $createExit = $Global{'createWindow'}->Button(
                        -text => "CANCEL CREATE ENTRY DISPLAY",
                        -command => \&create_cancel, -font => $Global{'Font'},
@@ -3825,13 +3825,13 @@ $Global{'createWindow'}->Label( -text => "All attributes in red, or located abov
 $Global{'createWindow'}->Label(-text => "entered for the attribute.")
       ->pack(-side => "top", -anchor => 'w');
 #
-# Create a ROText Box that will actually contain the 
+# Create a ROText Box that will actually contain the
 # returned directory data.
 #
 
-$createlist = $Global{'createWindow'} ->Scrolled('ROText', 
+$createlist = $Global{'createWindow'} ->Scrolled('ROText',
         -scrollbars => 'se',
-        -width => 100, -height => 20, -wrap => 'none', 
+        -width => 100, -height => 20, -wrap => 'none',
         -font => $Global{'Font'}  );
 
 $createlist->pack(-fill => "both", -expand => 1 );
@@ -3864,7 +3864,7 @@ $dnTxt = $createlist->Entry(-width => 65,
                    -textvariable => \$Creation{dn}->[0] );
 
 $createlist->windowCreate("end", -window => $dnTxt );
- 
+
 $createlist->insert("end", "\n"); # position to the next row.
 #
 # create attribute label
@@ -3879,7 +3879,7 @@ $Creation{$_}->[0] = "" if ( !/objectClass/ );
 $NamingAttribute = "";
 
 ${$_} = $createlist->Radiobutton( -text => "", -anchor => 'w',
-                    -variable => \$NamingAttribute, -value => "$_" ) 
+                    -variable => \$NamingAttribute, -value => "$_" )
                     if ( !/objectClass/ );
 
 $createlist->windowCreate("end", -window => ${$_} );
@@ -3890,21 +3890,21 @@ ${$_} = $createlist->Label(-text => "$_",
                     -foreground => 'red',
                     -anchor => 'e',
                     -width => ($max+2) ) if ( !/objectClass/ );
- 
+
 $createlist->windowCreate("end", -window => ${$_} );
 #
 # create data entry window
 #
 ${$_} = $createlist->Entry(-width => 65,
-                   -textvariable => \$Creation{$_}->[0] ) 
+                   -textvariable => \$Creation{$_}->[0] )
    if ( !/objectClass/ );
 
 $createlist->windowCreate("end", -window => ${$_} ) if ( !/objectClass/ );
- 
+
 $createlist->insert("end", "\n") if ( !/objectClass/ );
 }
 
-$ptr = 0; 
+$ptr = 0;
 $Creation{objectClass} = [];
 
 foreach ( @{$Global{entryData}->{objectClass}} )
@@ -3915,7 +3915,7 @@ ${$_} = $createlist->Label(-text => "objectClass",
                     -relief => 'groove',
                     -anchor => 'e',
                     -width => ($max+7) );
- 
+
 $createlist->windowCreate("end", -window => ${$_} );
 #
 # create data entry window
@@ -3924,7 +3924,7 @@ ${$_} = $createlist->Label(-width => 65, -anchor => 'w',
                    -text => $Creation{objectClass}->[$ptr]);
 
 $createlist->windowCreate("end", -window => ${$_} );
- 
+
 $createlist->insert("end", "\n"); # position to the next row.
 ++$ptr;
 }
@@ -3938,7 +3938,7 @@ $Creation{$_} = [];
 $Creation{$_}->[0] = "";
 
 ${$_} = $createlist->Radiobutton( -text => "", -anchor => 'w',
-                    -variable => \$NamingAttribute, -value => "$_" ) 
+                    -variable => \$NamingAttribute, -value => "$_" )
                     if ( !/objectClass/ );
 
 $createlist->windowCreate("end", -window => ${$_} );
@@ -3948,7 +3948,7 @@ ${$_} = $createlist->Label(-text => "$_",
                     -relief => 'groove',
                     -anchor => 'e',
                     -width => ($max+2) )if ( !/objectClass/ );
- 
+
 $createlist->windowCreate("end", -window => ${$_} );
 #
 # create data entry window
@@ -3956,14 +3956,14 @@ $createlist->windowCreate("end", -window => ${$_} );
 ${$_} = $createlist->Entry(-width => 65,
                    -textvariable => \$Creation{$_}->[0] );
 $createlist->windowCreate("end", -window => ${$_} );
- 
+
 $createlist->insert("end", "\n"); # position to the next row.
 }
 
 #
 # Create the Create button
 #
- 
+
 $createMe = $Global{'createWindow'}->Button(
                        -text => "CREATE ENTRY",
                        -command => \&create_entry, -font => $Global{'Font'},
@@ -4007,7 +4007,7 @@ $DN = $Creation{dn}[0];
 
 delete($Creation{dn});
 
-my @attrs = keys( %Creation ); 
+my @attrs = keys( %Creation );
 
 foreach $att ( @attrs )
 {
@@ -4027,7 +4027,7 @@ $error = dirConn();
 
 if ( $error == 1 )
 {
-  if ( defined($Global{dirConnError}) ) 
+  if ( defined($Global{dirConnError}) )
   {
   $error = "Create Entry  $Global{dirConnError}";
   ERROR(\$error);
@@ -4045,10 +4045,10 @@ $do_it = 1;
 $Global{loopCount} = 0;
 
 while ($do_it == 1 )
-{ 
- $mesg = $Global{ldap}->add($DN, attrs => \@add ); 
-   
- if ( $mesg->code ) 
+{
+ $mesg = $Global{ldap}->add($DN, attrs => \@add );
+
+ if ( $mesg->code )
  {
      if ( $mesg->code == 10 && $Global{fref} )
      {
@@ -4067,17 +4067,17 @@ while ($do_it == 1 )
         }
         else
         {
-          $rmesg = $Global{rldap}->add($DN, attrs => \@add ); 
- 
+          $rmesg = $Global{rldap}->add($DN, attrs => \@add );
+
           if ( !$rmesg->code )
           {
             &dirRUConn();
             $do_it = 0;
             last;
           }
- 
+
         }
- 
+
        } # End of foreach my $rref (@ref )
 
        if ( $do_it )
@@ -4085,7 +4085,7 @@ while ($do_it == 1 )
        #
        # All referrals have been tried, there is a major error.
        #
- 
+
         &dirRUConn();
         $errstr = "There has been a major referral error creating this DN.";
         $errstr .= "The following referrals were tried;\n";
@@ -4095,9 +4095,9 @@ while ($do_it == 1 )
         }
         ERROR($errstr);
         return;
- 
+
        } # End of if ( $do_it )
- 
+
      }
      else
      {
@@ -4116,7 +4116,7 @@ while ($do_it == 1 )
       $errstr = $mesg->code;
       ERROR($errstr);
       return;
-     } 
+     }
   }
  }
  else
@@ -4164,11 +4164,11 @@ my $objects = $Global{'ldapActionDN'};
 $Global{nb}->raise("SEARCH DISPLAY");
 
 delete($Global{'ldapActionDN'});
- 
+
 # clear the entry data display window.
 if ( $display_clear ) { &display_clear(); }
 #
-# Format and display the data associcated with the dn 
+# Format and display the data associcated with the dn
 # passed to this subroutine.
 #
 @DNs = split(/$sepChar/,$objects); # split base from dn.
@@ -4183,7 +4183,7 @@ $text = sprintf "%${max}s: %s\n",'dn',$dn;
 $list->insert("end", $text); # insert data
 #
 # For each attribute display it's data
-# 
+#
 foreach my $var (@infoKeys)
 {
 
@@ -4193,7 +4193,7 @@ foreach my $var (@infoKeys)
    # Display jpegPhoto in separate window if Tk::JPEG is used.
    #
    my $Value = decode_base64($$info{$var});
-   displayPhoto($Value, $dn ) if ( $Global{'jpeg'}) ;  
+   displayPhoto($Value, $dn ) if ( $Global{'jpeg'}) ;
    $dstring = "JpegPhoto binary data is not being displayed.\n";
    #
    #
@@ -4209,7 +4209,7 @@ foreach my $var (@infoKeys)
 
   #
   # Format data and print data into Entry Box
-  # 
+  #
   if ( $var =~ /;binary$/ )
   {
    $encoded = encode_base64($Value);
@@ -4225,7 +4225,7 @@ foreach my $var (@infoKeys)
   }
 }
 
-# position to the next row. 
+# position to the next row.
 $list->insert("end", "-----------------------------------------------------------------------------\n");
 $list->insert("end", "\n");
 
@@ -4268,7 +4268,7 @@ return if Tk::Exists($Global{'editWindow'});
 # clear the entry data display window.
 
 #
-# Format and display the data associcated with the dn 
+# Format and display the data associcated with the dn
 # passed to this subroutine.
 #
 @DNs = split(/$sepChar/,$objects); # split base from dn.
@@ -4285,7 +4285,7 @@ $info = $$data[2];   # get data hash address.
 foreach my $attrKey ( @tmp1 )
 {
  #
- # User can not edit these attributes, remove from the list of 
+ # User can not edit these attributes, remove from the list of
  # attributes to display.
  #
  if ( $attrKey =~ /createTimeStamp/i || $attrKey =~ /modifyTimeStamp/i ||
@@ -4299,11 +4299,11 @@ foreach my $attrKey ( @tmp1 )
 }
 
 #
-# create attribute label 
+# create attribute label
 #
 $text = sprintf "%${max}s",'DN';
 
-$lb = $elist->Label(-text => $text, 
+$lb = $elist->Label(-text => $text,
                     -font => $Global{'Font'},
                     -relief => 'groove',
                     -anchor => 'e',
@@ -4321,7 +4321,7 @@ $elist->insert("end", "\n"); # position to the next row.
 
 #
 # For each attribute display it's data
-# 
+#
 my $sptr = 0;
 foreach my $var (@infoKeys)
 {
@@ -4338,9 +4338,9 @@ foreach my $var (@infoKeys)
   if ( $var =~ /;binary$/ ) { next; } # We do not do binary data, yet.
 
   #
-  # create attribute action button 
+  # create attribute action button
   #
-  $ab = $elist->Button(-text => $text, 
+  $ab = $elist->Button(-text => $text,
                       -font => $Global{'Font'},
                       -borderwidth => 3,
                       -relief => 'raised' );
@@ -4349,14 +4349,14 @@ foreach my $var (@infoKeys)
 
   #
   # Format data and print data into Entry Box
-  # 
+  #
   $lb = $elist->Listbox(-width => 85, -height => 1 );
-  $elist->windowCreate("end", -window => $lb ); 
+  $elist->windowCreate("end", -window => $lb );
   $lb->insert('end', $Value );
 
   $ab->configure( -command => [ \&changeAttribute, \$ab, \$lb, \$Value, \$var, $sptr ] );
 
-  # position to the next row. 
+  # position to the next row.
   $elist->insert("end", "\n");
 
   }
@@ -4365,8 +4365,8 @@ foreach my $var (@infoKeys)
 
 $lb = $elist->Entry(-width => 85,
                     -textvariable => \$blank);
-$elist->windowCreate("end", -window => $lb ); 
-# position to the next row. 
+$elist->windowCreate("end", -window => $lb );
+# position to the next row.
 $elist->insert("end", "\n");
 
 }
@@ -4391,15 +4391,15 @@ $Global{'tmpDELETE'} = {};
 $Global{'tmpREPLACE'} = {};
 
 $Global{'changeWindow'} = MainWindow->new;
- 
+
 $Global{'changeWindow'}->title("ATTRIBUTE MODIFICATION WINDOW");
- 
+
 $Global{'changeWindow'}->geometry("+$x+$y");
- 
+
 #
 # Create process Cancel button
 #
- 
+
 $Global{'changeWindow'}->Button(-text => "CANCEL ATTRIBUTE EDIT",
       -command => \&change_cancel,
       -font => $Global{'Font'}, -borderwidth => 5 )
@@ -4407,82 +4407,82 @@ $Global{'changeWindow'}->Button(-text => "CANCEL ATTRIBUTE EDIT",
 #
 # Create frame for clear buttons.
 #
- 
+
 $acframe = $Global{'changeWindow'}->Frame()
       ->pack( -fill => "both", -side => "bottom", -padx => 5, -pady => 2);
- 
+
 #
 # Create Clear Data
 #
- 
+
 $acframe -> Button(-text => "     ACCEPT DATA CHANGE     ",
       -command =>  \&makeChanges,
       -font => $Global{'Font'},
       -borderwidth => 3 )
       ->pack( -fill => 'both' );
- 
+
 #
 # Create list frame.
 #
- 
+
 $outerframe = $Global{'changeWindow'}->Frame()
       ->pack( -fill => "both", -side => "top", -padx => 5, -pady => 2,
       -expand => 1);
- 
+
 #
 # Create data frame.
 #
- 
+
 $alframe = $outerframe->LabFrame(-label => "ATTRIBUTE DATA",
       -labelside => "acrosstop" )
       ->pack( -fill => "both", -side => "top", -padx => 5, -pady => 2,
       -expand => 1);
- 
+
 #
 # Create a Text Box that will actually contain the
 # returned directory data.
 #
- 
-$attrlist = $alframe ->Text( -width => 80, -height => 1, 
+
+$attrlist = $alframe ->Text( -width => 80, -height => 1,
       -wrap => 'none',
       -font => $Global{'Font'}  );
- 
+
 $attrlist->pack(-fill => "both", -expand => 1 );
-$attrlist->insert('end', $$Value); 
+$attrlist->insert('end', $$Value);
 
 if ( $Global{'add_new_attribute'} )
 {
 #
 # Create data frame.
 #
- 
+
 $Global{'newAttributeFrame'} = $outerframe->LabFrame(
       -label => "NEW ATTRBUTE NAME",
       -labelside => "acrosstop" )
       ->pack( -fill => "both", -side => "top", -padx => 5, -pady => 2,
       -expand => 1);
- 
+
 #
 # Create a Text Box that will actually contain the
 # returned directory data.
 #
- 
- 
-$Global{'newAttribute'} = $Global{'newAttributeFrame'}->Text( 
-      -width => 80, -height => 1, 
+
+
+$Global{'newAttribute'} = $Global{'newAttributeFrame'}->Text(
+      -width => 80, -height => 1,
       -wrap => 'none',
       -font => $Global{'Font'}  );
- 
+
 $Global{'newAttribute'}->pack(-fill => "both", -expand => 1 );
- 
+
 $Global{'newAttributeReady'} = 1 ;
 
 }
- 
+
 #
 # Create process Add button
 #
- 
+
 $Global{'changeWindow'}->Button(-text => "ADD",
       -command => [\&add_data, $attr, $Value, \$attrlist],
       -font => $Global{'Font'}, -borderwidth => 5 )
@@ -4494,7 +4494,7 @@ if ( !defined($Global{'add_new_attribute'}) )
 #
 # Create process Delete button
 #
- 
+
 $Global{'changeWindow'}->Button(-text => "DELETE",
       -command => [\&delete_data, $attr, $Value],
       -font => $Global{'Font'}, -borderwidth => 5 )
@@ -4504,7 +4504,7 @@ $Global{'changeWindow'}->Button(-text => "DELETE",
 #
 # Create process Replace button
 #
- 
+
 $Global{'changeWindow'}->Button(-text => "REPLACE",
       -command => [\&replace_data, $attr, $Value,\$attrlist, $mv],
       -font => $Global{'Font'}, -borderwidth => 5 )
@@ -4516,22 +4516,22 @@ $Global{'multi'} = [];
 
 }
 else { return; }
- 
+
 sub delete_data {
 my ( $attr, $Value ) = @_;
 #
-# 
+#
 #
 $Global{'tmpDELETE'}{$$attr} = $$Value;
- 
+
 } # End of delete_data subroutine
- 
- 
+
+
 sub replace_data {
 my ( $attr, $Value, $tbox,$mv ) = @_;
 #
 # Replace this attributes value.
-# But what if this is a multi-valued attribute.  
+# But what if this is a multi-valued attribute.
 #
 if ( $$Global{'multi'}[$mv] )
 {
@@ -4548,14 +4548,14 @@ else
 $Global{'tmpREPLACE'}{$$attr} = $$tbox->get('1.0','1.end');
 
 }
- 
+
 } # End of replace_data subroutine
- 
+
 sub add_data {
 my ( $attr, $Value, $tbox ) = @_;
 my $newAttribute;
 if ( $Global{'newAttributeReady'} )
-{ 
+{
 #
 # add new attribute and it's value
 #
@@ -4573,16 +4573,16 @@ else
 $Global{'tmpADD'}{$$attr} = $$tbox->get('1.0','1.end');
 
 }
- 
+
 } # End of add_data subroutine
- 
-sub makeChanges 
+
+sub makeChanges
 {
 
 my $tmp = $Global{'tmpADD'};
 my @Keys = sort(keys(%$tmp));
 
-if ( @Keys ) 
+if ( @Keys )
 {
 foreach my $var ( @Keys)
 {
@@ -4592,15 +4592,15 @@ $Global{'add'}{$var} = $Global{'tmpADD'}{$var};
 
 $Global{tmpADD} = {};
 
-$Global{'newAttribute'}->destroy 
+$Global{'newAttribute'}->destroy
        if Tk::Exists($Global{'newAttribute'});
-$Global{'newAttributeFrame'}->destroy 
+$Global{'newAttributeFrame'}->destroy
        if Tk::Exists($Global{'newAttributeFrame'});
-delete( $Global{'newAttributeReady'} ) 
+delete( $Global{'newAttributeReady'} )
        if ( defined($Global{'newAttributeReady'} ));
-delete( $Global{'newAttribute'}) 
+delete( $Global{'newAttribute'})
        if ( defined($Global{'newAttribute'} ));
-delete( $Global{'newAttributeFrame'}) 
+delete( $Global{'newAttributeFrame'})
        if ( defined($Global{'newAttributeFrame'} ));
 
 }
@@ -4609,7 +4609,7 @@ $tmp = $Global{'tmpDELETE'};
 
 @Keys = sort(keys(%$tmp));
 
-if ( @Keys ) 
+if ( @Keys )
 {
 foreach my $var ( @Keys)
 {
@@ -4625,7 +4625,7 @@ $Global{tmpDELETE} = {};
 $tmp = $Global{'tmpREPLACE'};
 @Keys = sort(keys(%$tmp));
 
-if ( @Keys ) 
+if ( @Keys )
 {
 foreach my $var ( @Keys)
 {
@@ -4639,16 +4639,16 @@ $Global{tmpREPLACE} = {};
 $Global{'changeWindow'}->destroy if Tk::Exists($Global{'changeWindow'});
 
 } # End of clear subroutine
- 
+
 sub change_cancel
 {
- 
+
 $Global{tmpADD} = {};
 $Global{tmpDELETE} = {};
 $Global{tmpREPLACE} = {};
 $Global{'multi'} = [];
 $Global{'changeWindow'}->destroy if Tk::Exists($Global{'changeWindow'});
- 
+
 } # End of cancel subroutine
 
 } # End of subroutine changeAttribute
@@ -4675,7 +4675,7 @@ return;
 my $objects = $Global{'ldapActionDN'};
 
 &ldapActionCancel();
- 
+
 @DNs = split(/$sepChar/,$objects); # split base from dn.
 $error = 0;
 
@@ -4686,7 +4686,7 @@ $error = dirConn();
 
 if ( $error == 1 )
 {
-  if ( defined($Global{dirConnError}) ) 
+  if ( defined($Global{dirConnError}) )
   {
   $error = "ldapActionDelete $Global{dirConnError}";
   ERROR(\$error);
@@ -4705,12 +4705,12 @@ $Global{loopCount} = 0;
 $okay = 0;
 
 while ($do_it == 1 )
-{ 
- $mesg = $Global{ldap}->delete($DNs[1]); 
-   
- if ( $mesg->code ) 
+{
+ $mesg = $Global{ldap}->delete($DNs[1]);
+
+ if ( $mesg->code )
  {
-   if ( $mesg->code == 10 && $Global{fref} ) 
+   if ( $mesg->code == 10 && $Global{fref} )
    {
    #
    #  Being refer'ed to another directory server.
@@ -4727,7 +4727,7 @@ while ($do_it == 1 )
     }
     else
     {
-      $rmesg = $Global{rldap}->delete($DNs[1]); 
+      $rmesg = $Global{rldap}->delete($DNs[1]);
 
       if ( !$rmesg->code )
       {
@@ -4735,29 +4735,29 @@ while ($do_it == 1 )
         $do_it = 0;
         last;
       }
- 
+
     }
- 
+
    } # End of foreach my $rref (@ref )
 
-   if ( $do_it ) 
+   if ( $do_it )
    {
    #
    # All referrals have been tried, there is a major error.
    #
- 
+
     &dirRUConn();
     $errstr = "There has been a major referral error deleteing this DN.";
     $errstr .= "The following referrals were tried;\n";
     foreach  my $rref (@referral )
-    { 
+    {
       $errstr .= "$rref\n";
     }
     ERROR($errstr);
     return;
- 
+
    } # End of if ( $do_it )
- 
+
    }  # End of if ( $mesg->code == 10 && $Global{fref} )
    else
    {
@@ -4778,7 +4778,7 @@ while ($do_it == 1 )
     $errstr = $mesg->code;
     ERROR($errstr);
     return;
-   } 
+   }
    } # End of else for if ( $mesg->code == 10 && $Global{fref} )
  }   # End of if ( $mesg->code )
  else
@@ -4816,14 +4816,14 @@ my $type;
 my $task;
 my $rresult;
 my @referral;
- 
+
 $error = 0;
 
 if ( !defined($Global{ldap}) )
 {
- 
+
 $error = dirConn();
- 
+
 if ( $error == 1 )
 {
   if ( defined($Global{dirConnError}) )
@@ -4838,14 +4838,14 @@ if ( $error == 1 )
   return;
   }
 }
- 
+
 }
 
 @entry = ();
 
   if ( $Global{createLdifFile} && -f $Global{createLdifFile})
   {
-       $ldif = Net::LDAP::LDIF->new( "$Global{createLdifFile}", "r", 
+       $ldif = Net::LDAP::LDIF->new( "$Global{createLdifFile}", "r",
                onerror => 'undef' );
 
        if ( $ldif->error() )
@@ -4858,14 +4858,14 @@ if ( $error == 1 )
 
        while( not $ldif->eof() ) {
           $entry = $ldif->read_entry();
-          if ( $ldif->error() ) 
+          if ( $ldif->error() )
           {
              $mesg = "LDIF create entry error msg: " . $ldif->error() . "\n";
              $mesg .= "Error lines:\n" . $ldif->error_lines() . "\n";
              ERROR(\$mesg);
 
           }
-          else 
+          else
           {
 
            $op = $$entry{changetype};
@@ -4893,7 +4893,7 @@ if ( $error == 1 )
 
             if ( $mesg->code )
             {
- 
+
             if ( $mesg->code == 10 && $Global{fref} )
             {
              #
@@ -4901,7 +4901,7 @@ if ( $error == 1 )
              #
              @referral = $mesg->referrals();
              foreach my $rref (@referral )
-             { 
+             {
                 print "LDAP Referral: $rref \n" if $debug;
                 $rresult = &dirRConn($rref);
                 if ( $rresult != 0 )
@@ -4913,7 +4913,7 @@ if ( $error == 1 )
                 {
                   $task = '$entry->update($Global{rldap})';
                   $rmesg = eval $task;
- 
+
                   if ( !$rmesg->code )
                   {
                     &dirRUConn();
@@ -4921,7 +4921,7 @@ if ( $error == 1 )
                     last;
                   }
                 }
- 
+
              } # End of foreach my $rref (@ref )
 
              if ( $do_it )
@@ -4929,7 +4929,7 @@ if ( $error == 1 )
               #
               # All referrals have been tried, there is a major error.
               #
- 
+
               &dirRUConn();
               $errstr = "There has been a major referral updating this DN.";
               $errstr .= "The following referrals were tried;\n";
@@ -4939,13 +4939,13 @@ if ( $error == 1 )
               }
               ERROR($errstr);
               return;
- 
+
               } # End of if ( $do_it )
             } # End of if ( $mesg->code == 10 && $Global{fref} )
             else
             {
                print "Delete check busy now\n" if ( $debug );
- 
+
               #
               # There was an error, check for dsa busy
               # error.
@@ -4971,13 +4971,13 @@ if ( $error == 1 )
               #
               $do_it = 0;
             } # End of else for if ( $mesg->code == 10 && $Global{fref} )
- 
+
            } # End of while ( $do_it )
           } # End of else for if ( $ldif->error() )
        }
 
        $ldif->done();
-     
+
       @entry = undef;
   }
   else
@@ -5006,16 +5006,16 @@ my $f;
 my $ldif;
 my @entry;
 my $do_it;
- 
+
 &ldapActionCancel();
- 
+
 $error = 0;
 
 if ( !defined($Global{ldap}) )
 {
- 
+
 $error = dirConn();
- 
+
 if ( $error == 1 )
 {
   if ( defined($Global{dirConnError}) )
@@ -5030,7 +5030,7 @@ if ( $error == 1 )
   return;
   }
 }
- 
+
 }
 
 @entry = ();
@@ -5040,7 +5040,7 @@ $mesg = $Global{ldap}->search(
   filter => $Global{filter},
   attrs  => $Global{att_wanted},
 );
- 
+
 if ( $mesg->code && $mesg->code != 48 )
 {
    ERROR($mesg->code);
@@ -5051,24 +5051,24 @@ if ( $mesg->count )
   if ( $Global{ldifFile} )
   {
     @entry = $mesg->all_entries;
- 
+
        if ( $Global{ldif} )
        {
-       $ldif = Net::LDAP::LDIF->new( "$Global{ldifFile}", "w", 
+       $ldif = Net::LDAP::LDIF->new( "$Global{ldifFile}", "w",
                onerror => 'undef' );
        $ldif->write(@entry, -encode => "base64");
        $ldif->done();
        }
        elsif ( $Global{xml} )
        {
-       open(FXML, ">$Global{'ldifFile'}");  
+       open(FXML, ">$Global{'ldifFile'}");
        my $dsml = Net::LDAP::DSML->new(output => *FXML, pretty_print => 1);
        $dsml->write_entry(@entry);
-       $dsml->end_dsml;        
+       $dsml->end_dsml;
        close(FXML);
 
        }
-       else 
+       else
        {
        print "saveldif ",$Global{ldif}, "\n";
        print "saveXml ",$Global{xml}, "\n";
@@ -5079,7 +5079,7 @@ if ( $mesg->count )
           if ( defined( $msgbox) );
 
        }
-     
+
       @entry = undef;
   }
   else
@@ -5114,7 +5114,7 @@ my $f;
 my $ldif;
 my @entry;
 my $do_it;
- 
+
 if ( !$Global{'ldapActionDN'} )
 {
 &ldapActionCancel();
@@ -5123,15 +5123,15 @@ return;
 my $objects = $Global{'ldapActionDN'};
 
 &ldapActionCancel();
- 
+
 @DNs = split(/$sepChar/,$objects); # split base from dn.
 $error = 0;
 
 if ( !defined($Global{ldap}) )
 {
- 
+
 $error = dirConn();
- 
+
 if ( $error == 1 )
 {
   if ( defined($Global{dirConnError}) )
@@ -5146,7 +5146,7 @@ if ( $error == 1 )
   return;
   }
 }
- 
+
 }
 
 @entry = ();
@@ -5156,7 +5156,7 @@ $mesg = $Global{ldap}->search(
   filter => $Global{filter},
   attrs  => $Global{att_wanted},
 );
- 
+
 if ( $mesg->code && $mesg->code != 48 )
 {
    ERROR($mesg->code);
@@ -5167,7 +5167,7 @@ if ( $mesg->count )
   if ( $Global{ldifFile} )
   {
     @entry = $mesg->all_entries;
- 
+
     foreach $entry (@entry)
     {
 
@@ -5176,21 +5176,21 @@ if ( $mesg->count )
      {
        if ( $Global{ldif} )
        {
-       $ldif = Net::LDAP::LDIF->new( "$Global{ldifFile}", "w", 
+       $ldif = Net::LDAP::LDIF->new( "$Global{ldifFile}", "w",
                onerror => 'undef' );
        $ldif->write($entry, -encode => "base64");
        $ldif->done();
        }
        elsif ( $Global{xml} )
        {
-       open(FXML, ">$Global{'ldifFile'}");  
+       open(FXML, ">$Global{'ldifFile'}");
        my $dsml = Net::LDAP::DSML->new(output => *FXML, pretty_print => 1);
        $dsml->write_entry($entry);
-       $dsml->end_dsml;        
+       $dsml->end_dsml;
        close(FXML);
 
        }
-       else 
+       else
        {
        print "saveldif ",$Global{ldif}, "\n";
        print "saveXml ",$Global{xml}, "\n";
@@ -5203,7 +5203,7 @@ if ( $mesg->count )
        }
 
      }
-     else 
+     else
      {
        $entry = undef;
      }
@@ -5246,7 +5246,7 @@ my $do_it;
 my $rresult;
 my @referral;
 
-if ( $Global{'Rename'} == -1 ) 
+if ( $Global{'Rename'} == -1 )
 {
 return;
 }
@@ -5258,7 +5258,7 @@ $error = dirConn();
 
 if ( $error == 1 )
 {
-  if ( defined($Global{dirConnError}) ) 
+  if ( defined($Global{dirConnError}) )
   {
   $error = "ldapActionRename $Global{dirConnError}";
   ERROR(\$error);
@@ -5270,20 +5270,20 @@ if ( $error == 1 )
   }
 }
 
-} 
- 
+}
+
 $do_it = 1;
 $Global{loopCount} = 0;
- 
+
 while ($do_it == 1 )
 {
 
-$mesg = $Global{ldap}->moddn($Global{'RenameDN'}, 
-                     newrdn => $Global{'newrdn'}, 
-                     deleteoldrdn => $Global{'deleteoldrdn'}, 
-                     newsuperior => $Global{'newsuperior'} ); 
+$mesg = $Global{ldap}->moddn($Global{'RenameDN'},
+                     newrdn => $Global{'newrdn'},
+                     deleteoldrdn => $Global{'deleteoldrdn'},
+                     newsuperior => $Global{'newsuperior'} );
 
-if ( $mesg->code ) 
+if ( $mesg->code )
 {
   if ( $mesg->code == 10 && $Global{fref} )
   {
@@ -5302,27 +5302,27 @@ if ( $mesg->code )
       }
       else
       {
- 
-        $rmesg = $Global{rldap}->moddn($Global{'RenameDN'}, 
-                     newrdn => $Global{'newrdn'}, 
-                     deleteoldrdn => $Global{'deleteoldrdn'}, 
-                     newsuperior => $Global{'newsuperior'} ); 
- 
+
+        $rmesg = $Global{rldap}->moddn($Global{'RenameDN'},
+                     newrdn => $Global{'newrdn'},
+                     deleteoldrdn => $Global{'deleteoldrdn'},
+                     newsuperior => $Global{'newsuperior'} );
+
       if ( !$rmesg->code )
        {
          &dirRUConn();
          $do_it = 0;
          last;
        }
-      } 
-    } # End of foreach my $rref (@ref ) 
+      }
+    } # End of foreach my $rref (@ref )
 
    if ( $do_it )
    {
    #
    # All referrals have been tried, there is a major error.
    #
- 
+
     &dirRUConn();
     $errstr = "There has been a major referral error renaming this DN.";
     $errstr .= "The following referrals were tried;\n";
@@ -5332,9 +5332,9 @@ if ( $mesg->code )
     }
     ERROR($errstr);
     return;
- 
+
    } # End of if ( $do_it )
- 
+
   } # End of if ( $mesg->code == 10 && $Global{fref} )
   else
   {
@@ -5355,7 +5355,7 @@ if ( $mesg->code )
     return;
    }
   }
- } # End of if ( $mesg->code ) 
+ } # End of if ( $mesg->code )
  else
  {
  #
@@ -5373,12 +5373,12 @@ $Global{'searchHList'}->delete('all') if Tk::Exists($Global{'searchHList'});
 $Global{nb}->raise('SEARCH');
 
 } # End of subroutine ldapActionRename
- 
+
 #
 # Create Rename DATA  Window
 #
- 
-sub getRenameData 
+
+sub getRenameData
 {
 $Global{'newsuperior'} = "";
 $Global{'newrdn'} = "";
@@ -5401,7 +5401,7 @@ return;
 my $objects = $Global{'ldapActionDN'};
 
 &ldapActionCancel();
- 
+
 @DNs = split(/$sepChar/,$objects); # split base from dn.
 
 $Global{'RenameDN'} = $DNs[1];
@@ -5413,44 +5413,44 @@ $rdn = shift(@rdnData);
 foreach my $var (@rdnData)
 {
 $super .= $var . ",";
-} 
+}
 
 chop($super); # get rid of trailing comma
 
 #
 # Create Data Window
 #
- 
+
 $Global{'renameWindow'} = MainWindow->new;
- 
+
 $Global{'renameWindow'}->title("MODDN INFORMATION");
- 
+
 $Global{'renameWindow'}->geometry("+$x+$y");
 #
 # Create process accept button
 #
-$Global{'renameWindow'}->Button( -text => "ACCEPT", -command => \&rdnAccept, 
+$Global{'renameWindow'}->Button( -text => "ACCEPT", -command => \&rdnAccept,
            -font => $Global{'Font'}, -borderwidth => 3 )
            -> pack(-side => "bottom", -padx => 5, -pady => 5 ) ;
- 
+
 #
 # Create process cancel button
 #
-$Global{'renameWindow'}->Button(-text => "CANCEL", -command => \&rdnCancel, 
+$Global{'renameWindow'}->Button(-text => "CANCEL", -command => \&rdnCancel,
            -font => $Global{'Font'}, -borderwidth => 3)
            -> pack(-side => "top", -padx => 5, -pady => 5 ) ;
- 
+
 my $newrdnframe = $Global{'renameWindow'}->LabFrame(-label => "Newrdn",
       -labelside => "acrosstop")
       ->pack( -fill => "both", -side => "top", -padx => 5, -pady => 5 );
- 
+
 #
 # Create newrdn text box.
 #
- 
+
 my $t1 = $newrdnframe->Entry(-textvariable => \$Global{'newrdn'}, -width => 25 )
       -> pack(-fill => 'x');
- 
+
 $t1->insert("end", $rdn);
 
 #
@@ -5459,7 +5459,7 @@ $t1->insert("end", $rdn);
 #
 
 $delrdn = $Global{'renameWindow'} -> Checkbutton(-text => "DELETE OLD RDN DATA",
-      -variable =>  \$Global{'deleteoldrdn'}, -onvalue => 1, -offvalue => 0, 
+      -variable =>  \$Global{'deleteoldrdn'}, -onvalue => 1, -offvalue => 0,
       -font => $Global{'Font'} )
       -> pack(-anchor => 'sw' );
 
@@ -5468,29 +5468,29 @@ $delrdn->select();
 my $newsuperiorframe = $Global{'renameWindow'}->LabFrame(-label => "Newsuperior RDN",
       -labelside => "acrosstop")
       ->pack( -fill => "both", -side => "top", -padx => 5, -pady => 5 );
- 
+
 #
 # Create Password Entry text box.
 #
- 
-my $t2 = $newsuperiorframe->Entry( -textvariable => \$Global{'newsuperior'}, 
+
+my $t2 = $newsuperiorframe->Entry( -textvariable => \$Global{'newsuperior'},
                     -width => 25, -font => $Global{'Font'} )
                     -> pack(-fill => 'x');
- 
+
 $t2->insert("end", $super);
 
 sub rdnCancel{
- 
+
 $Global{'renameWindow'}->destroy() if Tk::Exists($Global{'renameWindow'});
-delete($Global{'renameWindow'}); 
+delete($Global{'renameWindow'});
 delete( $Global{'newsuperior'});
 delete( $Global{'newrdn'});
 delete( $Global{'deleteoldrdn'} );
 delete( $Global{'RenameDN'} );
 } # End of cancel subroutine
- 
-sub rdnAccept{ 
- 
+
+sub rdnAccept{
+
 #
 # Clean up data and close windows, forces another search to
 # get valid new data.
@@ -5498,11 +5498,11 @@ sub rdnAccept{
 
 $Global{'renameWindow'}->destroy() if Tk::Exists($Global{'renameWindow'});
 $Global{'searchHistWindow'}->destroy if Tk::Exists($Global{'searchHistWindow'});
-$Global{'renameWindow'} = undef(); 
-$Global{'searchHistWindow'} = undef(); 
+$Global{'renameWindow'} = undef();
+$Global{'searchHistWindow'} = undef();
 
 &ldapActionRename();  # Rename the entry in the directory
- 
+
 delete( $Global{'newsuperior'});
 delete( $Global{'newrdn'});
 delete( $Global{'deleteoldrdn'} );
@@ -5514,7 +5514,7 @@ delete($Global{'index'}) if ( defined($Global{'index'}));
 
 } # End of getRenameData subroutine
 
-sub display_clear 
+sub display_clear
 {
 
 #
@@ -5524,7 +5524,7 @@ sub display_clear
 $list->delete("1.0", "end");
 
 } # End of clear subroutine
- 
+
 
 sub displayEdit()
 {
@@ -5550,8 +5550,8 @@ $Global{'editWindow'}->geometry("+$x+$y");
 # Create process Exit button
 #
 
-$Global{'editWindow'}->Button(-text => "CANCEL ENTRY EDIT", 
-                    -command => \&edit_cancel, 
+$Global{'editWindow'}->Button(-text => "CANCEL ENTRY EDIT",
+                    -command => \&edit_cancel,
                     -font => $Global{'Font'}, -borderwidth => 5 )
                     -> pack(-fill => "both", -padx => 2, -pady => 2 ) ;
 
@@ -5567,9 +5567,9 @@ $ecframe = $Global{'editWindow'}->Frame()
 # Create Clear Data
 #
 
-$ecframe -> Button(-text => "     CHANGE DATA     ", 
+$ecframe -> Button(-text => "     CHANGE DATA     ",
      -command =>  \&changeEntry, -font => $Global{'Font'},
-     -borderwidth => 3 ) 
+     -borderwidth => 3 )
      ->pack( -fill => 'both' );
 
 #
@@ -5582,21 +5582,21 @@ $elframe = $Global{'editWindow'}->LabFrame(-label => "ENTRY DATA",
       -expand => 1);
 
 #
-# Create a ROText Box that will actually contain the 
+# Create a ROText Box that will actually contain the
 # returned directory data.
 #
 
 $elist = $elframe ->Scrolled('Text', -scrollbars => 'se',
-        -width => 80, -height => 20, -wrap => 'none', 
+        -width => 80, -height => 20, -wrap => 'none',
         -font => $Global{'Font'}  );
 
 $elist->pack(-fill => "both", -expand => 1 );
 
- 
+
 #
 # Create process add new attribute button
 #
- 
+
 $elframe->Button(-text => "ADD\nATTRIBUTE",
       -command => \&add_new_attribute,
       -font => $Global{'Font'}, -borderwidth => 5 )
@@ -5607,11 +5607,11 @@ $elframe->Button(-text => "ADD\nATTRIBUTE",
 
 sub edit_cancel{
 
-delete($Global{'add'}); 
-delete($Global{'delete'}); 
-delete($Global{'replace'}); 
+delete($Global{'add'});
+delete($Global{'delete'});
+delete($Global{'replace'});
 $Global{'editWindow'}->destroy if Tk::Exists($Global{'editWindow'});
- 
+
 } # End of cancel subroutine
 
 } # End of subroutine displayEdit
@@ -5629,7 +5629,7 @@ delete($Global{'add_new_attribute'});
 #
 # Execute any LDAP add, delete, or replace changes.
 #
-sub changeEntry 
+sub changeEntry
 {
 my $errstr;
 my $mesg;
@@ -5643,10 +5643,10 @@ if ( !defined($Global{ldap}) )
 {
 
 $error = dirConn();
- 
+
 if ( $error == 1 )
 {
-  if ( defined($Global{dirConnError}) ) 
+  if ( defined($Global{dirConnError}) )
   {
   $error = "changeEntry $Global{dirConnError}";
   ERROR(\$error);
@@ -5657,7 +5657,7 @@ if ( $error == 1 )
   }
   return;
 }
- 
+
 }
 #
 # Execute any LDAP add changes.
@@ -5667,12 +5667,12 @@ if ( defined($Global{'add'}) )
 
 $do_it = 1;
 $Global{loopCount} = 0;
- 
+
 while ($do_it == 1 )
 {
 
 $mesg = $Global{ldap}->modify( $Global{'entryDN'}, add => $Global{'add'});
- 
+
 if ( $mesg->code )
 {
 
@@ -5680,15 +5680,15 @@ if ( $mesg->code )
    {
     #
     #  Being refer'ed to another directory server.
-    #  
-    # 
+    #
+    #
    @referral = $mesg->referrals();
- 
+
    foreach my $rref (@referral )
    {
     print "LDAP Referral: $rref \n" if $debug;
     $rresult = &dirRConn($rref);
- 
+
     if ( $rresult != 0 )
     {
     print "Referral connect error, trying next now\n" if ( $debug );
@@ -5697,16 +5697,16 @@ if ( $mesg->code )
     else
     {
       $rmesg = $Global{rldap}->modify( $Global{'entryDN'}, add => $Global{'add'});
- 
+
       if ( !$rmesg->code )
       {
         &dirRUConn();
         $do_it = 0;
         last;
       }
- 
+
     }
- 
+
    } # End of foreach my $rref (@ref )
 
    if ( $do_it )
@@ -5714,7 +5714,7 @@ if ( $mesg->code )
    #
    # All referrals have been tried, there is a major error.
    #
- 
+
     &dirRUConn();
     $errstr = "There has been a major referral error adding an attribute to this DN.";
     $errstr .= "The following referrals were tried;\n";
@@ -5724,7 +5724,7 @@ if ( $mesg->code )
     }
     ERROR($errstr);
     return;
- 
+
    } # End of if ( $do_it )
 
    }
@@ -5770,12 +5770,12 @@ if ( defined($Global{'delete'}) )
 
 $do_it = 1;
 $Global{loopCount} = 0;
- 
+
 while ($do_it == 1 )
 {
 
 $mesg = $Global{ldap}->modify( $Global{'entryDN'}, delete => $Global{'delete'});
- 
+
 if ( $mesg->code )
 {
 
@@ -5783,14 +5783,14 @@ if ( $mesg->code )
    {
     #
     #  Being refer'ed to another directory server.
-    #  
-    # 
+    #
+    #
    @referral = $mesg->referrals();
- 
+
    foreach my $rref (@referral )
    {
     $rresult = &dirRConn($rref);
- 
+
     if ( $rresult != 0 )
     {
       print "Referral connect error, trying next now\n" if ( $debug );
@@ -5799,16 +5799,16 @@ if ( $mesg->code )
     else
     {
       $rmesg = $Global{rldap}->modify( $Global{'entryDN'}, delete => $Global{'delete'});
- 
+
       if ( !$rmesg->code )
       {
         &dirRUConn();
         $do_it = 0;
         last;
       }
- 
+
     }
- 
+
    } # End of foreach my $rref (@ref )
 
     if ( $do_it )
@@ -5816,7 +5816,7 @@ if ( $mesg->code )
     #
     # All referrals have been tried, there is a major error.
     #
- 
+
      &dirRUConn();
      $errstr = "There has been a major referral error deleteing an attribute on this DN.";
      $errstr .= "The following referrals were tried;\n";
@@ -5826,7 +5826,7 @@ if ( $mesg->code )
      }
      ERROR($errstr);
      return;
- 
+
     } # End of if ( $do_it )
 
    }
@@ -5872,12 +5872,12 @@ if ( defined($Global{'replace'}) )
 
 $do_it = 1;
 $Global{loopCount} = 0;
- 
+
 while ($do_it == 1 )
 {
 
 $mesg = $Global{ldap}->modify( $Global{'entryDN'}, replace => $Global{'replace'});
- 
+
 if ( $mesg->code )
 {
 
@@ -5885,14 +5885,14 @@ if ( $mesg->code )
    {
     #
     #  Being refer'ed to another directory server.
-    #  
-    # 
+    #
+    #
    @referral = $mesg->referrals();
- 
+
    foreach my $rref (@referral )
    {
     $rresult = &dirRConn($rref);
- 
+
     if ( $rresult != 0 )
     {
       print "Referral connect error, trying next now\n" if ( $debug );
@@ -5901,16 +5901,16 @@ if ( $mesg->code )
     else
     {
       $rmesg = $Global{rldap}->modify( $Global{'entryDN'}, replace => $Global{'replace'});
- 
+
       if ( !$rmesg->code )
       {
         &dirRUConn();
         $do_it = 0;
         last;
       }
- 
+
     }
- 
+
    } # End of foreach my $rref (@ref )
 
    if ( $do_it )
@@ -5918,7 +5918,7 @@ if ( $mesg->code )
    #
    # All referrals have been tried, there is a major error.
    #
- 
+
     &dirRUConn();
     $errstr = "There has been a major referral error replacing an attribute on this DN.";
     $errstr .= "The following referrals were tried;\n";
@@ -5928,12 +5928,12 @@ if ( $mesg->code )
     }
     ERROR($errstr);
     return;
- 
+
    } # End of if ( $do_it )
- 
- 
+
+
    }
-   else 
+   else
    {
    #
    # There was an error, check for dsa busy
@@ -6015,7 +6015,7 @@ $error = dirConn();
 
 if ( $error )
 {
-  if ( defined($Global{dirConnError}) ) 
+  if ( defined($Global{dirConnError}) )
   {
   $error = "rootDSE $Global{dirConnError}";
   ERROR(\$error);
@@ -6030,7 +6030,7 @@ if ( $error )
 }
 my $root = $Global{ldap}->root_dse();
 
-my @Attributes = ( qw(subschemaSubentry namingContexts supportedLDAPVersion 
+my @Attributes = ( qw(subschemaSubentry namingContexts supportedLDAPVersion
                     supportedControl supportedExtension altServer supportedSASLMechanisms) );
 
 if ( !defined($root) )
@@ -6044,27 +6044,27 @@ if ( !defined($root) )
 # Set up the Tk windows.
 #
 #
- 
+
 if ( ! Exists($Global{'rootWindow'} ) )
 {
    $Global{'rootWindow'} = MainWindow->new();
    $Global{'rootWindow'}->title("ROOT DSE ENTRY");
-   $Global{'rootWindow'}->geometry("+$x+$y"); 
+   $Global{'rootWindow'}->geometry("+$x+$y");
 }
 
 #
 # Create label box
 #
-# 
+#
 if ( !Exists($Global{'labelDSE'}) )
 {
  $Global{'labelDSE'} = $Global{'rootWindow'}->Label()->pack;
 }
- 
+
 #
 # Create process Exit button
 #
- 
+
 $Global{'ebuttonDSE'} = $Global{'rootWindow'}->Button(
               -text => "CLOSE ROOT DSE DISPLAY WINDOW",
               -command => \&root_cancel, -font => $Global{'Font'},
@@ -6072,12 +6072,12 @@ $Global{'ebuttonDSE'} = $Global{'rootWindow'}->Button(
               -> pack(-fill => "both", -padx => 2, -pady => 2 )
               if ( Exists($Global{'rootWindow'} ) &&
                    !Exists($Global{'ebuttonDSE'} ) );
- 
+
 #
 # Create list box, this is where the selected objectclass data will
 # be displayed.
 #
- 
+
 if ( !Exists($Global{'listDSE'}) )
 {
  $Global{'listDSE'} = $Global{'rootWindow'}->Scrolled('ROText',
@@ -6091,12 +6091,12 @@ else
  # clear the list box
  #
  $Global{'listDSE'}->delete("1.0", "end");
-} 
+}
 
 foreach $attr (@Attributes)
 {
 
- $base = $root->get_value( $attr, asref => 1); 
+ $base = $root->get_value( $attr, asref => 1);
  foreach (@$base)
  {
  $Global{'listDSE'}->insert("end", "$attr:  $_\n");
@@ -6142,27 +6142,27 @@ tklkup -  A script to do LDAP directory lookups, edits, and displaying directory
 =head1 SYNOPSIS
 
 
-This script is used to lookup and edit information from a LDAP 
-directory server.  It is GUI based with several buttons for 
+This script is used to lookup and edit information from a LDAP
+directory server.  It is GUI based with several buttons for
 selecting directory servers, search bases, attributes and
 for enabling the Directory Schema Search window.
 
-This script has been tested on Solaris, RedHat 7.3 Linux, 
-Mandrake 6.5 Linux, ActiveState Perl 628 and 5.8.7, but should work with 
-any system that has PERL and the required modules installed in 
+This script has been tested on Solaris, RedHat 7.3 Linux,
+Mandrake 6.5 Linux, ActiveState Perl 628 and 5.8.7, but should work with
+any system that has PERL and the required modules installed in
 it.
 
 Execute tklkup -h to view the list of input options and their
 usage.
 
 The SSL connection has been tested on Solaris, RedHat 7.3, and
-Mandrake 6.5 Linux.  The SSL connection from a Microsoft Windows 
+Mandrake 6.5 Linux.  The SSL connection from a Microsoft Windows
 system is not available at this time.  If the user has SSL on
 the Microsoft Windows system this can easily changed by
 modifying the tklkup program, in subroutine dirConn comment out
 the 6 lines of code that detects the platform type of MSWin32.
 
-There are 2 files associated with the tklkup program in this 
+There are 2 files associated with the tklkup program in this
 tar file; dot.tklkup, and tklkup.
 
 About the files.
@@ -6171,16 +6171,16 @@ About the files.
 
 =item dot.tklkup
 
-dot.tklkup - This is the initialization file that should be put 
-into each users home directory as I<.tklkup>.  
+dot.tklkup - This is the initialization file that should be put
+into each users home directory as I<.tklkup>.
 
-This file will have to be setup properly before the user 
+This file will have to be setup properly before the user
 can expect the tklkup script to work properly.  The odds of this
 initialization file being setup correctly for anyone is I<ZERO>.
-However the script can be run with this file to get a feel 
+However the script can be run with this file to get a feel
 for how the script will look.
 
-It allows the user to customize how tklkup will look and 
+It allows the user to customize how tklkup will look and
 work for them.
 If the .tklkup files does not exist in a users home
 directory the program has a set of built-in defaults
@@ -6191,7 +6191,7 @@ To be used this file must have user read permission.
 There are 10 commands that can be used with this file;
 
  binddn  -> string value:  Bind DN.
- 
+
  followref -> no value needed.  Setting this option will
               activate following referrals on entry modification.
 
@@ -6201,10 +6201,10 @@ There are 10 commands that can be used with this file;
  mwheight -> numeric value: Default is 430 main window height in
                             pixels, user may need to adjust this.
 
- hand -> values: left or right.  Defines where the 
+ hand -> values: left or right.  Defines where the
                  attribute label box will be place.
 
- limit -> value: default is 100.  Limits the number of 
+ limit -> value: default is 100.  Limits the number of
                  search base(s) detected.
 
  port -> value: default is 389.  User should set this
@@ -6221,17 +6221,17 @@ There are 10 commands that can be used with this file;
               additional attribute that is always listed without
               any action by the user; Filter.  This attribute
               allows the user to enter the I<COMPLETE> filter
-              that will used to search for data.  
+              that will used to search for data.
 
  server -> name of the directory server that you wish
-           to conduct the data search. 
+           to conduct the data search.
            One server per line.
            Each line can have one of two formats
            server: server name
                   or
-           server: server name: base 
+           server: server name: base
 
-           The I<server: server name> format will try to use the 
+           The I<server: server name> format will try to use the
            root_dse function to define the base.
            It the root_dse returns the namingContexts attribute,
            that information will be use to determine the search
@@ -6241,47 +6241,47 @@ There are 10 commands that can be used with this file;
            In this case the user will have to define a search base
            in the server command of the .tklkup file.
 
-           The I<server: server name: base> format will 
-           cause each of the defined servers to have it's 
+           The I<server: server name: base> format will
+           cause each of the defined servers to have it's
            own special initial search base and use this initial
            search base to find all of the other search bases.
            This is an attempt to do auto search base detection.
            Using this method has one I<draw back>, when changing
            to a different directory server there is a possible
-           I<delay> on displaying the new server name and 
-           search base.  This is due to the fact that TK and 
+           I<delay> on displaying the new server name and
+           search base.  This is due to the fact that TK and
            it's MainLoop() process are not multi-tasking.
-           The new search base has to be acquired and setup before 
+           The new search base has to be acquired and setup before
            MainLoop() takes control of the process.
            Depending on the number of search bases this time period
-           can be quite a few seconds.  
+           can be quite a few seconds.
 
-           When switching between servers with the same base, the 
-           search base will I<not> be updated.  This too can have 
-           a I<draw back> if there are new search bases in the 
+           When switching between servers with the same base, the
+           search base will I<not> be updated.  This too can have
+           a I<draw back> if there are new search bases in the
            new server but it saves time.
 
-           None of this is a problem if all of your servers have 
-           the same DIT layouts. Just define them with the 
+           None of this is a problem if all of your servers have
+           the same DIT layouts. Just define them with the
            same search base, there should be little or no delay
            when switching to the new server.
 
 =back
 
- Now a word about directory branch, or search base, detection.  
+ Now a word about directory branch, or search base, detection.
  There are many things that can prevent this function from working
- properly.  Several version 2 LDAP servers that this was tested 
+ properly.  Several version 2 LDAP servers that this was tested
  on required that you be bound to the server.
- None of the version 3 LDAP servers required this. 
- If this function does not work for you, provide a bind DN and 
- password.  The normal mode of operation for this function is an 
- anonymous bind situation. 
- Some of the ldap servers I worked with would never return the 
+ None of the version 3 LDAP servers required this.
+ If this function does not work for you, provide a bind DN and
+ password.  The normal mode of operation for this function is an
+ anonymous bind situation.
+ Some of the ldap servers I worked with would never return the
  information I expected, auto detection never functioned on these
  systems.
- There is one college ldap server on the Internet that has so 
- many bases that it takes over an hour to figure out all the 
- search bases.  The only way the operator knows that the 
+ There is one college ldap server on the Internet that has so
+ many bases that it takes over an hour to figure out all the
+ search bases.  The only way the operator knows that the
  script is still working is because search limit exceeded messages
  are displayed on the console that initiated the tklkup script.
  Who wants to wait a hour while the script figures this out.
@@ -6293,24 +6293,24 @@ There are 10 commands that can be used with this file;
 
 =head1 tklkup
 
-tklkup - PERL executable file.  
+tklkup - PERL executable file.
 
-You may need to change the first line of the PERL tklkup script 
+You may need to change the first line of the PERL tklkup script
 to point to your file pathname of perl.
 
 When executed tklkup will display a window on your
-computer.  The graphical user interface, GUI, has 
-several sections to it.  
+computer.  The graphical user interface, GUI, has
+several sections to it.
 
-If tklkup is run on a HPUX, Sun, or Linux system the 
+If tklkup is run on a HPUX, Sun, or Linux system the
 tklkup process will fork and run in background mode.
 If tklkup is run in debug mode or on a system that is not
-listed above it will I<NOT> fork and will run in in 
+listed above it will I<NOT> fork and will run in in
 foreground mode.
 
 During initial program initialization a "splash" screen will
 be displayed telling the user what is going on.  It is possible
-that the user will never see the splash screen if tklkup 
+that the user will never see the splash screen if tklkup
 initializes quickly.
 
 
@@ -6319,15 +6319,15 @@ initializes quickly.
 =head1 Tklkup Menu Bar
 
 At the top of the GUI is the main menu bar.  It has 3 drop down
-menus; "Directory OPS", "Set Bind Credentials", and 
+menus; "Directory OPS", "Set Bind Credentials", and
 "Set DSA Port".
 
 The I<DIRECTORY OPS> button will activate a drop down menu that
-has 2 menu selections; 
+has 2 menu selections;
 
 The I<EXPLORE ROOT DSE> menu will attempt to obtain the
 root dse entry for the selected directory server.  If the root
-dse entry is obtained a separate window will be displayed that 
+dse entry is obtained a separate window will be displayed that
 will display the information obtained from the root dse entry.
 If the root dse entry can not be obtained then an error message
 window will be displayed.  This menu has a "Hot" key, Ctrl-r.
@@ -6335,31 +6335,31 @@ window will be displayed.  This menu has a "Hot" key, Ctrl-r.
 The I<Set SSL> menu will set parameters for a SSL ldap connection.
 This menu has a "Hot" key, Ctrl-s.
 
-The I<Set NON-SSL> menu will set parameters for a non-SSL ldap 
+The I<Set NON-SSL> menu will set parameters for a non-SSL ldap
 connection.  This menu has a "Hot" key, Ctrl-n.
 
 The I<Toggle LDAP Version> menu will toggle the ldap version
 between version 2 and 3.  This menu has a "Hot" key, Ctrl-l.
 
 The I<Toggle Follow Referral> menu will toggle the flag that
-determines whether a ldap modify follows a referral.  This menu 
+determines whether a ldap modify follows a referral.  This menu
 has a "Hot" key, Ctrl-f.
 
 The I<Exit> menu will exit the program.  This menu has a
 "Hot" key, Ctrl-x.
 
-The I<SET BIND CREDENTIALS> button will activate a window 
-that is separate from the main window.  This menu has a 
+The I<SET BIND CREDENTIALS> button will activate a window
+that is separate from the main window.  This menu has a
 "Hot" key, Alt-b.
 
-The new window contains two buttons and two text boxes. 
+The new window contains two buttons and two text boxes.
 
 At the top of the window is a Cancel button, pressing
 this button will cancel the operation of setting the
-bind DN and password. 
+bind DN and password.
 
 The DN text box is where the user will enter the DN
-to bind with.  If the user has the binddn option in the .tklkup 
+to bind with.  If the user has the binddn option in the .tklkup
 file, the binddn will be displayed in the DN text box.
 
 The PASSWORD text box is where the user will enter the password
@@ -6376,12 +6376,12 @@ selected directory server.
 Having both the dn and password fields blank and pressing the
 accept key will cause an anonymous bind to the directory.
 
-The I<DIRECTORY PORT> button will activate a window 
-that is separate from the main window.  This menu has a 
+The I<DIRECTORY PORT> button will activate a window
+that is separate from the main window.  This menu has a
 "Hot" key, Alt-p.
 
-The new window contains two buttons, and one text box.  If the 
-user needs to change the TCP connection port, this is where it 
+The new window contains two buttons, and one text box.  If the
+user needs to change the TCP connection port, this is where it
 is done.
 
 At the top of the window is a Cancel button, pressing
@@ -6398,7 +6398,7 @@ port number will I<NOT> cause the program to issue a new
 connection to the directory server.  The user must re-select or
 change to a new directory server.
 
-I<EXIT PROGRAM> button.  Just below the main menu bar is 
+I<EXIT PROGRAM> button.  Just below the main menu bar is
 the "Exit" button.  When a mouse click is done on the "EXIT PROGRAM"
  button the program will terminate. This menu has a "Hot" key, Alt-e.
 
@@ -6409,18 +6409,18 @@ the "Exit" button.  When a mouse click is done on the "EXIT PROGRAM"
 Just below the Menu Bar is a section of the GUI that is displayed
 at all time regardless of which panel is displayed.
 
-The I<SELECT SERVER> button will activate a 
-drop down menu.  From the menu the user will select the 
+The I<SELECT SERVER> button will activate a
+drop down menu.  From the menu the user will select the
 "RadioButton" that corresponds to the directory server the
 user wishes to use.  When selected the "RadioButton" diamond
-will turn red in color.  This menu is a designed to be a 
-"I<tear off>" menu, selecting the "---------------" line will 
-cause the pull down menu to become a separate window that 
-is still somewhat controlled by the GUI.  The 
-DIRECTORY SERVER text box will display the directory name 
-that is selected.  If the GUI is icon-ed or exited, the tear 
-off window will follow the actions of the GUI.  All other 
-actions like moving or closing just the torn off window 
+will turn red in color.  This menu is a designed to be a
+"I<tear off>" menu, selecting the "---------------" line will
+cause the pull down menu to become a separate window that
+is still somewhat controlled by the GUI.  The
+DIRECTORY SERVER text box will display the directory name
+that is selected.  If the GUI is icon-ed or exited, the tear
+off window will follow the actions of the GUI.  All other
+actions like moving or closing just the torn off window
 must be done by the user's window manager.
 
 To the left of the  I<SELECT SERVER> button are two text labels;
@@ -6428,8 +6428,8 @@ one for the LDAP version and one for the SSL connection type.
 These labels will display information about the selected LDAP
 version and SSL connection status.
 
-At this point the tklkup GUI is made of five display and 
-control panels;  SEARCH,  SEARCH DISPLAY, SCHEMA DATA, CREATE ENTRY, 
+At this point the tklkup GUI is made of five display and
+control panels;  SEARCH,  SEARCH DISPLAY, SCHEMA DATA, CREATE ENTRY,
 and INFO;
 
 -------------------------------------------------------------------
@@ -6440,53 +6440,53 @@ The I<SELECT BASE> button will activate a Select Search Base window
 contains 2 buttons and a herical tree structure of the directory.
 At the top of the Select Search Base window is the CANCEL BASE CHANGE
 button.  Pressing the button will cancel the search base change and
-will close, or withdraw, the window.  At the bottom of the Select Search 
-Base window is the ACCEPT BASE CHANGE button.  Pressing the button 
+will close, or withdraw, the window.  At the bottom of the Select Search
+Base window is the ACCEPT BASE CHANGE button.  Pressing the button
 will change the search base to the highlighted directory branch and
-will close, or withdraw, the window.   
+will close, or withdraw, the window.
 In the middle of the Select Search Base window is the hierarchical
 list box where a tree type display of the directory branch structure
 will be displayed.  The directory namingContext(s) form the base of the
 tree(s), to the left of each branch in the directory will be a small
 box with a + or - sign in it, if the box has a + in it, clicking on
-the box will expand the tree structure, if the box has a - in it, 
+the box will expand the tree structure, if the box has a - in it,
 clicking on the box will collapse the tree structure.
 
 To select a search base, click on a branch, which will highlight the
 branch, and press the ACCEPT BASE CHANGE button.
 
-The I<SELECT ADDITIONAL ATTRIBUTES> button will activate a 
-drop down menu.  From the menu the user will select the 
+The I<SELECT ADDITIONAL ATTRIBUTES> button will activate a
+drop down menu.  From the menu the user will select the
 "RadioButton" that corresponds to the attribute the
-user wishes to use in the filter of the directory search.  When 
-selected the "RadioButton" diamond will turn red in color.  This 
-menu is a designed to be a "I<tear off>" menu, selecting the 
-"---------------" line will cause the pull down menu to 
-become a separate window that is still somewhat controlled 
-by the GUI.  If the GUI is icon-ed or exited, the tear off 
-window will follow the actions of the GUI.  All other 
-actions like moving or closing just the torn off window 
+user wishes to use in the filter of the directory search.  When
+selected the "RadioButton" diamond will turn red in color.  This
+menu is a designed to be a "I<tear off>" menu, selecting the
+"---------------" line will cause the pull down menu to
+become a separate window that is still somewhat controlled
+by the GUI.  If the GUI is icon-ed or exited, the tear off
+window will follow the actions of the GUI.  All other
+actions like moving or closing just the torn off window
 must be done by the user's window manager.
 
-The I<SAVE FORMAT> frame contains to check boxes.  
+The I<SAVE FORMAT> frame contains to check boxes.
 If checkbox XML is select, the SAVE TO and SAVE ALL TO
-buttons will save the select data in XML format. 
+buttons will save the select data in XML format.
 If checkbox LDIF is select, the SAVE TO and SAVE ALL TO
-buttons will save the select data in LDIF format. 
+buttons will save the select data in LDIF format.
 
-Just under the I<SELECT BASE> button is the hierarchical text 
+Just under the I<SELECT BASE> button is the hierarchical text
 box where the DN results of the directory search will be displayed.
-If there were valid results returned from the search a list of DN 
-entry(s) will be displayed in the hierarchical list box.  Selecting 
-a DN will cause the five LDAP Action buttons to the left of the 
-hierarchical text box to be put in the active state.  It is with 
+If there were valid results returned from the search a list of DN
+entry(s) will be displayed in the hierarchical list box.  Selecting
+a DN will cause the five LDAP Action buttons to the left of the
+hierarchical text box to be put in the active state.  It is with
 these 5 buttons that the user can select to view, rename, edit,
-save to a ldif file, or delete the corresponding DSA's directory 
+save to a ldif file, or delete the corresponding DSA's directory
 data.
 
 =head1 LDAP ACTION BUTTONS
 
-I<DISPLAY> - Will display the selected DN's information in the 
+I<DISPLAY> - Will display the selected DN's information in the
 Directory Data text box that is located in the SEARCH DISPLAY
 panel. The SEARCH DISPLAY panel will be brought to the foreground
 of the GUI.
@@ -6499,48 +6499,48 @@ I<DELETE> - Will cause the selected DN to be deleted from the
 directory.  When this button has the focus, it's text will turn
 red, letting the user know to use caution with this button.
 
-I<EDIT> - Will cause a Entry Edit Display window with the 
-corresponding entry data in it.  It is from this window that the 
-user can change directory data.  This window is described in 
+I<EDIT> - Will cause a Entry Edit Display window with the
+corresponding entry data in it.  It is from this window that the
+user can change directory data.  This window is described in
 detail later in this document.
 
 I<SAVE TO> - Will cause the entry that is selected to be written
-to the file specified in the FILE NAME text box.  The data 
-format of this file will be whatever is selected in the 
+to the file specified in the FILE NAME text box.  The data
+format of this file will be whatever is selected in the
 SAVE FORMAT frame.
 
 I<CANCEL> - Will cancel the action request for the select DN.
 
-I<SEARCH THE DIRECTORY> button.  At the bottom of the GUI is 
-the "Search" button.  When a mouse click is done on the 
+I<SEARCH THE DIRECTORY> button.  At the bottom of the GUI is
+the "Search" button.  When a mouse click is done on the
 "SEARCH THE DIRECTORY" button the program will execute a ldap search
-of the directory.  
+of the directory.
 
-The I<FILTER DATA> text box is where the user will enter 
+The I<FILTER DATA> text box is where the user will enter
 the data to be searched for.  The program will automatically
 put the beginning and ending parenthesis around the data.
-If the I<Filter> attribute is selected this is where the 
+If the I<Filter> attribute is selected this is where the
 I<COMPLETE> filter is entered, the program will not modify this
 string in any way.
 If the user presses the Enter key while the I<FILTER DATA> text box
 has the key board focus, a ldap search for the filter data will be
-executed.  This action is the same as pressing the 
+executed.  This action is the same as pressing the
 I<SEARCH THE DIRECTORY> button.
 
 The I<CLEAR FILTER DATA> button will clear out the text
 that appears in the Attribute Data text box.
 
-The I<SET FILTER CONDITION> button will activate a drop down menu.  
-From the menu the user will select the "RadioButton" that 
-corresponds to the filter conditions the user wishes to use 
-in the directory search.  When selected the "RadioButton" 
-diamond will turn red in color.  This menu is a designed 
-to be a "I<tear off>" menu, selecting the 
-"---------------" line will cause the pull down menu to 
-become a separate window that is still somewhat controlled 
-by the GUI.  If the GUI is icon-ed or exited, the tear off 
-window will follow the actions of the GUI.  All other 
-actions like moving or closing just the torn off window 
+The I<SET FILTER CONDITION> button will activate a drop down menu.
+From the menu the user will select the "RadioButton" that
+corresponds to the filter conditions the user wishes to use
+in the directory search.  When selected the "RadioButton"
+diamond will turn red in color.  This menu is a designed
+to be a "I<tear off>" menu, selecting the
+"---------------" line will cause the pull down menu to
+become a separate window that is still somewhat controlled
+by the GUI.  If the GUI is icon-ed or exited, the tear off
+window will follow the actions of the GUI.  All other
+actions like moving or closing just the torn off window
 must be done by the user's window manager.
 The four filter conditions control how the search filter
 will be created.  Just to the side of the I<SET FILTER CONDITION>
@@ -6549,26 +6549,26 @@ that is selected.
 
 =head1 SAVE ALL TO BUTTON
 
-At the bottom of the SEARCH RESULTS panel is the SAVE ALL TO 
-button, pressing this button will cause the previous search to be 
-re-executed and all of the search results will be written to the 
-file specified in the FILE NAME text box.  The data 
-format of this file will be whatever is selected in the 
+At the bottom of the SEARCH RESULTS panel is the SAVE ALL TO
+button, pressing this button will cause the previous search to be
+re-executed and all of the search results will be written to the
+file specified in the FILE NAME text box.  The data
+format of this file will be whatever is selected in the
 SAVE FORMAT frame.
 
 -------------------------------------------------------------------
 
 =head1 SEARCH DISPLAY PANEL
- 
+
 The I<SEARCH DISPLAY> is the panel where data for the
 selected DN is displayed. Data is displayed in the read only
-Directory Data text box.  Associated with the Directory Data 
+Directory Data text box.  Associated with the Directory Data
 text box is the "RadioButton" that determines how often the
-data in the directory text box is cleared.  If the "CheckButton" 
-is selected, colored red, the directory data text box will be 
-cleared out before each directory query.  If the "CheckButton" 
-is not selected the directory data text box will NOT be cleared 
-out until the Clear Data button in clicked or the 
+data in the directory text box is cleared.  If the "CheckButton"
+is selected, colored red, the directory data text box will be
+cleared out before each directory query.  If the "CheckButton"
+is not selected the directory data text box will NOT be cleared
+out until the Clear Data button in clicked or the
 CLEAR DIRECTORY DATA ON EACH QUERY "RadioButton" is selected.
 
 The Directory Data text box is where the results of the
@@ -6580,16 +6580,16 @@ with 4 additional functions will be displayed inside the
 Directory Data text box.  These 4 functions are;
 
  File -> This function exits the window.  You can not edit
-         the Directory Data text box because it is created 
+         the Directory Data text box because it is created
          as a read only text box.
 
  Edit -> This function gives the user 3 additional functions;
          Copy -> I do not know what this function does.
          Select All -> Highlights/Selects all of the text in
          the Directory Data text box.
-         Unselect All -> Unselects all of the text in 
+         Unselect All -> Unselects all of the text in
          the Directory Data text box.
-         Select/Unselect are used in-conjunction with the 
+         Select/Unselect are used in-conjunction with the
          Copy function.
 
  Search -> This function gives the user 4 additional
@@ -6597,12 +6597,12 @@ Directory Data text box.  These 4 functions are;
          Find, Find Next, Find Previous -> These functions
          find text in the Directory Data text box.
          Replace -> This function allows you to replace the
-         text that is selected.  However this is just 
-         a fake replacement as you can not edit the 
-         Directory Data text box because it is created 
+         text that is selected.  However this is just
+         a fake replacement as you can not edit the
+         Directory Data text box because it is created
          as a read only text box.
 
- View -> This function gives the user 3 additional 
+ View -> This function gives the user 3 additional
          functions.
          Goto Line ->  When selected will prompt the
          user for a line number, the line number being
@@ -6610,7 +6610,7 @@ Directory Data text box.  These 4 functions are;
          What Line ->  When selected will tell the user
          what line number the cursor is on.
          Wrap ->  When selected will prompt the user
-         to choose how to do line wrapping in the 
+         to choose how to do line wrapping in the
          Directory Data text box.
 
 The CLEAR DATA button will clear out the text that
@@ -6623,18 +6623,18 @@ when a jpegPhoto attribute is read a separate I<JPEG PHOTO DISPLAY>
 window will be display.  Inside this window will be the jpeg photo,
 a list box containing the DN of the entry, and a I<CLOSE WINDOW> button.
 
-If the Tk::JPEG module is I<NOT> installed in the user's Perl 
+If the Tk::JPEG module is I<NOT> installed in the user's Perl
 system, nothing will be displayed for the jpegPhoto.
 
 -------------------------------------------------------------------
 
 =head1 MODDN INFORMATION WINDOW
 
-The I<RENAME> button will activate a window that is separate from 
-the main window.  
+The I<RENAME> button will activate a window that is separate from
+the main window.
 
-The new window contains two buttons, two text boxes and one 
-checkbutton. 
+The new window contains two buttons, two text boxes and one
+checkbutton.
 The text boxes are initialized with data that corresponds the
 DN that was selected in the Search Results window.  It is in
 these text boxes that the user will enter the data needed for the
@@ -6655,7 +6655,7 @@ this button will set the new RDN and the superior RDN.
 The I<DELETE OLD RDN DATA> check box controls whether the old
 entry information is deleted or not deleted.  When the check box
 is selected, colored red, the old entry information will be deleted.
-This is the default action for this button.  
+This is the default action for this button.
 Unselecting the check box will cause the entry data to not be deleted.
 
 -------------------------------------------------------------------
@@ -6687,7 +6687,7 @@ Each line in the box is broken up into two parts; the attribute button and
 the attribute data list box. There is one attribute and data pair per
 line.  Multi-valued attributes have one line per attribute value.
 
-The first line in the I<ENTRY DATA> box will be the DN of the entry. 
+The first line in the I<ENTRY DATA> box will be the DN of the entry.
 This line can not be edited.
 
 To edit an attribute, press the button that has the attributes name on
@@ -6695,15 +6695,15 @@ it.  This will cause a I<ATTRIBUTE MODIFICATION> window to be displayed.
 This window is described in detail later in this documentation.
 
 When the user has finished making changes, press the I<CHANGE DATA> button.
-This will start the process of making the change(s) in the LDAP 
+This will start the process of making the change(s) in the LDAP
 directory.  If any errors occur a error window will appear.  After the
-error window is dismissed the I<ENTRY EDIT DISPLAY> window will still 
+error window is dismissed the I<ENTRY EDIT DISPLAY> window will still
 be active.  The user can at this point do what ever it takes to correct
 the problem.
 
-If no errors occur the I<ENTRY EDIT DISPLAY> window and the 
+If no errors occur the I<ENTRY EDIT DISPLAY> window and the
 I<SEARCH RESULTS> windows will be destroyed.  This is due to the fact
-that the data in both windows is no longer valid.  The user must 
+that the data in both windows is no longer valid.  The user must
 research the LDAP directory to get the new updated information.
 
 
@@ -6724,11 +6724,11 @@ the pending data change queue.
 
 In the middle of the window is the attribute data text box.  It is in
 this text box that the user will find the current data for the attribute
-the user selected.  Depending on the operation the user wants to do the 
+the user selected.  Depending on the operation the user wants to do the
 user can change the data or leave the data as is.
 
 Below the attribute data text box are three buttons, ADD, DELETE, and
-REPLACE.  
+REPLACE.
 
 =head2 ADD operations.
 
@@ -6744,7 +6744,7 @@ the I<DELETE> button.
 
 =head2 REPLACE operations.
 
-The attribute value being replaced is a part of a multi-valued 
+The attribute value being replaced is a part of a multi-valued
 attribute, the new value will be added to the attribute, then
 the old value will be deleted.  If the add operation has an error
 code, the delete part of this operation will not take place.
@@ -6752,9 +6752,9 @@ code, the delete part of this operation will not take place.
 If the attribute value being replace is a single valued attribute
 this value will be replaced.
 
-When the user done with the changes the user should press the 
+When the user done with the changes the user should press the
 I<ACCEPT DATA CHANGES> button.  This will move the data changes onto
-the pending data change queue and close the window. 
+the pending data change queue and close the window.
 
 -------------------------------------------------------------------
 
@@ -6771,8 +6771,8 @@ directory entry to be deleted.
 
 =head1 SCHEMA DATA PANEL
 
-This panel has schema information from a LDAP directory server.  
-This data is retrieved, with in one second, upon connection to the 
+This panel has schema information from a LDAP directory server.
+This data is retrieved, with in one second, upon connection to the
 selected directory server.  This action takes place upon start up
 of the program or when a new directory server is selected.
 
@@ -6781,27 +6781,27 @@ of the program or when a new directory server is selected.
 When the SCHEMA DATA panel tab is pressed, the SCHEMA DATA
 panel is brought to the foreground of the GUI.
 
-When the Write Data To File RadioButton is selected the 
-LDAP Schema data will be written to the file listed 
+When the Write Data To File RadioButton is selected the
+LDAP Schema data will be written to the file listed
 in the text box below the RadioButton text.  By selecting
 the DSML XML RadionButton, the data will be written to the
-file in XML format.  Once the data has been written to the file a 
-message will be written to the DIRECTORY SCHEMA DATA text box 
-stating that the data has been written to a file and will list 
-the file name. Upon completion of the schema dump operation 
+file in XML format.  Once the data has been written to the file a
+message will be written to the DIRECTORY SCHEMA DATA text box
+stating that the data has been written to a file and will list
+the file name. Upon completion of the schema dump operation
 the RadioButton and text in the file name text box will be reset.
-At the bottom of the GUI is the "Retrieve Directory Schema" button.  
-When a mouse click is done on the "Retrieve Directory Schema" 
+At the bottom of the GUI is the "Retrieve Directory Schema" button.
+When a mouse click is done on the "Retrieve Directory Schema"
 button the script will query the directory server for schema information
 and then write the information to the file.
 
 Associated with the Directory Schema Data text box is a series of
 "CheckButtons" that determines what of the schema objects will be
 displayed.  There are 9 Checkbuttons; ALL, objectClass, matchingRules,
-attributeTypes, ldapsyntaxes, nameforms, ditstructurerules, 
-ditcontentrules, and matchingruleuse.  If the "CheckButton" is 
-selected, colored red, then schema objects of that type will be 
-displayed in the Directory Schema Data text box. 
+attributeTypes, ldapsyntaxes, nameforms, ditstructurerules,
+ditcontentrules, and matchingruleuse.  If the "CheckButton" is
+selected, colored red, then schema objects of that type will be
+displayed in the Directory Schema Data text box.
 If the "CheckButton" is not selected, gray in color, then schema
 objects of this type will not be displayed in the Directory Schema
 Data text box.  By default the ALL CheckButton is select.
@@ -6811,20 +6811,20 @@ directory search will be displayed.  With the cursor
 in the Directory Data text box you have access to additional
 functions when you depress the mouse "action" button.
 When the "action" mouse button is depressed a small text box
-with 4 additional functions will be displayed inside the 
+with 4 additional functions will be displayed inside the
 Directory Data text box.  These 4 functions are;
 
  File -> This function exits the window.  You can not edit
-         the Directory Data text box because it is created 
+         the Directory Data text box because it is created
          as a read only text box.
 
  Edit -> This function gives the user 3 additional functions;
          Copy -> I do not know what this function does.
          Select All -> Highlights/Selects all of the text in
          the Directory Data text box.
-         Unselect All -> Unselects all of the text in 
+         Unselect All -> Unselects all of the text in
          the Directory Data text box.
-         Select/Unselect are used in-conjunction with the 
+         Select/Unselect are used in-conjunction with the
          Copy function.
 
  Search -> This function gives the user 4 additional
@@ -6832,12 +6832,12 @@ Directory Data text box.  These 4 functions are;
          Find, Find Next, Find Previous -> These functions
          find text in the Directory Data text box.
          Replace -> This function allows you to replace the
-         text that is selected.  However this is just 
-         a fake replacement as you can not edit the 
-         Directory Data text box because it is created 
+         text that is selected.  However this is just
+         a fake replacement as you can not edit the
+         Directory Data text box because it is created
          as a read only text box.
 
- View -> This function gives the user 3 additional 
+ View -> This function gives the user 3 additional
          functions.
          Goto Line ->  When selected will prompt the
          user for a line number, the line number being
@@ -6845,39 +6845,39 @@ Directory Data text box.  These 4 functions are;
          What Line ->  When selected will tell the user
          what line number the cursor is on.
          Wrap ->  When selected will prompt the user
-         to choose how to do line wrapping in the 
+         to choose how to do line wrapping in the
          Directory Data text box.
 
-The Clear Data button will clear out the text that 
+The Clear Data button will clear out the text that
 appears in the Directory Schema Data text box.
 
 The I<SHOW HIERARCHICAL OBJECTCLASS TREE> will cause one of two
-windows to be displayed.  For information about these windows see 
+windows to be displayed.  For information about these windows see
 the HIERARCHICAL OBJECTCLASS section of the manual.
 
-At the bottom of the GUI is the "Retrieve Directory Schema" button.  
-When a mouse click is done on the "Retrieve Directory Schema" 
+At the bottom of the GUI is the "Retrieve Directory Schema" button.
+When a mouse click is done on the "Retrieve Directory Schema"
 button the script will query the directory server for schema information.
 
 =head1 HIERARCHICAL OBJECTCLASS Window
 
-If no directory schema data has been obtained from the selected 
+If no directory schema data has been obtained from the selected
 directory server a error message window will be displayed stating
 that no schema data is available.
 
 If directory schema data has been obtained from the selected
 directory server a separate window will be displayed.
-The I<HIERARCHICAL OBJECTCLASS> window has two list boxes and 
-a I<CLOSE HIERARCHICAL DISPLAY WINDOW> button.  The 
-I<CLOSE HIERARCHICAL DISPLAY WINDOW> button will destroy the 
+The I<HIERARCHICAL OBJECTCLASS> window has two list boxes and
+a I<CLOSE HIERARCHICAL DISPLAY WINDOW> button.  The
+I<CLOSE HIERARCHICAL DISPLAY WINDOW> button will destroy the
 I<HIERARCHICAL OBJECTCLASS> window.  In one of the list boxes will
 be a hierarchical tree of all of the objectclasses obtained from the
-directory server.  Doing a mouse button select on one of the 
-objects in the tree will cause information about that objectclass 
+directory server.  Doing a mouse button select on one of the
+objects in the tree will cause information about that objectclass
 branch to be displayed in the adjacent list box.  The most superior
 ojectclass will be at the top of the listing, the leaf objectclass
 will be at the bottom of the listing.  Each objectclass is separated
-by a dashed line.  All information about each objectclass will be 
+by a dashed line.  All information about each objectclass will be
 displayed in that objectclass's section.
 
 -------------------------------------------------------------------
@@ -6888,7 +6888,7 @@ displayed in that objectclass's section.
 
 The user can create and modify an entry from a LDIF file.
 
-When the user presses the "CREATE/MODIFY ENTRY FROM LDIF FILE" 
+When the user presses the "CREATE/MODIFY ENTRY FROM LDIF FILE"
 button, the file listed in the "LDIF FILE NAME" text box will be used
 to create or modify the entries listed in the ldif formatted file.
 
@@ -6902,16 +6902,16 @@ the SELECT DN BASE button.  This will setup part of the entry's
 DN.
 
 After selecting the DN base the user can find and select an objectclass,
-or objectclasses from the list of objectClass(s).  When the user selects, 
+or objectclasses from the list of objectClass(s).  When the user selects,
 by clicking the pointer on an objectClass, the objectclass will appear
 in the window to the left of the objectclass list. The superior objectclass(s)
-of the selected objectclass will also be displayed.  
+of the selected objectclass will also be displayed.
 
 If the user adds a wrong objectclass, the user may remove the objectclass
-by clicking the button with the objectclass name in it.  Only that 
+by clicking the button with the objectclass name in it.  Only that
 class will be removed.
 
-When the user is ready to create the entry, the user must click the 
+When the user is ready to create the entry, the user must click the
 "Create The Entry" button and a CREATE DIRECTORY ENTRY window
 will be displayed.  It is from the CREATE DIRECTORY ENTRY window the
 the user will finish entering data for the new entry.
@@ -6924,7 +6924,7 @@ include in the objectclasses for the new entry.
 
 =head1 CREATE DIRECTORY ENTRY WINDOW
 
-At the top of the CREATE DIRECTORY ENTRY window is the 
+At the top of the CREATE DIRECTORY ENTRY window is the
 CANCEL CREATE ENTRY DISPLAY button.  Pressing this button
 will cancel the entry creation process.
 
@@ -6939,20 +6939,20 @@ the Naming Attribute, or sets up a DN.
 The data list box is for all practical purposes divided into 4
 sections.
 
-The DN text field is where the user can edit the DN base or 
-enter in a complete DN.  If the user enters a complete DN the 
+The DN text field is where the user can edit the DN base or
+enter in a complete DN.  If the user enters a complete DN the
 user should B<NOT> select a Naming Attribute radionbutton.
 
 Between the DN text field and the objectClass text fields will
-be all of the B<MUST> attributes.  The B<MUST> attribute names 
+be all of the B<MUST> attributes.  The B<MUST> attribute names
 will be colored red.  These attributes must have information in
 them for the entry to be accepted into the directory.
 
 The objectClass text fields are read only fields that list the
 objectClasses that will be used in the creation of the entry.
 
-All attributes below the objectClass text fields are B<MAY> 
-attributes, the user does not have to supply information about 
+All attributes below the objectClass text fields are B<MAY>
+attributes, the user does not have to supply information about
 these attributes unless the attribute is selected to be the
 Naming Attribute.  If the attribute is selected to be the Naming
 Attribute it B<MUST> have data associated with it.
@@ -6964,16 +6964,16 @@ does not have to use these buttons, but if one is selected,
 due to the nature of radiobuttons, one of them must be used
 as there is no way to deselect any of the radiobuttons.
 
-At the bottom of the CREATE DIRECTORY ENTRY window is the 
+At the bottom of the CREATE DIRECTORY ENTRY window is the
 CREATE ENTRY button.  Pressing this button will start the process
 of putting the new entry into the directory.
 
 If during the actual creation of the entry there is an error
 detected, a error window will be displayed stating the error.
 Once the error is acknowledged, the user can correct the error
-and then re-click the CREATE ENTRY button will re-attempt to 
-create the entry in the directory.  The CREATE DIRECTORY ENTRY  
-window will not be destroyed until either the user cancels the 
+and then re-click the CREATE ENTRY button will re-attempt to
+create the entry in the directory.  The CREATE DIRECTORY ENTRY
+window will not be destroyed until either the user cancels the
 action or the entry is created in the directory.
 
 
@@ -6985,7 +6985,7 @@ This panel is mainly for information.
 
 The I<Process Messages> text window is where process messages
 will be displayed.  The messages are indicators of what is
-happening during the execution of the program.  By selecting 
+happening during the execution of the program.  By selecting
 a line of text and moving the cursor up or down, the user
 can scroll through the messages.
 
@@ -7023,14 +7023,14 @@ load the following PERL module.
 Perl Digest-MD5 module.  You can get this from the following URL;
    ftp://ftp.duke.edu/pub/CPAN/modules/by-module/MD5/
 
-Bundled inside each PERL module is instructions on how to install the 
+Bundled inside each PERL module is instructions on how to install the
 module into your PERL system.
 
 -------------------------------------------------------------------
 
 =head1 INSTALLING THE SCRIPT
 
-Install the tklkup script anywhere you wish, I suggest 
+Install the tklkup script anywhere you wish, I suggest
 /usr/local/bin/tklkup.
 
 Install the dot.tklkup file in each users home directory
@@ -7039,7 +7039,7 @@ create a link in the user home directory to the central copy.
 
 -------------------------------------------------------------------
 
-Since the script is in PERL, feel free to modify it if it does not 
+Since the script is in PERL, feel free to modify it if it does not
 meet your needs.  This is one of the main reasons I did it in PERL.
 If you make an addition to the code that you feel other individuals
 could use let me know about it.  I may incorporate your code
@@ -0,0 +1,95 @@
+
+dn: o=University of Michigan, c=US
+control: 2.16.840.1.113730.3.4.2 true
+control: 2.16.840.1.113730.3.4.18 true:: ZG46Y249SMOkZ2FyLG91PXBlb3BsZSxvPW15b
+ 3JnLmNvbQ==
+changetype: add
+objectclass: top
+objectclass: organization
+objectclass: domainRelatedObject
+objectclass: quipuObject
+objectclass: quipuNonLeafObject
+l: Ann Arbor, Michigan
+st: Michigan
+streetaddress: 535 West William St.
+o: University of Michigan
+o: UMICH
+o: UM
+o: U-M
+o: U of M
+description: The University of Michigan at Ann Arbor
+postaladdress: University of Michigan $ 535 W. William St. $ Ann Arbor, MI 481
+ 09 $ USpostalcode: 48109
+telephonenumber: +1 313 764-1817
+lastmodifiedtime: 930106182800Z
+lastmodifiedby: cn=manager, o=university of michigan, c=US
+associateddomain: umich.edu
+
+dn: ou=People, o=University of Michigan, c=US
+control: 2.16.840.1.113730.3.4.18 true: dn:cn=me,ou=people,o=myorg.com
+changetype: add
+objectclass: top
+objectclass: organizationalUnit
+objectclass: quipuObject
+objectclass: quipuNonLeafObject
+ou: People
+
+dn: ou=Groups, o=University of Michigan, c=US
+changetype: add
+objectclass: top
+objectclass: organizationalUnit
+objectclass: quipuObject
+objectclass: quipuNonLeafObject
+ou: Groups
+lastmodifiedtime: 950120182331Z
+lastmodifiedby: cn=manager, o=university of michigan, c=US
+
+dn: ou=Alumni Association, ou=People, o=University of Michigan, c=US
+changetype: add
+objectclass: top
+objectclass: organizationalUnit
+objectclass: quipuObject
+objectclass: quipuNonLeafObject
+ou: Alumni Association
+
+dn: ou=Information Technology Division, ou=People, o=University of Michigan, c
+ =US
+changetype: add
+objectclass: top
+objectclass: organizationalUnit
+objectclass: quipuObject
+objectclass: quipuNonLeafObject
+ou: Information Technology Divisio
+
+dn: cn=All Staff,ou=Groups,o=University of Michigan,c=US
+control: 2.16.840.1.113730.3.4.2 true
+changetype: add
+member: cn=Manager, o=University of Michigan, c=US
+member: cn=Barbara Jensen, ou=Information Technology Division, ou=People, o=Un
+ iversity of Michigan, c=US
+member: cn=Jane Doe, ou=Alumni Association, ou=People, o=University of Michiga
+ n, c=US
+member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
+ ty of Michigan, c=US
+member: cn=Mark Elliot, ou=Alumni Association, ou=People, o=University of Mich
+ igan, c=US
+member: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of 
+ Michigan, c=US
+member: cn=James A Jones 2, ou=Information Technology Division, ou=People, o=U
+ niversity of Michigan, c=US
+member: cn=Jennifer Smith, ou=Alumni Association, ou=People, o=University of M
+ ichigan, c=US
+member: cn=Dorothy Stevens, ou=Alumni Association, ou=People, o=University of 
+ Michigan, c=US
+member: cn=Ursula Hampster, ou=Alumni Association, ou=People, o=University of 
+ Michigan, c=US
+member: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, o=Univ
+ ersity of Michigan, c=US
+associateddomain: umich.edu
+requeststo: cn=Manager, o=University of Michigan, c=US
+errorsto: cn=Manager, o=University of Michigan, c=US
+owner: cn=Manager, o=University of Michigan, c=US
+cn: All Staff
+joinable: FALSE
+multi-linedescription: Everyone in the sample data
+objectclass: rfc822mailgroup
@@ -0,0 +1 @@
+Test Department $ 535 W. William St. Room 42 $ Ann Arbor, MI 48103-4943
@@ -9,7 +9,7 @@ use Net::LDAP qw(LDAP_SASL_BIND_IN_PROGRESS LDAP_DECODING_ERROR LDAP_SUCCESS
 		 LDAP_LOCAL_ERROR);
 use Net::LDAP::Message;
 
-our $VERSION = '1.04';
+our $VERSION = '1.05';
 our @ISA = qw(Net::LDAP::Message);
 
 sub _sasl_info {
@@ -35,9 +35,13 @@ sub decode {
 	  or $self->set_error(LDAP_DECODING_ERROR, 'LDAP decode error'), return;
   }
 
+  # Put the new layer over the raw socket, to get rid of any old layer,
+  # but only if we will be using a new layer. If we rebind but don't
+  # negotiate a new security layer, the old layer remains in place.
   if ($sasl and $bind->{resultCode} == LDAP_SUCCESS) {
     $sasl->property('ssf', 0)  if !$sasl->property('ssf');
-    $ldap->{net_ldap_socket} = $sasl->securesocket($ldap->{net_ldap_socket});
+    $ldap->{net_ldap_socket} = $sasl->securesocket($ldap->{net_ldap_rawsocket})
+      if ($sasl->property('ssf'));
   }
 
   return $self->SUPER::decode($result)
@@ -7,7 +7,7 @@ package Net::LDAP::Control::Paged;
 use Net::LDAP::Control;
 
 our @ISA = qw(Net::LDAP::Control);
-our $VERSION = '0.04';
+our $VERSION = '0.05';
 
 use Net::LDAP::ASN qw(realSearchControlValue);
 use strict;
@@ -99,7 +99,7 @@ Net::LDAP::Control::Paged - LDAPv3 Paged results control object
    $page->cookie($cookie);
  }
 
- if (defined($cookie) && (length($cookie)) {
+ if (defined($cookie) && length($cookie)) {
    # We had an abnormal exit, so let the server know we do not want any more
    $page->cookie($cookie);
    $page->size(0);
@@ -7,7 +7,7 @@ package Net::LDAP::Control::ProxyAuth;
 use Net::LDAP::Control;
 
 our @ISA = qw(Net::LDAP::Control);
-our $VERSION = '1.07';
+our $VERSION = '1.08';
 
 use Net::LDAP::Constant qw(LDAP_CONTROL_PROXYAUTHORIZATION);
 use Net::LDAP::ASN qw(proxyAuthValue);
@@ -23,12 +23,12 @@ sub init {
   if (defined($self->{proxyDN})) {
     $self->{type} = LDAP_CONTROL_PROXYAUTHORIZATION_OLD;
 
-    unless (exists $self->{value}) {
-      $self->{asn} = { proxyDN => $self->{proxyDN} || '' };
-    }
+    $self->{asn} = { proxyDN => $self->{proxyDN} || '' }
+      unless (exists $self->{value});
   }
   else {
-    $self->{value} = $self->{authzID} || '';
+    $self->{value} = $self->{authzID} || ''
+      unless (exists $self->{value});
   }
 
   # criticality must be set !
@@ -27,7 +27,7 @@ use Net::LDAP::Constant qw(
   LDAP_CONTROL_RELAX
 );
 
-our $VERSION = '0.15';
+our $VERSION = '0.17';
 
 my %Pkg2Type = (
 
@@ -156,27 +156,35 @@ Net::LDAP::Control - LDAPv3 control object base class
 =head1 SYNOPSIS
 
  use Net::LDAP::Control;
- use Net::LDAP::Constant qw( LDAP_CONTROL_MATCHEDVALS );
+ use Net::LDAP::Constant qw( LDAP_CONTROL_MANAGEDSAIT );
 
- $ctrl = Net::LDAP::Control->new(
+ my $req_ctrl1 = Net::LDAP::Control->new( type => LDAP_CONTROL_MANAGEDSAIT );
+ my $req_ctrl2 = Net::LDAP::Control->new(
    type     => "1.2.3.4",
    value    => "help",
    critical => 0
  );
 
- $mesg = $ldap->search( @args, control => [ $ctrl ]);
+ $mesg = $ldap->search( @args, control => [ $req_ctrl1, $req_ctrl2 ]);
 
- $ctrl = Net::LDAP::Control->new( type => LDAP_CONTROL_MATCHEDVALS );
+ my @res_ctrls = $mesg->control();
 
 =head1 DESCRIPTION
 
-C<Net::LDAP::Control> is a base-class for LDAPv3 control objects.
+C<Net::LDAP::Control> is the base-class for LDAPv3 control objects.
 
-=cut
+Controls provide a mechanism that allows one to extend the semantics and
+arguments of LDAP operations.
+Controls may be attached to LDAP operations, and only affect the semantics
+of the operation they are attached to.
+
+Controls sent by clients are termed I<request controls>, and are set using
+the C<control> option of the respective LDAP operations.
+Controls sent by servers are called I<response controls>, they can be found
+using the C<control()> method of the response message objects.
 
-##
-## Need more blurb in here about controls
-##
+Servers announce the controls they support in the attribute C<supportedControls>
+in their L<RootDSE|Net::LDAP::RootDSE>.
 
 =head1 CONSTRUCTORS
 
@@ -300,23 +308,25 @@ for this method is to return TRUE if there is no error, but sub-classes may over
 
 =head1 SEE ALSO
 
-L<Net::LDAP>
-L<Net::LDAP::Control::Assertion>
-L<Net::LDAP::Control::EntryChange>
-L<Net::LDAP::Control::ManageDsaIT>
-L<Net::LDAP::Control::MatchedValues>
-L<Net::LDAP::Control::Paged>
-L<Net::LDAP::Control::PasswordPolicy>
-L<Net::LDAP::Control::PersistentSearch>
-L<Net::LDAP::Control::PostRead>
-L<Net::LDAP::Control::PreRead>
-L<Net::LDAP::Control::ProxyAuth>
-L<Net::LDAP::Control::Sort>
-L<Net::LDAP::Control::SortResult>
-L<Net::LDAP::Control::SyncDone>
-L<Net::LDAP::Control::SyncRequest>
-L<Net::LDAP::Control::SyncState>
-L<Net::LDAP::Control::VLV>
+L<Net::LDAP>,
+L<Net::LDAP::RootDSE>,
+L<Net::LDAP::Control::Assertion>,
+L<Net::LDAP::Control::EntryChange>,
+L<Net::LDAP::Control::ManageDsaIT>,
+L<Net::LDAP::Control::MatchedValues>,
+L<Net::LDAP::Control::Paged>,
+L<Net::LDAP::Control::PasswordPolicy>,
+L<Net::LDAP::Control::PersistentSearch>,
+L<Net::LDAP::Control::PostRead>,
+L<Net::LDAP::Control::PreRead>,
+L<Net::LDAP::Control::ProxyAuth>,
+L<Net::LDAP::Control::Relax>,
+L<Net::LDAP::Control::Sort>,
+L<Net::LDAP::Control::SortResult>,
+L<Net::LDAP::Control::SyncDone>,
+L<Net::LDAP::Control::SyncRequest>,
+L<Net::LDAP::Control::SyncState>,
+L<Net::LDAP::Control::VLV>,
 L<Net::LDAP::Control::VLVResponse>
 
 =head1 AUTHOR
@@ -15,7 +15,7 @@ BEGIN {
     if (CHECK_UTF8);
 }
 
-our $VERSION = '0.26';
+our $VERSION = '0.27';
 
 sub new {
   my $self = shift;
@@ -214,7 +214,7 @@ sub delete {
 
   unless (@_) {
     $self->changetype('delete');
-    return;
+    return $self;
   }
 
   my $cmd = $self->{changetype} eq 'modify' ? [] : undef;
@@ -288,7 +288,7 @@ sub update {
   }
   elsif (eval { $target->isa('Net::LDAP::LDIF') }) {
     require Net::LDAP::Message;
-    $target->write_entry($self);
+    $target->write_entry($self, %opt);
     $mesg = Net::LDAP::Message::Dummy->new();
     $mesg->set_error(LDAP_OTHER, $target->error())
       if ($target->error());
@@ -334,8 +334,8 @@ by the add, modify or delete method called on CLIENT.
 Alternatively C<CLIENT> can also be a C<Net::LDAP::LDIF> object, that
 must be an LDIF file opened for writing.
 
-In this case, C<OPTIONS> are ignored as the method C<write_entry>
-of C<Net::LDAP::LDIF> does not take options.
+In this case, the entry, together with any C<OPTIONS> is passed as
+arguments to the C<write_entry> method of the C<CLIENT> object.
 
 Here too, the result is an object class C<Net::LDAP::Message>.
 On error, the error code is C<LDAP_OTHER> with the LDIF error message
@@ -401,11 +401,11 @@ To install the modules that are in the perl-ldap distribution follow the
 same steps that you would for most other distributions found on CPAN, that
 is
 
-   # replace 0.44 with the version you have
+   # replace 0.62 with the version you have
 
-   gunzip perl-ldap-0.44.tar.gz
-   tar xvf perl-ldap-0.44.tar
-   cd perl-ldap-0.44
+   gunzip perl-ldap-0.62.tar.gz
+   tar xvf perl-ldap-0.62.tar
+   cd perl-ldap-0.62
 
    perl Makefile.PL
    make
@@ -423,13 +423,13 @@ This will output information about the version of Perl you have
 installed. Near the bottom you will find something like
 
   @INC:
-    /usr/local/lib/perl/5.8.3
-    /usr/local/share/perl/5.8.3
+    /usr/local/lib/perl/5.18.2
+    /usr/local/share/perl/5.18.2
     /usr/lib/perl5
     /usr/share/perl5
-    /usr/lib/perl/5.8.3
-    /usr/share/perl/5.8.3
-    /usr/local/lib/site_perl
+    /usr/lib/perl/5.18
+    /usr/share/perl/5.18
+    /usr/local/lib/site_per
 
 This is a list of directories that Perl searches when it is looking for
 a module. The directory you need is the site_perl directory, but without
@@ -437,13 +437,13 @@ the system architecture name, in this case it is
 C</usr/local/lib/site_perl>. The files required
 can then be installed with
 
-   # replace 0.44 with the version you have
+   # replace 0.62 with the version you have
 
-   gunzip perl-ldap-0.44.tar.gz
-   tar xvf perl-ldap-0.44.tar
-   cd perl-ldap-0.44/lib
+   gunzip perl-ldap-0.62.tar.gz
+   tar xvf perl-ldap-0.62.tar
+   cd perl-ldap-0.62/lib
 
-   cp * /usr/local/lib/site_perl
+   cp -r * /usr/local/lib/site_perl
 
 =head2 How can I load perl-ldap into an ActiveState Perl installation?
 
@@ -521,6 +521,15 @@ IO::Socket::INET6 gets installed.
 You can obtain the latest releases from
   http://search.cpan.org/search?module=IO::Socket::INET6
 
+=item IO::Socket::IP
+
+This is an alternative to using IO::Socket::INET6. Like that module, it gets
+detected automatically at runtime. If version 0.20 or higher is installed, is
+is preferred over IO::Socket::INET6 and IO::Socket::INET for all IP connections.
+
+You can obtain the latest releases from
+  http://search.cpan.org/search?module=IO::Socket::IP
+
 =item Authen::SASL
 
 This module is optional.  You only need to install Authen::SASL
@@ -6,7 +6,7 @@ package Net::LDAP::Filter;
 
 use strict;
 
-our $VERSION = '0.19';
+our $VERSION = '0.20';
 
 # filter       = "(" filtercomp ")"
 # filtercomp   = and / or / not / item
@@ -28,9 +28,10 @@ our $VERSION = '0.19';
 # initial      = value
 # any          = "*" *(value "*")
 # final        = value
-# attr         = AttributeDescription from Section 4.1.5 of [1]
-# matchingrule = MatchingRuleId from Section 4.1.9 of [1]
-# value        = AttributeValue from Section 4.1.6 of [1]
+# attr         = AttributeDescription from Section 2.5 of RFC 4512
+# matchingrule = MatchingRuleId from Section 4.1.8 of RFC 4511
+# value        = AttributeValue from Section 4.1.6 of RFC 4511
+#                with some characters encoded, see below.
 #
 # Special Character encodings
 # ---------------------------
@@ -14,7 +14,7 @@ BEGIN {
     if (CHECK_UTF8);
 }
 
-our $VERSION = '0.22';
+our $VERSION = '0.26';
 
 # allow the letters r,w,a as mode letters
 my %modes = qw(r <  r+ +<  w >  w+ +>  a >>  a+ +>>);
@@ -54,10 +54,10 @@ sub new {
   }
 
   # Default the encoding of DNs to 'none' unless the user specifies
-  $opt{encode} = 'none'  unless exists $opt{encode};
+  $opt{encode} = 'none'  unless (exists $opt{encode});
 
   # Default the error handling to die
-  $opt{onerror} = 'die'  unless exists $opt{onerror};
+  $opt{onerror} = 'die'  unless (exists $opt{onerror});
 
   # sanitize options
   $opt{lowercase} ||= 0;
@@ -131,7 +131,7 @@ sub _read_lines {
 }
 
 
-# read attribute value from URL (currently only file: URLs)
+# read attribute value from URL
 sub _read_url_attribute {
   my $self = shift;
   my $url = shift;
@@ -139,26 +139,59 @@ sub _read_url_attribute {
   my $line;
 
   if ($url =~ s/^file:(?:\/\/)?//) {
-    my $fh;
-    unless (open($fh, '<', $url)) {
-      $self->_error("can't open $line: $!", @ldif);
-      return;
-    }
+    open(my $fh, '<', $url)
+      or  return $self->_error("can't open $url: $!", @ldif);
+
     binmode($fh);
     { # slurp in whole file at once
       local $/;
       $line = <$fh>;
     }
     close($fh);
-  } else {
-    $self->_error('unsupported URL type', @ldif);
-    return;
+  }
+  elsif ($url =~ /^(https?|ftp|gopher|news:)/ and
+         eval { require LWP::UserAgent; }) {
+    my $ua = LWP::UserAgent->new();
+    my $response = $ua->get($url);
+
+    return $self->_error("can't get data from $url: $!", @ldif)
+      if (!$response->is_success);
+
+    $line = $response->decoded_content();
+
+    return $self->error("decoding data from $url failed: $@", @ldif)
+      if (!defined($line));
+  }
+  else {
+    return $self->_error('unsupported URL type', @ldif);
   }
 
   $line;
 }
 
 
+# read attribute value (decode it based in its type)
+sub _read_attribute_value {
+  my $self = shift;
+  my $type = shift;
+  my $value = shift;
+  my @ldif = @_;
+
+  # Base64-encoded value: decode it
+  if ($type && $type eq ':') {
+    require MIME::Base64;
+    $value = MIME::Base64::decode($value);
+  }
+  # URL value: read from URL
+  elsif ($type && $type eq '<' and $value =~ s/^(.*?)\s*$/$1/) {
+    $value = $self->_read_url_attribute($value, @ldif);
+    return  if (!defined($value));
+  }
+
+  $value;
+}
+
+
 # _read_one() is deprecated and will be removed
 # in a future version
 *_read_one = \&_read_entry;
@@ -179,24 +212,20 @@ sub _read_entry {
     $self->{version} = $1;
     shift @ldif;
     return $self->_read_entry
-      unless @ldif;
+      unless (@ldif);
   }
 
   if (@ldif < 1) {
-     $self->_error('LDIF entry is not valid', @ldif);
-     return;
+     return $self->_error('LDIF entry is not valid', @ldif);
   }
-  elsif (not ( $ldif[0] =~ s/^dn:(:?) *//) ) {
-     $self->_error('First line of LDIF entry does not begin with "dn:"', @ldif);
-     return;
+  elsif ($ldif[0] !~ /^dn::? */) {
+     return $self->_error('First line of LDIF entry does not begin with "dn:"', @ldif);
   }
 
   my $dn = shift @ldif;
+  my $xattr = $1  if ($dn =~ s/^dn:(:?) *//);
 
-  if (length($1)) {	# $1 is the optional colon from above
-    require MIME::Base64;
-    $dn = MIME::Base64::decode($dn);
-  }
+  $dn = $self->_read_attribute_value($xattr, $dn, @ldif);
 
   my $entry = Net::LDAP::Entry->new;
   $dn = Encode::decode_utf8($dn)
@@ -211,19 +240,19 @@ sub _read_entry {
 
     if ($control =~ /^control:\s*(\d+(?:\.\d+)*)(?:\s+(true|false))?(?:\s*\:(.*))?$/) {
       my($oid,$critical,$value) = ($1,$2,$3);
-      my $prefix = $1  if (defined($value) && $value =~ s/^([\<\:])\s*//);
 
       $critical = ($critical && $critical =~ /true/) ? 1 : 0;
 
-      # base64 encoded value: decode it
-      if ($prefix && $prefix eq ':') {
-        require MIME::Base64;
-        $value = MIME::Base64::decode($value);
-      }
-      # url value: read in file:// url, fail on others
-      elsif ($prefix && $prefix eq '<' and $value =~ s/^(.*?)\s*$/$1/) {
-        $value = $self->_read_url_attribute($value, @ldif);
-        return  if !defined($value);
+      if (defined($value)) {
+        my $type = $1  if ($value =~ s/^([\<\:])\s*//);
+
+        $value =~ s/^\s*//;
+
+        if ($type) {
+          $value = $self->_read_attribute_value($type, $value, @ldif);
+          return $self->_error('Illegal value in control line given', @ldif)
+            if !defined($value);
+        }
       }
 
       require Net::LDAP::Control;
@@ -233,146 +262,118 @@ sub _read_entry {
 
       push(@controls, $ctrl);
 
-      if (!@ldif) {
-        $self->_error('Illegally formatted control line given', @ldif);
-        return;
-      }
+      return $self->_error('Illegally formatted control line given', @ldif)
+        if (!@ldif);
     }
     else {
-      $self->_error('Illegally formatted control line given', @ldif);
-      return;
+      return $self->_error('Illegally formatted control line given', @ldif);
     }
   }
 
+  # LDIF change record
   if ((scalar @ldif) && ($ldif[0] =~ /^changetype:\s*/)) {
     my $changetype = $ldif[0] =~ s/^changetype:\s*//
         ? shift(@ldif) : $self->{changetype};
     $entry->changetype($changetype);
 
-    return $entry  if ($changetype eq 'delete');
-
-    unless (@ldif) {
-      $self->_error('LDAP entry is not valid', @ldif);
-      return;
+    if ($changetype eq 'delete') {
+      return $self->_error('LDIF "delete" entry is not valid', @ldif)
+        if (@ldif);
+      return $entry;
     }
 
-    while(@ldif) {
-      my $modify = $self->{modify};
+    return $self->_error('LDAP entry is not valid', @ldif)
+      unless (@ldif);
+
+    while (@ldif) {
+      my $action = $self->{modify};
       my $modattr;
       my $lastattr;
-      if($changetype eq 'modify') {
-        unless ( (my $tmp = shift @ldif) =~ s/^(add|delete|replace|increment):\s*([-;\w]+)// ) {
-          $self->_error('LDAP entry is not valid', @ldif);
-          return;
+      my @values;
+
+      if ($changetype eq 'modify') {
+        unless ((my $tmp = shift @ldif) =~ s/^(add|delete|replace|increment):\s*([-;\w]+)//) {
+          return $self->_error('LDAP entry is not valid', @ldif);
         }
         $lastattr = $modattr = $2;
-        $modify  = $1;
+        $action = $1;
       }
-      my @values;
-      while(@ldif) {
+
+      while (@ldif) {
         my $line = shift @ldif;
-        my $attr;
-	my $xattr;
 
         if ($line eq '-') {
-          if (defined $lastattr) {
-	    if (CHECK_UTF8 && $self->{raw}) {
-  	      map { $_ = Encode::decode_utf8($_) } @values
-	        if ($lastattr !~ /$self->{raw}/);
-	    }
-            $entry->$modify($lastattr, \@values);
-	  }
-          undef $lastattr;
-          @values = ();
+          return $self->_error('LDAP entry is not valid', @ldif)
+            if (!defined($modattr) || !defined($lastattr));
+
           last;
         }
 
-        $line =~ s/^([-;\w]+):([\<\:]?)\s*// and
-	    ($attr, $xattr) = ($1, $2);
+        if ($line =~ /^([-;\w]+):([\<\:]?)\s*(.*)$/o) {
+          my ($attr,$xattr,$val) = ($1,$2,$3);
 
-        # base64 encoded attribute: decode it
-        if ($xattr eq ':') {
-          require MIME::Base64;
-          $line = MIME::Base64::decode($line);
-        }
-        # url attribute: read in file:// url, fail on others
-        elsif ($xattr eq '<' and $line =~ s/^(.*?)\s*$/$1/) {
-          $line = $self->_read_url_attribute($line, @ldif);
-          return  if !defined($line);
-        }
+          return $self->_error('LDAP entry is not valid', @ldif)
+            if (defined($modattr) && $attr ne $modattr);
 
-        if( defined($modattr) && $attr ne $modattr ) {
-          $self->_error('LDAP entry is not valid', @ldif);
-          return;
-        }
+          $val = $self->_read_attribute_value($xattr, $val, $line)
+            if ($xattr);
+          return  if !defined($val);
 
-        if(!defined($lastattr) || $lastattr ne $attr) {
-          if (defined $lastattr) {
-	    if (CHECK_UTF8 && $self->{raw}) {
-  	      map { $_ = Encode::decode_utf8($_) } @values
-	        if ($lastattr !~ /$self->{raw}/);
-	    }
-            $entry->$modify($lastattr, \@values);
-	  }
-          $lastattr = $attr;
-          @values = ($line);
-          next;
+          $val = Encode::decode_utf8($val)
+            if (CHECK_UTF8 && $self->{raw} && ($attr !~ /$self->{raw}/));
+
+          if (!defined($lastattr) || $lastattr ne $attr) {
+            $entry->$action($lastattr => \@values)
+              if (defined $lastattr);
+
+            $lastattr = $attr;
+            @values = ();
+          }
+          push(@values, $val);
         }
-        push @values, $line;
-      }
-      if (defined $lastattr) {
-        if (CHECK_UTF8 && $self->{raw}) {
-  	  map { $_ = Encode::decode_utf8($_) } @values
-	    if ($lastattr !~ /$self->{raw}/);
+        else {
+          return $self->_error('LDAP entry is not valid', @ldif);
         }
-        $entry->$modify($lastattr, \@values);
       }
+      $entry->$action($lastattr => \@values)
+        if (defined $lastattr);
     }
   }
-
+  # content record (i.e. no 'changetype' line; implicitly treated as 'add')
   else {
-    my @attr;
     my $last = '';
-    my $vals = [];
-    my $attr;
-    my $xattr;
+    my @values;
 
-    if (@controls) {
-      $self->_error("Controls only allowed with LDIF change entries", @ldif);
-      return;
-    }
+    return $self->_error('Controls only allowed with LDIF change entries', @ldif)
+      if (@controls);
 
     foreach my $line (@ldif) {
-      $line =~ s/^([-;\w]+):([\<\:]?)\s*// &&
-	  (($attr, $xattr) = ($1, $2)) or next;
+      if ($line =~ /^([-;\w]+):([\<\:]?)\s*(.*)$/o) {
+        my($attr,$xattr,$val) = ($1,$2,$3);
 
-      # base64 encoded attribute: decode it
-      if ($xattr eq ':') {
-        require MIME::Base64;
-        $line = MIME::Base64::decode($line);
-      }
-      # url attribute: read in file:// url, fail on others
-      elsif ($xattr eq '<' and $line =~ s/^(.*?)\s*$/$1/) {
-        $line = $self->_read_url_attribute($line, @ldif);
-        return  if !defined($line);
-      }
+        $last = $attr  if (!$last);
 
-      if (CHECK_UTF8 && $self->{raw}) {
-        $line = Encode::decode_utf8($line)
-          if ($attr !~ /$self->{raw}/);
-      }
+        $val = $self->_read_attribute_value($xattr, $val, $line)
+          if ($xattr);
+        return  if !defined($val);
+
+        $val = Encode::decode_utf8($val)
+          if (CHECK_UTF8 && $self->{raw} && ($attr !~ /$self->{raw}/));
 
-      if ($attr eq $last) {
-        push @$vals, $line;
-        next;
+        if ($attr ne $last) {
+          $entry->add($last => \@values);
+          @values = ();
+          $last = $attr;
+        }
+        push(@values, $val);
       }
       else {
-        $vals = [$line];
-        push(@attr, $last=$attr, $vals);
+        return $self->_error("illegal LDIF line '$line'", @ldif);
       }
     }
-    $entry->add(@attr);
+    $entry->add($last => \@values);
   }
+
   $self->{_current_entry} = $entry;
 
   $entry;
@@ -381,10 +382,9 @@ sub _read_entry {
 sub read_entry {
   my $self = shift;
 
-  unless ($self->{fh}) {
-     $self->_error('LDIF file handle not valid');
-     return;
-  }
+  return $self->_error('LDIF file handle not valid')
+    unless ($self->{fh});
+
   $self->_read_entry();
 }
 
@@ -396,7 +396,7 @@ sub read {
   return $self->read_entry()  unless wantarray;
 
   my($entry, @entries);
-  push(@entries, $entry)  while $entry = $self->read_entry;
+  push(@entries, $entry)  while ($entry = $self->read_entry);
 
   @entries;
 }
@@ -405,18 +405,17 @@ sub eof {
   my $self = shift;
   my $eof = shift;
 
-  if ($eof) {
-    $self->{_eof} = $eof;
-  }
+  $self->{_eof} = $eof
+    if ($eof);
 
   $self->{_eof};
 }
 
 sub _wrap {
-  my $len=int($_[1]);	# needs to be >= 2 to avoid division by zero
-  return $_[0]  if length($_[0]) <= $len or $len <= 40;
+  my $len = int($_[1]);	# needs to be >= 2 to avoid division by zero
+  return $_[0]  if (length($_[0]) <= $len or $len <= 40);
   use integer;
-  my $l2 = $len-1;
+  my $l2 = $len - 1;
   my $x = (length($_[0]) - $len) / $l2;
   my $extra = (length($_[0]) == ($l2 * $x + $len)) ? '' : 'a*';
   join("\n ", unpack("a$len" . "a$l2" x $x . $extra, $_[0]));
@@ -433,6 +432,7 @@ sub _write_attr {
 
     $v = Encode::encode_utf8($v)
       if (CHECK_UTF8 and Encode::is_utf8($v));
+
     if ($v =~ /(^[ :<]|[\x00-\x1f\x7f-\xff]| $)/) {
       require MIME::Base64;
       $ln .= ':: ' . MIME::Base64::encode($v, '');
@@ -465,6 +465,34 @@ sub _write_attrs {
   $res;
 }
 
+sub _write_controls {
+  my($self, @ctrls) = @_;
+  my $res = 1;
+  my $fh = $self->{fh};
+
+  require Net::LDAP::Control;
+
+  foreach my $ctrl (@ctrls) {
+    my $ln = 'control: ' . $ctrl->type . ($ctrl->critical ? ' true' : ' false');
+    my $v = $ctrl->value;
+
+    if (defined($v)) {
+      $v = Encode::encode_utf8($v)
+        if (CHECK_UTF8 and Encode::is_utf8($v));
+
+      if ($v =~ /(^[ :<]|[\x00-\x1f\x7f-\xff]| $)/) {
+        require MIME::Base64;
+        $v = MIME::Base64::encode($v, '');
+        $ln .= ':';	# indicate Base64-encoding of $v
+      }
+
+      $ln .= ': ' . $v;
+    }
+    $res &&= print $fh _wrap($ln, $self->{wrap}), "\n";
+  }
+  $res;
+}
+
 sub _write_dn {
   my($self, $dn) = @_;
   my $encode = $self->{encode};
@@ -472,6 +500,7 @@ sub _write_dn {
 
   $dn = Encode::encode_utf8($dn)
     if (CHECK_UTF8 and Encode::is_utf8($dn));
+
   if ($dn =~ /^[ :<]|[\x00-\x1f\x7f-\xff]/) {
     if ($encode =~ /canonical/i) {
       require Net::LDAP::Util;
@@ -480,13 +509,16 @@ sub _write_dn {
       # are special in LDIF, so we fix those up here.
       $dn =~ s/^([ :<])/\\$1/;
       $dn = "dn: $dn";
-    } elsif ($encode =~ /base64/i) {
+    }
+    elsif ($encode =~ /base64/i) {
       require MIME::Base64;
       $dn = 'dn:: ' . MIME::Base64::encode($dn, '');
-    } else {
+    }
+    else {
       $dn = "dn: $dn";
     }
-  } else {
+  }
+  else {
     $dn = "dn: $dn";
   }
   print $fh _wrap($dn, $self->{wrap}), "\n";
@@ -522,76 +554,108 @@ sub _write_entry {
   my $self = shift;
   my $change = shift;
   my $res = 1;	# result value
-  local($\, $,); # output field and record separators
+  my @args = ();
+
+  return $self->_error('LDIF file handle not valid')
+    unless ($self->{fh});
+
+  # parse list of entries optionally interspersed with lists of option pairs
+  # each option-pair list belongs to the preceding entry
+  #  e.g. $entry1, control => $ctrl1, $entry2, $entry3, control => [ $ctrl3a, $ctrl3b ], ...
+  foreach my $elem (@_) {
+    if (ref($elem)) {
+      if (scalar(@args) % 2) {    # odd number of args: $entry + optional args
+        $res &&= $self->_write_one($change, @args);
+        @args = ();
+      }
+    }
+    elsif (!@args) {	# 1st arg needs to be an N:L:E object
+      $self->_error("Entry '$elem' is not a valid Net::LDAP::Entry object.");
+      $res = 0;
+      @args = ();
+      next;	# try to re-sync
+    }
 
-  unless ($self->{fh}) {
-     $self->_error('LDIF file handle not valid');
-     return;
+    push(@args, $elem);
   }
 
-  my $fh = $self->{fh};
+  if (scalar(@args) % 2) {
+    $res &&= $self->_write_one($change, @args);
+  }
+  elsif (@args) {
+    $self->error("Illegal argument list passed");
+    $res = 0;
+  }
 
-  foreach my $entry (@_) {
-    unless (ref $entry) {
-       $self->_error("Entry '$entry' is not a valid Net::LDAP::Entry object.");
-       $res = 0;
-       next;
-    }
+  $self->_error($!)  if (!$res && $!);
 
-    if ($change) {
-      my @changes = $entry->changes;
-      my $type = $entry->changetype;
+  $res;
+}
 
-      # Skip entry if there is nothing to write
-      next  if $type eq 'modify' and !@changes;
+# internal helper to write exactly one entry
+sub _write_one
+{
+  my $self = shift;
+  my $change = shift;
+  my $entry = shift;
+  my %opt = @_;
+  my $fh = $self->{fh};
+  my $res = 1;	# result value
+  local($\, $,); # output field and record separators
 
-      $res &&= $self->write_version()  unless $self->{write_count}++;
-      $res &&= print $fh "\n";
-      $res &&= $self->_write_dn($entry->dn);
+  if ($change) {
+    my @changes = $entry->changes;
+    my $type = $entry->changetype;
 
-      $res &&= print $fh "changetype: $type\n";
+    # Skip entry if there is nothing to write
+    return $res  if ($type eq 'modify' and !@changes);
 
-      if ($type eq 'delete') {
-        next;
-      }
-      elsif ($type eq 'add') {
-        $res &&= $self->_write_attrs($entry);
-        next;
-      }
-      elsif ($type =~ /modr?dn/o) {
-        my $deleteoldrdn = $entry->get_value('deleteoldrdn') || 0;
-        $res &&= $self->_write_attr('newrdn', $entry->get_value('newrdn', asref => 1));
-        $res &&= print $fh 'deleteoldrdn: ', $deleteoldrdn, "\n";
-        my $ns = $entry->get_value('newsuperior', asref => 1);
-        $res &&= $self->_write_attr('newsuperior', $ns)  if defined $ns;
-        next;
-      }
+    $res &&= $self->write_version()  unless ($self->{write_count}++);
+    $res &&= print $fh "\n";
+    $res &&= $self->_write_dn($entry->dn);
 
-      my $dash=0;
-      foreach my $chg (@changes) {
-        unless (ref($chg)) {
-          $type = $chg;
-          next;
-        }
-        my $i = 0;
-        while ($i < @$chg) {
-	  $res &&= print $fh "-\n"  if (!$self->{version} && $dash++);
-          my $attr = $chg->[$i++];
-          my $val = $chg->[$i++];
-          $res &&= print $fh $type, ': ', $attr, "\n";
-          $res &&= $self->_write_attr($attr, $val);
-	  $res &&= print $fh "-\n"  if ($self->{'version'});
-        }
-      }
-    }
+    $res &&= $self->_write_controls(ref($opt{control}) eq 'ARRAY'
+                                    ? @{$opt{control}}
+                                    : ( $opt{control} ))
+      if ($opt{control});
 
-    else {
-      $res &&= $self->write_version()  unless $self->{write_count}++;
-      $res &&= print $fh "\n";
-      $res &&= $self->_write_dn($entry->dn);
+    $res &&= print $fh "changetype: $type\n";
+
+    if ($type eq 'delete') {
+      return $res;
+    }
+    elsif ($type eq 'add') {
       $res &&= $self->_write_attrs($entry);
+      return $res;
+    }
+    elsif ($type =~ /modr?dn/o) {
+      my $deleteoldrdn = $entry->get_value('deleteoldrdn') || 0;
+      $res &&= $self->_write_attr('newrdn', $entry->get_value('newrdn', asref => 1));
+      $res &&= print $fh 'deleteoldrdn: ', $deleteoldrdn, "\n";
+      my $ns = $entry->get_value('newsuperior', asref => 1);
+      $res &&= $self->_write_attr('newsuperior', $ns)  if (defined $ns);
+      return $res;
+    }
+
+    my $dash = 0;
+    # changetype: modify
+    while (my($action,$attrs) = splice(@changes, 0, 2)) {
+      my @attrs = @$attrs;
+
+      while (my($attr,$val) = splice(@attrs, 0, 2)) {
+        $res &&= print $fh "-\n"  if (!$self->{version} && $dash++);
+        $res &&= print $fh "$action: $attr\n";
+        $res &&= $self->_write_attr($attr, $val);
+        $res &&= print $fh "-\n"  if ($self->{version});
+      }
     }
   }
+  else {
+    $res &&= $self->write_version()  unless ($self->{write_count}++);
+    $res &&= print $fh "\n";
+    $res &&= $self->_write_dn($entry->dn);
+    $res &&= $self->_write_attrs($entry);
+  }
 
   $res;
 }
@@ -604,7 +668,7 @@ sub read_cmd {
   return $self->read_entry()  unless wantarray;
 
   my($entry, @entries);
-  push(@entries, $entry)  while $entry = $self->read_entry;
+  push(@entries, $entry)  while ($entry = $self->read_entry);
 
   @entries;
 }
@@ -624,12 +688,13 @@ sub write_cmd {
 sub done {
   my $self = shift;
   my $res = 1;	# result value
+
   if ($self->{fh}) {
-     if ($self->{opened_fh}) {
-       $res = close $self->{fh};
-       undef $self->{opened_fh};
-     }
-     delete $self->{fh};
+    if ($self->{opened_fh}) {
+      $res = close($self->{fh});
+      undef $self->{opened_fh};
+    }
+    delete $self->{fh};
   }
   $res;
 }
@@ -655,16 +720,19 @@ my %onerror = (
   undef => sub {
                 my $self = shift;
                 require Carp;
-                Carp::carp($self->error(@_))  if $^W;
+                Carp::carp($self->error(@_))  if ($^W);
              },
 );
 
 sub _error {
-   my ($self, $errmsg, @errlines) = @_;
-   $self->{_err_msg} = $errmsg;
-   $self->{_err_lines} = join "\n", @errlines;
+  my ($self, $errmsg, @errlines) = @_;
+  $self->{_err_msg} = $errmsg;
+  $self->{_err_lines} = join("\n", @errlines);
+
+  scalar &{ $onerror{ $self->{onerror} } }($self, $self->{_err_msg})
+    if ($self->{onerror});
 
-   scalar &{ $onerror{ $self->{onerror} } }($self, $self->{_err_msg})  if $self->{onerror};
+  return;
 }
 
 sub _clear_error {
@@ -696,7 +764,7 @@ sub current_lines {
 
 sub version {
   my $self = shift;
-  return $self->{version}  unless @_;
+  return $self->{version}  unless (@_);
   $self->{version} = shift || 0;
 }
 
@@ -29,6 +29,18 @@ As when reading an entire file into memory with perl normally, take
 into account the possibility of memory use when loading an LDIF file
 in one go.
 
+
+=head1 SPECIAL FEATURES
+
+By default, Net::LDAP::LDIF supports reading attribute values from
+URLs of type C<file://>.
+
+When Gisle Aas' L<LWP> module package is installed, Net::LDAP::LDIF uses
+it to also support reading data from the URL types supported by these
+modules; most prominently C<http://>, C<https://>, and C<ftp://> resources.
+This extended feature is dynamically detected at runtime.
+
+
 =head1 CONSTRUCTOR
 
 =over 4
@@ -128,15 +140,14 @@ Default is 78. Setting it to 40 or lower inhibits wrapping.
 =item raw =E<gt> REGEX
 
 Use REGEX to denote the names of attributes that are to be considered
-binary in search results.
+binary when reading.
 
-When running on Perl 5.8 and this option is given Net::LDAP converts all
+When this option is given, Net::LDAP converts all
 values of attributes not matching this REGEX into Perl UTF-8 strings
 so that the regular Perl operators (pattern matching, ...) can operate
 as one expects even on strings with international characters.
 
-If this option is not given or the version of Perl Net::LDAP is running on
-is too old strings are encoded the same as in earlier versions of perl-ldap.
+If this option is not given, attribute values are treated as byte strings.
 
 Example: raw =E<gt> qr/(?i:^jpegPhoto|;binary)/
 
@@ -157,9 +168,24 @@ object.
 
 Returns I<true> when the end of the file is reached.
 
-=item write_entry ( ENTRIES )
+=item write_entry ( ENTRY [, OPTIONS ], ... )
+
+Write entries to the LDIF file.
+
+The arguments accepted are a list of entries, optionally interspersed with
+options belonging to the preceding entry.
 
-Write the entries to the LDIF file.
+For each entry, C<OPTIONS> is a list of key-value pairs, recognizing:
+
+=over 4
+
+=item control =E<gt> CONTROL
+
+=item control =E<gt> [ CONTROL, ... ]
+
+See L<Net::LDAP/CONTROLS>.
+
+=back
 
 =item write_version ( )
 
@@ -36,14 +36,11 @@ The code value in the result message from the server. Normally for a
 success zero will be returned. Constants for the result codes can be
 imported from the L<Net::LDAP> or L<Net::LDAP::Constant> module.
 
-=item control ( )
+=item control ( [ OID, ... ] )
 
-Return a list of controls that were returned from the server.
-
-=item control ( OID, ... )
-
-Return a list of controls with the given OIDs that were returned from
-the server.
+Return the list of controls that were returned from the server.
+If one or more OIDs are given as arguments, return only the controls
+of the OIDs given.
 
 =item dn ( )
 
@@ -59,7 +59,7 @@ our %EXPORT_TAGS = (
 	time	=> [ qw(generalizedTime_to_time time_to_generalizedTime) ],
 );
 
-our $VERSION = '0.18';
+our $VERSION = '0.19';
 
 =item ldap_error_name ( ERR )
 
@@ -753,7 +753,7 @@ my $generalizedTime = shift;
 
     # Time::Local's timegm() interpret years strangely
     if ($year >= 1000) {
-      $dec = "0.$dec";
+      $dec = defined($dec) ? "0.$dec" : 0;
 
       # decimals in case of missing minutes / seconds - see RFC 4517
       if (!defined($min)) {
@@ -790,12 +790,15 @@ my $generalizedTime = shift;
 
           # make decimal part directional
           if ($dec != 0) {
+            my $sign = '';
+
             if ($time < 0) {
               $dec = 1 - $dec;
               $time++; 
+              $sign = '-'  if ($time == 0);
             }
             $dec =~ s/^0\.//;
-            $time .= ".$dec";
+            $time = "${sign}${time}.${dec}";
           }
 
           return $time;
@@ -830,7 +833,7 @@ Returns the generalizedTime string, or C<undef> on error.
 Times before BC or after year 9999 result in C<undef>
 as they cannot be represented in the generalizedTime format.
 
-B<Note:> this function depends on  Perl's implementation of gmtime.
+B<Note:> this function depends on Perl's implementation of gmtime.
 See L<Time::Local/Limits of time_t>, L<Time::Local/Negative Epoch Values>, and
 L<perlport/gmtime> for restrictions in older versions of Perl.
 
@@ -841,19 +844,20 @@ sub time_to_generalizedTime($;@)
 my $arg = shift;
 my %opt = @_;
 
-  if ($arg =~ /^(\-?\d*)(?:[.,](\d*))?$/) {
-    my ($time, $dec) = ($1, $2);
+  if ($arg =~ /^(\-?)(\d*)(?:[.,](\d*))?$/) {
+    my ($sign, $time, $dec) = ($1, $2, $3);
 
     $dec = defined($dec) ? "0.$dec" : 0;
 
     # decimal part of time is directional: make sure to have it positive
-    if ($time < 0 && $dec != 0) {
-      $time--;
-      $dec = 1 - $dec;
+    if ($sign) {
+      if ($dec != 0) {
+        $time++;
+        $dec = 1 - $dec;
+      }
+      $time = -$time;
     }
 
-    $time = int($time);
-
     my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = gmtime(int($time));
 
     # generalizedTime requires 4-digit year without sign
@@ -28,9 +28,14 @@ use Net::LDAP::Constant qw(LDAP_SUCCESS
 			   LDAP_UNAVAILABLE
 			);
 
-use constant CAN_IPV6 => eval { require IO::Socket::INET6 } ? 1 : 0;
-
-our $VERSION 	= '0.58';
+# check for IPv6 support: prefer IO::Socket::IP 0.20+ over IO::Socket::INET6
+use constant CAN_IPV6 => eval { require IO::Socket::IP; IO::Socket::IP->VERSION(0.20); }
+			 ? 'IO::Socket::IP'
+			 : eval { require IO::Socket::INET6; }
+			   ? 'IO::Socket::INET6'
+			   : '';
+
+our $VERSION 	= '0.64';
 our @ISA     	= qw(Tie::StdHash Net::LDAP::Extra);
 our $LDAP_VERSION 	= 3;      # default LDAP protocol version
 
@@ -122,6 +127,7 @@ sub new {
   $obj->{net_ldap_socket}->setsockopt(SOL_SOCKET, SO_KEEPALIVE, $arg->{keepalive} ? 1 : 0)
     if (defined($arg->{keepalive}));
 
+  $obj->{net_ldap_rawsocket} = $obj->{net_ldap_socket};
   $obj->{net_ldap_resp}    = {};
   $obj->{net_ldap_version} = $arg->{version} || $LDAP_VERSION;
   $obj->{net_ldap_async}   = $arg->{async} ? 1 : 0;
@@ -140,7 +146,7 @@ sub new {
 sub connect_ldap {
   my ($ldap, $host, $arg) = @_;
   my $port = $arg->{port} || 389;
-  my $class = (CAN_IPV6) ? 'IO::Socket::INET6' : 'IO::Socket::INET';
+  my $class = (CAN_IPV6) ? CAN_IPV6 : 'IO::Socket::INET';
   my $domain = $arg->{inet4} ? AF_INET : ($arg->{inet6} ? AF_INET6 : AF_UNSPEC);
 
   # separate port from host overwriting given/default port
@@ -245,7 +251,8 @@ sub _SSL_context_init_args {
   }
 
   (
-    SSL_cipher_list     => defined $arg->{ciphers} ? $arg->{ciphers} : 'ALL',
+    defined $arg->{ciphers} ?
+      ( SSL_cipher_list => $arg->{ciphers} ) : (),
     SSL_ca_file         => exists  $arg->{cafile}  ? $arg->{cafile}  : '',
     SSL_ca_path         => exists  $arg->{capath}  ? $arg->{capath}  : '',
     SSL_key_file        => $clientcert ? $clientkey : undef,
@@ -314,8 +321,17 @@ sub debug {
     : $ldap->{net_ldap_debug};
 }
 
+sub sasl {
+  $_[0]->{sasl};
+}
+
 sub socket {
-  $_[0]->{net_ldap_socket};
+  my $ldap = shift;
+  my %opt = @_;
+
+  (exists($opt{sasl_layer}) && !$opt{sasl_layer})
+    ? $ldap->{net_ldap_rawsocket}
+    : $ldap->{net_ldap_socket};
 }
 
 sub host {
@@ -425,15 +441,16 @@ sub bind {
 
       # If we're talking to a round-robin, the canonical name of
       # the host we are talking to might not match the name we
-      # requested
+      # requested. Look at the rawsocket because SASL layer filehandles
+      # don't support socket methods.
       my $sasl_host;
 
       if (exists($arg->{sasl_host})) {
         if ($arg->{sasl_host}) {
           $sasl_host = $arg->{sasl_host};
         }
-        elsif ($ldap->{net_ldap_socket}->can('peerhost')) {
-          $sasl_host = $ldap->{net_ldap_socket}->peerhost;
+        elsif ($ldap->{net_ldap_rawsocket}->can('peerhost')) {
+          $sasl_host = $ldap->{net_ldap_rawsocket}->peerhost;
         }
       }
       $sasl_host ||= $ldap->{net_ldap_host};
@@ -452,8 +469,8 @@ sub bind {
 
     # Tell SASL the local and server IP addresses
     $sasl_conn->property(
-      sockname => $ldap->{net_ldap_socket}->sockname,
-      peername => $ldap->{net_ldap_socket}->peername,
+      sockname => $ldap->{net_ldap_rawsocket}->sockname,
+      peername => $ldap->{net_ldap_rawsocket}->peername,
     );
 
     my $initial = $sasl_conn->client_start;
@@ -849,7 +866,8 @@ sub _sendmesg {
   my $to_send = \( $mesg->pdu );
   my $offset = 0;
   while ($offset < length($$to_send)) {
-    my $n = syswrite($socket, substr($$to_send, $offset, 15000), 15000)
+    my $s = substr($$to_send, $offset, 15000);
+    my $n = syswrite($socket, $s, length($s))
       or return _error($ldap, $mesg, LDAP_LOCAL_ERROR, "$!");
     $offset += $n;
   }
@@ -940,6 +958,7 @@ sub process {
 sub _drop_conn {
   my ($self, $err, $etxt) = @_;
 
+  delete $self->{net_ldap_rawsocket};
   my $sock = delete $self->{net_ldap_socket};
   close($sock)  if $sock;
 
@@ -158,14 +158,12 @@ LDAPv2.
 Use REGEX to denote the names of attributes that are to be considered
 binary in search results.
 
-When running on Perl 5.8 and this option is given Net::LDAP converts all
+When this option is given, Net::LDAP converts all
 values of attributes not matching this REGEX into Perl UTF-8 strings
 so that the regular Perl operators (pattern matching, ...) can operate
 as one expects even on strings with international characters.
 
-If this option is not given or the version of Perl Net::LDAP is running
-on is too old strings are encoded the same as in earlier versions of
-perl-ldap.
+If this option is not given, attribute values are treated as byte strings.
 
 Example: raw =E<gt> qr/(?i:^jpegPhoto|;binary)/
 
@@ -727,13 +725,12 @@ See L</CALLBACKS> below.
 Use REGEX to denote the names of attributes that are to be considered
 binary in search results.
 
-When running on Perl 5.8 and this option is given Net::LDAP converts all
+When this option is given, Net::LDAP converts all
 values of attributes not matching this REGEX into Perl UTF-8 strings
 so that the regular Perl operators (pattern matching, ...) can operate
 as one expects even on strings with international characters.
 
-If this option is not given or the version of Perl Net::LDAP is running on
-is too old strings are encoded the same as in earlier versions of perl-ldap.
+If this option is not given, attribute values are treated as byte strings.
 
 The value provided here overwrites the value inherited from the constructor.
 
@@ -795,8 +792,8 @@ B<'tlsv1'>.
 
 Specify which subset of cipher suites are permissible for this
 connection, using the standard OpenSSL string format. The default
-value is B<'ALL'>, which permits all ciphers, even those that don't
-encrypt.
+behavior is to keep the decision on the underlying cryptographic
+library.
 
 =item clientcert =E<gt> '/path/to/cert.pem'
 
@@ -980,9 +977,34 @@ B<Example>
  # Get the attributes
  @atts = $schema->all_attributes;
 
-=item socket ( )
+=item sasl ( )
 
-Returns the underlying C<IO::Socket> object being used.
+Returns the C<Authen::SASL> object associated with the LDAP object,
+or C<undef> if there isn't.
+
+=item socket ( OPTIONS )
+
+Returns the underlying socket object being used.
+
+The exact object type returned depends on whether SASL layers are
+established.
+Without SASL layers the result is always an C<IO::Socket> object;
+with SASL layers the outcome depends on the options given:
+
+=over 4
+
+=item sasl_layer =E<gt> FLAG
+
+This option is only relevant if SASL layers are established.
+
+If it it missing or if is set to a TRUE value, then the SASL
+layer handle is returned. Depending on the SASL library used,
+the object returned is not necessarily an C<IO::Socket> object.
+
+If it exists, but is set to a value evaluating to FALSE, then the
+base C<IO::Socket> object underneath the SASL layer is returned.
+
+=back
 
 =item host ( )
 
@@ -49,8 +49,8 @@ my @entry = ($e, $ldif->read);
 
 ok($ldif->version == 1, "version == 1");
 
-Net::LDAP::LDIF->new($outfile1,"w")->write(@entry);
-Net::LDAP::LDIF->new($outfile2,"w", version => 1)->write(@entry);
+Net::LDAP::LDIF->new($outfile1,"w")->write_entry(@entry);
+Net::LDAP::LDIF->new($outfile2,"w", version => 1)->write_entry(@entry);
 
 ok(!compare_text($cmpfile1,$outfile1), $cmpfile1);
 
@@ -154,7 +154,7 @@ $outfile = "$TEMPDIR/00-out3.ldif";
 $cmpfile = "data/00-cmp2.ldif";
 
 $ldif = Net::LDAP::LDIF->new($outfile,"w");
-$ldif->write($e);
+$ldif->write_entry($e);
 $ldif->write_cmd($e);
 $ldif->done;
 ok(!compare_text($cmpfile,$outfile), $cmpfile);
@@ -0,0 +1,122 @@
+#!perl
+
+use Test::More;
+
+use Net::LDAP::Util qw(:time);
+
+# Each line consists of a OPCDODE, a RESULT, DATETIME, and a EXPECTED
+# where
+# - OPCDODE is a TESTCASE followed by a RESULT sepaated by a colon
+# - TESTCASE is the check to be performed: one of
+#     g2t   generalizedTime_to_time
+#     t2g   time_to_generalizedTime
+# - RESULT is the expected result, one of:
+#     yes   TESTCASE succeeds and matches EXPECTED
+#     no    TESTCASE succeeds, but may not match EXPECTED
+#     fail  TESTCASE failes
+# - DATETIME is a date-time combination to be checked.
+#   Depending on TESTCASE it may be either a string in LDAP's generalizedTime
+#   format or a UNIX time string denoting the seconds since the epoch,
+#   optionally extended by sub-second parts as decimal fractions
+# - EXPECTED is the expected value on successful conversion
+
+# To keep the order of tests, @tests is an array of ($filterstring => @ops) tuples
+my @tests = map { /^(g2t|t2g):(\w+)\s+(\S+)\s+(\S+)/ &&  [ $1, $2, $3, $4 ] }
+                grep(/^(:?g2t|t2g):\w+\s+\S+\s+\S+/, <DATA>);
+
+# The elements of the @testcases array are the TESTCASE prefixes described above
+my %testcases = ( g2t => "generalizedTime_to_time",
+                  t2g => "time_to_generalizedTime" );
+
+
+# calculate number of tests:
+($] >= 5.012)
+? plan tests =>  scalar(@tests) 	# @tests is a list of tests
+: plan skip_all => 'Perl version too old';
+
+
+foreach my $elem (@tests) {
+  my ($testcase, $result, $datetime, $expected) = @{$elem};
+  my $function = $testcases{$testcase};
+  my $got = &$function($datetime);
+
+  foreach ($result) {
+    /fail/  &&  ok(!defined($got), "$function('$datetime') should fail");
+    /no/   &&   is(defined($got), $expected, "$function('$datetime') should succeed");
+    /yes/   &&  is($got, $expected, "$function('$datetime') should yield $expected");
+  }
+}
+
+
+__DATA__
+
+## generalizedTime -> time
+g2t:yes		19691231235958.9Z		-1.1
+g2t:yes		19691231235959Z			-1
+g2t:yes		19691231235959.9Z		-0.1
+g2t:yes		19700101000000Z			0
+g2t:yes		19700101000000.1Z		0.1
+g2t:yes		19700101000001Z			1
+g2t:yes		19700101000001.1Z		1.1
+
+# "abbreviated" formats
+gt2:yes		196912312253.9Z			-3966
+gt2:yes		196912312254Z			-3960
+gt2:yes		1969123122.9Z			-3960
+g2t:yes		1969123123Z			-3600
+g2t:yes		1970010100Z			0
+g2t:yes		1970010101Z			3600
+gt2:yes		1970010101.1Z			3960
+gt2:yes		197001010106Z			3960
+gt2:yes		197001010106.1Z			3966
+
+# formats wih offsets
+g2t:yes		19700101000000+0130		-5400
+g2t:yes		19700101000000+01		-3600
+g2t:yes		19700101000000-01		3600
+g2t:yes		19700101000000-0130		5400
+
+## time -> generalizedTime
+t2g:yes		-1.1				19691231235958.9Z
+t2g:yes		-1				19691231235959Z
+t2g:yes		-0.1				19691231235959.9Z
+t2g:yes		0				19700101000000Z
+t2g:yes		0.1				19700101000000.1Z
+t2g:yes		1				19700101000001Z
+t2g:yes		1.1				19700101000001.1Z
+t2g:yes		-33358996800			09121123120000Z
+
+
+# illegally formatted generalizedTimes
+g2t:fail	9999				?
+g2t:fail	2013Z				?
+g2t:fail	201303Z				?
+g2t:fail	20130315Z			?
+g2t:fail	20130315000000+1		?
+g2t:fail	20130315000000+115		?
+
+# wrong date: 2013 is/was no leap year
+g2t:fail	20130229000000Z			?
+# wrong date: gap between Julian & Gregorian calendar - this really should fail
+#g2t:yes		15821013000000Z			-12219552000
+# wrong date: second out of range
+g2t:fail	20130315000060Z			?
+# wrong date: minute out of range
+g2t:fail	20130315006000Z			?
+# wrong date: hour out of range
+g2t:fail	20130315240000Z			?
+# wrong date: day out of range
+g2t:fail	20130100000000Z			?
+g2t:fail	20131232000000Z			?
+# wrong date: month out of range
+g2t:fail	20130029000000Z			?
+g2t:fail	20131329000000Z			?
+# wrong date: year out of range
+g2t:fail	-01230101000000Z		?
+g2t:fail	123450101000000Z		?
+# wrong date: year not supported by Time::Local
+g2t:fail	09991259235959Z			?
+g2t:fail	09121123120000Z			-33358996800
+
+
+# EOF
@@ -0,0 +1,39 @@
+#!perl
+
+use Test::More;
+use Net::LDAP::LDIF;
+use Net::LDAP::Entry;
+
+BEGIN { require "t/common.pl" }
+
+(eval { require LWP::UserAgent } && $HTTP_JPEG_URL && $HTTP_TEXT_URL)
+? plan tests => 4
+: plan skip_all => 'LWP::UserAgent module not installed or HTTP_JPEG_URL, HTTP_TEXT_URL not set';
+
+
+my $ldifdata = <<"LDIF";
+dn: cn=Sam One,ou=People,o=University of Michigan,c=US
+jpegPhoto:< $HTTP_JPEG_URL
+objectclass: OpenLDAPperson
+cn: Sam One
+uid: sam
+sn: One
+postalAddress:< $HTTP_TEXT_URL
+LDIF
+
+open(my $ldifhandle, '<', \$ldifdata);
+
+my $ldif = Net::LDAP::LDIF->new($ldifhandle);
+isa_ok($ldif, Net::LDAP::LDIF, "object");
+
+my $entry = $ldif->read_entry;
+isa_ok($entry, Net::LDAP::Entry, "entry");
+
+my $photo = $entry->get_value('jpegPhoto');
+ok(length($photo), 'jpegPhoto not empty');
+
+my $address = $entry->get_value('postalAddress');
+ok(length($address), 'postalAddress not empty');
+
+#print STDERR $entry->dump ."\n";
+
@@ -0,0 +1,61 @@
+#!perl
+
+use Test::More;
+use File::Compare qw(compare_text);
+
+BEGIN { require "t/common.pl" }
+
+
+plan tests => 9;
+
+
+require Net::LDAP::LDIF;
+require Net::LDAP::Control::ManageDsaIT;
+require Net::LDAP::Control::ProxyAuth;
+
+my $infile   = "data/10-in.ldif";
+my $outfile1 = "$TEMPDIR/10-out.ldif";
+my $cmpfile1 = "data/10-in.ldif";
+
+my $ldifin = Net::LDAP::LDIF->new($infile,"r");
+isa_ok($ldifin, Net::LDAP::LDIF, 'input object');
+
+my @entries = ();
+while (my $entry = $ldifin->read_entry) {
+  push(@entries, $entry);
+#  push(@entries, control => \@controls)  if (@controls);
+}
+is(scalar(@entries), 6, 'entries read');
+
+$ldifin->done;
+
+#use Data::Dumper;
+#print STDERR Dumper(@entries);
+
+my $manage = Net::LDAP::Control::ManageDsaIT->new(critical => 1);
+isa_ok($manage, Net::LDAP::Control::ManageDsaIT, "control object");
+
+my $auth1 = Net::LDAP::Control::ProxyAuth->new(authzID => 'dn:cn=me,ou=people,o=myorg.com');
+isa_ok($auth1, Net::LDAP::Control::ProxyAuth, "control object");
+
+my $auth2 = Net::LDAP::Control::ProxyAuth->new(authzID => 'dn:cn=Hägar,ou=people,o=myorg.com');
+isa_ok($auth2, Net::LDAP::Control::ProxyAuth, "control object");
+
+splice(@entries, 2, 0, control => [ $auth1 ]);
+splice(@entries, 1, 0, control => [ $manage, $auth2 ]);
+push(@entries, control => $manage);
+
+my $manage = $entries[-1];
+isa_ok($manage, Net::LDAP::Control::ManageDsaIT, "control object read");
+
+my $ldifout = Net::LDAP::LDIF->new($outfile1, 'w', change => 1);
+isa_ok($ldifout, Net::LDAP::LDIF, 'output object');
+
+# write all entres at once
+my $x = $ldifout->write_entry(@entries);
+ok($x, 'entries written');
+
+$ldifout->done;
+
+ok(!compare_text($cmpfile1,$outfile1), $cmpfile1);
+
@@ -20,8 +20,9 @@ ok($ldap, 'client with IPv4' .
 
 
 SKIP: {
-  skip('IO::Socket::INET6 not installed', 1)
-    unless (eval { require IO::Socket::INET6; });
+  skip('No IPv6 capable IO::Socket module installed', 1)
+    unless (eval { require IO::Socket::INET6; } or
+            eval { require IO::Socket::IP; IO::Socket::IP->VERSION(0.20); });
 
   $ldap = client(inet6 => 1);
   ok($ldap, 'client with IPv6' .
@@ -60,7 +60,8 @@ SKIP: {
 
   # cancel the running search => should work [may fail, as it depends on the server's speed]
   $cancel = $ldap->cancel($search);
-  ok(!$cancel->code, "cancel a running operation: " . $cancel->code . ": " . $cancel->error);
+  ok(!$cancel->code, "cancel a running operation: " . $cancel->code . ": " . $cancel->error)
+    or diag("This test may have failed because the server was too fast");
 }
 
 
@@ -13,7 +13,7 @@ BEGIN {
   # the Makefile is setup to delete temp/ when make clean is run
   $TEMPDIR  = "./temp";
   $SLAPD_SCHEMA_DIR ||= "./data";
-  $SLAPD_DB ||= 'bdb';
+  $SLAPD_DB ||= 'mdb';
   $SLAPD_MODULE_DIR ||= '';
 
   $TESTDB   = "$TEMPDIR/test-db";
@@ -18,13 +18,22 @@ $SERVER_TYPE = 'openldap';
 # Set this to the directory where your OpenLDAP schema files are located
 $SLAPD_SCHEMA_DIR = '';
 
-# OpenLDAP DB type: default is bdb, alternatives: hdb, mdb, ...
-#$SLAPD_DB = 'bdb';
+# OpenLDAP DB type: default is mdb, alternatives: hdb, bdb, ...
+#$SLAPD_DB = 'mdb';
 
 # Set this to the slapd module directory if your $SLAPD_DB is dynamically built
 # (e.g. '/usr/lib/ldap/')
 $SLAPD_MODULE_DIR = '';
 
+# for LDIF http support:
+# - set this to the value of a jpeg photo served by your web server
+#   (e.g. data/man.jpg or data/woman.jpg)
+#$HTTP_JPEG_URL = 'http://localhost/perl-ldap/jpegPhoto.jpeg';
+
+# - set this to the value of a file containing text
+#   (e.g. data/postalAddress.txt)
+#$HTTP_TEXT_URL = 'http://localhost/perl-ldap/postalAddress.txt';
+
 $EXTERNAL_TESTS = 0;
 
 1;