Code

Moving finalized
authorcajus <cajus@594d385d-05f5-0310-b6e9-bd551577e9d8>
Wed, 12 Dec 2007 11:37:51 +0000 (11:37 +0000)
committercajus <cajus@594d385d-05f5-0310-b6e9-bd551577e9d8>
Wed, 12 Dec 2007 11:37:51 +0000 (11:37 +0000)
git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@8102 594d385d-05f5-0310-b6e9-bd551577e9d8

258 files changed:
AUTHORS [deleted file]
Changelog [deleted file]
bin/mkntpasswd [deleted file]
contrib/altlinux/etc/cyrus.conf [deleted file]
contrib/altlinux/etc/gosa/gosa.conf [deleted file]
contrib/altlinux/etc/imapd.conf [deleted file]
contrib/altlinux/etc/ldap.conf [deleted file]
contrib/altlinux/etc/nsswitch.conf [deleted file]
contrib/altlinux/etc/openldap/ldap.conf [deleted file]
contrib/altlinux/etc/openldap/slapd.conf [deleted file]
contrib/altlinux/etc/postfix/main.cf [deleted file]
contrib/altlinux/etc/samba/smb.conf [deleted file]
contrib/altlinux/etc/sasl2/imapd.conf [deleted file]
contrib/altlinux/etc/sasl2/saslauthd.conf [deleted file]
contrib/altlinux/etc/services [deleted file]
contrib/altlinux/etc/squid/squid.conf [deleted file]
contrib/altlinux/init.ldif [deleted file]
contrib/daemon/arp-handler-d [deleted file]
contrib/daemon/arp-handler-d.cfg [deleted file]
contrib/daemon/debian/README.debian [deleted file]
contrib/daemon/debian/changelog [deleted file]
contrib/daemon/debian/compat [deleted file]
contrib/daemon/debian/control [deleted file]
contrib/daemon/debian/copyright [deleted file]
contrib/daemon/debian/default [deleted file]
contrib/daemon/debian/gosa-si-client.dirs [deleted file]
contrib/daemon/debian/gosa-si-client.install [deleted file]
contrib/daemon/debian/gosa-si-common.dirs [deleted file]
contrib/daemon/debian/gosa-si-common.install [deleted file]
contrib/daemon/debian/gosa-si-server.dirs [deleted file]
contrib/daemon/debian/gosa-si-server.init [deleted file]
contrib/daemon/debian/gosa-si-server.install [deleted file]
contrib/daemon/debian/rules [deleted file]
contrib/daemon/gosa-si-bus [deleted file]
contrib/daemon/gosa-si-bus.conf-template [deleted file]
contrib/daemon/gosa-si-client [deleted file]
contrib/daemon/gosa-si-client.conf-template [deleted file]
contrib/daemon/gosa-si-server [deleted file]
contrib/daemon/gosa-si-server.conf-template [deleted file]
contrib/daemon/modules/GosaPackages.pm [deleted file]
contrib/daemon/modules/ServerPackages.pm [deleted file]
contrib/daemon/tests/testGOsa.pl [deleted file]
contrib/demo.ldif [deleted file]
contrib/encodings [deleted file]
contrib/fai/README.fai [deleted file]
contrib/fai/get-debconf.sh [deleted file]
contrib/fai/get-packages.pl [deleted file]
contrib/fai/goto-fai/Makefile [deleted file]
contrib/fai/goto-fai/confdir.DEFAULT.source [deleted file]
contrib/fai/goto-fai/debian/README.debian [deleted file]
contrib/fai/goto-fai/debian/changelog [deleted file]
contrib/fai/goto-fai/debian/control [deleted file]
contrib/fai/goto-fai/debian/copyright [deleted file]
contrib/fai/goto-fai/debian/dirs [deleted file]
contrib/fai/goto-fai/debian/postrm [deleted file]
contrib/fai/goto-fai/debian/preinst [deleted file]
contrib/fai/goto-fai/debian/rules [deleted file]
contrib/fai/goto-fai/diversions/setup_harddisks [deleted file]
contrib/fai/goto-fai/faimond [deleted file]
contrib/fai/goto-fai/get_fai_dir [deleted file]
contrib/fai/goto-fai/goto-support.lib [deleted file]
contrib/fai/goto-fai/ldap2fai [deleted file]
contrib/fai/goto-fai/secret [deleted file]
contrib/fix_munged.php [deleted file]
contrib/gosa.conf [deleted file]
contrib/gosa.spec [deleted file]
contrib/keyboardLayouts [deleted file]
contrib/latex2html [deleted file]
contrib/mysql/README [deleted file]
contrib/mysql/glpi/glpi.sql [deleted file]
contrib/mysql/gofax/gofax.sql [deleted file]
contrib/mysql/gofon/gofon.sql [deleted file]
contrib/mysql/golog/golog.sql [deleted file]
contrib/mysql/logging/logging.sql [deleted file]
contrib/openldap/apple.schema.README [deleted file]
contrib/openldap/dhcp.schema [deleted file]
contrib/openldap/dnszone.schema [deleted file]
contrib/openldap/fai.schema [deleted file]
contrib/openldap/glpi.schema [deleted file]
contrib/openldap/goconfig.schema [deleted file]
contrib/openldap/gofax.schema [deleted file]
contrib/openldap/gofirewall.schema [deleted file]
contrib/openldap/gofon.schema [deleted file]
contrib/openldap/gosa+samba3.schema [deleted file]
contrib/openldap/gosa.schema [deleted file]
contrib/openldap/goserver.schema [deleted file]
contrib/openldap/gosystem.schema [deleted file]
contrib/openldap/goto-mime.schema [deleted file]
contrib/openldap/goto.schema [deleted file]
contrib/openldap/hdb.schema [deleted file]
contrib/openldap/kolab2.schema [deleted file]
contrib/openldap/nagios.schema [deleted file]
contrib/openldap/openxchange.schema [deleted file]
contrib/openldap/phpgwaccount.schema [deleted file]
contrib/openldap/phpscheduleit.schema [deleted file]
contrib/openldap/pptp.schema [deleted file]
contrib/openldap/pureftpd.schema [deleted file]
contrib/openldap/rfc2307bis.schema [deleted file]
contrib/openldap/rfc2739.schema [deleted file]
contrib/openldap/samba.schema [deleted file]
contrib/openldap/samba3.schema [deleted file]
contrib/openldap/slapd.conf [deleted file]
contrib/openldap/trust.schema [deleted file]
contrib/opensides/README.OpenSides [deleted file]
contrib/opensides/glpi.README [deleted file]
contrib/opensides/goNagios.pl [deleted file]
contrib/opensides/goSamba.pl [deleted file]
contrib/opensides/nagios.README [deleted file]
contrib/opensides/phpscheduleit.README [deleted file]
contrib/opensides/pptp.README [deleted file]
contrib/opensides/xls-export.README [deleted file]
contrib/openxchange/README.openxchange [deleted file]
contrib/patches/imap-2001a-quota.patch [deleted file]
contrib/patches/php4-imap-getacl.patch [deleted file]
contrib/resolutions [deleted file]
contrib/scripts/README [deleted file]
contrib/scripts/goAgent.pl [deleted file]
contrib/scripts/goQuota.pl [deleted file]
contrib/scripts/goQuotaView.pl [deleted file]
contrib/scripts/goSquid.pl [deleted file]
contrib/scripts/gosa [deleted file]
contrib/scripts/mkHash.pl [deleted file]
contrib/scripts/net-resolver.sh [deleted file]
contrib/scripts/sieve_vacation/IMAP/Sieve.pm [deleted file]
contrib/scripts/sieve_vacation/update-vacation.pl [deleted file]
contrib/shells [deleted file]
contrib/socket_server/client.php [deleted file]
contrib/socket_server/server.php [deleted file]
contrib/vacation_example.txt [deleted file]
gosa-core/AUTHORS [new file with mode: 0644]
gosa-core/Changelog [new file with mode: 0644]
gosa-core/bin/mkntpasswd [new file with mode: 0755]
gosa-core/contrib/altlinux/etc/cyrus.conf [new file with mode: 0644]
gosa-core/contrib/altlinux/etc/gosa/gosa.conf [new file with mode: 0644]
gosa-core/contrib/altlinux/etc/imapd.conf [new file with mode: 0644]
gosa-core/contrib/altlinux/etc/ldap.conf [new file with mode: 0644]
gosa-core/contrib/altlinux/etc/nsswitch.conf [new file with mode: 0644]
gosa-core/contrib/altlinux/etc/openldap/ldap.conf [new file with mode: 0644]
gosa-core/contrib/altlinux/etc/openldap/slapd.conf [new file with mode: 0644]
gosa-core/contrib/altlinux/etc/postfix/main.cf [new file with mode: 0644]
gosa-core/contrib/altlinux/etc/samba/smb.conf [new file with mode: 0644]
gosa-core/contrib/altlinux/etc/sasl2/imapd.conf [new file with mode: 0644]
gosa-core/contrib/altlinux/etc/sasl2/saslauthd.conf [new file with mode: 0644]
gosa-core/contrib/altlinux/etc/services [new file with mode: 0644]
gosa-core/contrib/altlinux/etc/squid/squid.conf [new file with mode: 0644]
gosa-core/contrib/altlinux/init.ldif [new file with mode: 0644]
gosa-core/contrib/daemon/arp-handler-d [new file with mode: 0755]
gosa-core/contrib/daemon/arp-handler-d.cfg [new file with mode: 0644]
gosa-core/contrib/daemon/debian/README.debian [new file with mode: 0644]
gosa-core/contrib/daemon/debian/changelog [new file with mode: 0644]
gosa-core/contrib/daemon/debian/compat [new file with mode: 0644]
gosa-core/contrib/daemon/debian/control [new file with mode: 0644]
gosa-core/contrib/daemon/debian/copyright [new file with mode: 0644]
gosa-core/contrib/daemon/debian/default [new file with mode: 0644]
gosa-core/contrib/daemon/debian/gosa-si-client.dirs [new file with mode: 0644]
gosa-core/contrib/daemon/debian/gosa-si-client.install [new file with mode: 0644]
gosa-core/contrib/daemon/debian/gosa-si-common.dirs [new file with mode: 0644]
gosa-core/contrib/daemon/debian/gosa-si-common.install [new file with mode: 0644]
gosa-core/contrib/daemon/debian/gosa-si-server.dirs [new file with mode: 0644]
gosa-core/contrib/daemon/debian/gosa-si-server.init [new file with mode: 0755]
gosa-core/contrib/daemon/debian/gosa-si-server.install [new file with mode: 0644]
gosa-core/contrib/daemon/debian/rules [new file with mode: 0755]
gosa-core/contrib/daemon/gosa-si-bus [new file with mode: 0755]
gosa-core/contrib/daemon/gosa-si-bus.conf-template [new file with mode: 0644]
gosa-core/contrib/daemon/gosa-si-client [new file with mode: 0755]
gosa-core/contrib/daemon/gosa-si-client.conf-template [new file with mode: 0644]
gosa-core/contrib/daemon/gosa-si-server [new file with mode: 0755]
gosa-core/contrib/daemon/gosa-si-server.conf-template [new file with mode: 0644]
gosa-core/contrib/daemon/modules/GosaPackages.pm [new file with mode: 0644]
gosa-core/contrib/daemon/modules/ServerPackages.pm [new file with mode: 0644]
gosa-core/contrib/daemon/tests/testGOsa.pl [new file with mode: 0644]
gosa-core/contrib/demo.ldif [new file with mode: 0644]
gosa-core/contrib/encodings [new file with mode: 0755]
gosa-core/contrib/fai/README.fai [new file with mode: 0644]
gosa-core/contrib/fai/get-debconf.sh [new file with mode: 0755]
gosa-core/contrib/fai/get-packages.pl [new file with mode: 0755]
gosa-core/contrib/fai/goto-fai/Makefile [new file with mode: 0644]
gosa-core/contrib/fai/goto-fai/confdir.DEFAULT.source [new file with mode: 0755]
gosa-core/contrib/fai/goto-fai/debian/README.debian [new file with mode: 0644]
gosa-core/contrib/fai/goto-fai/debian/changelog [new file with mode: 0644]
gosa-core/contrib/fai/goto-fai/debian/control [new file with mode: 0644]
gosa-core/contrib/fai/goto-fai/debian/copyright [new file with mode: 0644]
gosa-core/contrib/fai/goto-fai/debian/dirs [new file with mode: 0644]
gosa-core/contrib/fai/goto-fai/debian/postrm [new file with mode: 0755]
gosa-core/contrib/fai/goto-fai/debian/preinst [new file with mode: 0755]
gosa-core/contrib/fai/goto-fai/debian/rules [new file with mode: 0755]
gosa-core/contrib/fai/goto-fai/diversions/setup_harddisks [new file with mode: 0755]
gosa-core/contrib/fai/goto-fai/faimond [new file with mode: 0755]
gosa-core/contrib/fai/goto-fai/get_fai_dir [new file with mode: 0755]
gosa-core/contrib/fai/goto-fai/goto-support.lib [new file with mode: 0644]
gosa-core/contrib/fai/goto-fai/ldap2fai [new file with mode: 0755]
gosa-core/contrib/fai/goto-fai/secret [new file with mode: 0644]
gosa-core/contrib/fix_munged.php [new file with mode: 0755]
gosa-core/contrib/gosa.conf [new file with mode: 0644]
gosa-core/contrib/gosa.spec [new file with mode: 0644]
gosa-core/contrib/keyboardLayouts [new file with mode: 0644]
gosa-core/contrib/latex2html [new file with mode: 0755]
gosa-core/contrib/mysql/README [new file with mode: 0644]
gosa-core/contrib/mysql/glpi/glpi.sql [new file with mode: 0644]
gosa-core/contrib/mysql/gofax/gofax.sql [new file with mode: 0644]
gosa-core/contrib/mysql/gofon/gofon.sql [new file with mode: 0644]
gosa-core/contrib/mysql/golog/golog.sql [new file with mode: 0644]
gosa-core/contrib/mysql/logging/logging.sql [new file with mode: 0644]
gosa-core/contrib/openldap/apple.schema.README [new file with mode: 0644]
gosa-core/contrib/openldap/dhcp.schema [new file with mode: 0644]
gosa-core/contrib/openldap/dnszone.schema [new file with mode: 0644]
gosa-core/contrib/openldap/fai.schema [new file with mode: 0644]
gosa-core/contrib/openldap/glpi.schema [new file with mode: 0644]
gosa-core/contrib/openldap/goconfig.schema [new file with mode: 0644]
gosa-core/contrib/openldap/gofax.schema [new file with mode: 0644]
gosa-core/contrib/openldap/gofirewall.schema [new file with mode: 0644]
gosa-core/contrib/openldap/gofon.schema [new file with mode: 0644]
gosa-core/contrib/openldap/gosa+samba3.schema [new file with mode: 0644]
gosa-core/contrib/openldap/gosa.schema [new file with mode: 0644]
gosa-core/contrib/openldap/goserver.schema [new file with mode: 0644]
gosa-core/contrib/openldap/gosystem.schema [new file with mode: 0644]
gosa-core/contrib/openldap/goto-mime.schema [new file with mode: 0644]
gosa-core/contrib/openldap/goto.schema [new file with mode: 0644]
gosa-core/contrib/openldap/hdb.schema [new file with mode: 0644]
gosa-core/contrib/openldap/kolab2.schema [new file with mode: 0644]
gosa-core/contrib/openldap/nagios.schema [new file with mode: 0644]
gosa-core/contrib/openldap/openxchange.schema [new file with mode: 0644]
gosa-core/contrib/openldap/phpgwaccount.schema [new file with mode: 0644]
gosa-core/contrib/openldap/phpscheduleit.schema [new file with mode: 0644]
gosa-core/contrib/openldap/pptp.schema [new file with mode: 0644]
gosa-core/contrib/openldap/pureftpd.schema [new file with mode: 0644]
gosa-core/contrib/openldap/rfc2307bis.schema [new file with mode: 0644]
gosa-core/contrib/openldap/rfc2739.schema [new file with mode: 0644]
gosa-core/contrib/openldap/samba.schema [new file with mode: 0644]
gosa-core/contrib/openldap/samba3.schema [new file with mode: 0644]
gosa-core/contrib/openldap/slapd.conf [new file with mode: 0644]
gosa-core/contrib/openldap/trust.schema [new file with mode: 0644]
gosa-core/contrib/opensides/README.OpenSides [new file with mode: 0644]
gosa-core/contrib/opensides/glpi.README [new file with mode: 0644]
gosa-core/contrib/opensides/goNagios.pl [new file with mode: 0755]
gosa-core/contrib/opensides/goSamba.pl [new file with mode: 0755]
gosa-core/contrib/opensides/nagios.README [new file with mode: 0644]
gosa-core/contrib/opensides/phpscheduleit.README [new file with mode: 0644]
gosa-core/contrib/opensides/pptp.README [new file with mode: 0644]
gosa-core/contrib/opensides/xls-export.README [new file with mode: 0644]
gosa-core/contrib/openxchange/README.openxchange [new file with mode: 0644]
gosa-core/contrib/patches/imap-2001a-quota.patch [new file with mode: 0644]
gosa-core/contrib/patches/php4-imap-getacl.patch [new file with mode: 0644]
gosa-core/contrib/resolutions [new file with mode: 0755]
gosa-core/contrib/scripts/README [new file with mode: 0644]
gosa-core/contrib/scripts/goAgent.pl [new file with mode: 0644]
gosa-core/contrib/scripts/goQuota.pl [new file with mode: 0644]
gosa-core/contrib/scripts/goQuotaView.pl [new file with mode: 0644]
gosa-core/contrib/scripts/goSquid.pl [new file with mode: 0644]
gosa-core/contrib/scripts/gosa [new file with mode: 0755]
gosa-core/contrib/scripts/mkHash.pl [new file with mode: 0644]
gosa-core/contrib/scripts/net-resolver.sh [new file with mode: 0755]
gosa-core/contrib/scripts/sieve_vacation/IMAP/Sieve.pm [new file with mode: 0644]
gosa-core/contrib/scripts/sieve_vacation/update-vacation.pl [new file with mode: 0755]
gosa-core/contrib/shells [new file with mode: 0644]
gosa-core/contrib/socket_server/client.php [new file with mode: 0755]
gosa-core/contrib/socket_server/server.php [new file with mode: 0755]
gosa-core/contrib/vacation_example.txt [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644 (file)
index 8a46db4..0000000
--- a/AUTHORS
+++ /dev/null
@@ -1,76 +0,0 @@
-GOsa AUTHORS
-============
-
-This is the alphabetical list of all people that have
-contributed to the GOsa project, beeing code, translations,
-documentation and additional help.
-
-* Markus Amersdorfer <der.plusch@subnet.at>
-  Wiki setup, Testing, hints, proposals
-
-* Alessandro Amici <a.amici@bopen.it>
-  Italian translation
-
-* Holger Burbach <burbach@gonicus.de>
-  Kerberos PHP module
-
-* Craig Chang <craig0310@gmail.com>
-  Fixes for magic_quotes_qpc
-
-* Guillaume Delecourt <guillaume.delecourt@opensides.be>
-  Setup fixes, nagios tab plugin, xls addons ldapmanager
-  pptp connectivity option, phpscheduleit connectivity option
-
-* Dan Ellis <danellis@rushmore.com>
-  Sieve lib is taken from him
-
-* Alejandro Escanero Blanco <aescanero@chaosdimension.org>
-  Fixes, improvements, translation, Guide and some extensions
-
-* Fabian Hickert <hickert@gonicus.de>
-  Improvements for setup, various fixes and plugins
-
-* Eric Kilfoil <eric@ipass.net>
-  ldap.inc is taken from him
-
-* Niels Klomp <nk@careworks.nl>
-  Dutch translation
-  
-* Benoit Mortier <benoit.mortier@opensides.be>
-  French translation
-
-* Igor Muratov <migor@altlinux.org>
-  Various fixes and speed enhancements
-
-* Michael Pasdziernik <mp@secio.de>
-  Documentation for GOsa and safe-mode, fixes
-
-* Cajus Pollmeier <pollmeier@gonicus.de>
-  Virtually everyting which is GOsa related
-
-* Piotr Rybicki <meritus@innervision.pl>
-  Polish translation
-
-* Henning Schmiedehausen <hps@intermeta.de>
-  Various fixes, support for user defined people/group base
-
-* Alfred Schröder <schroeder@gonicus.de>
-  German translation
-
-* Thomas Schüßler <tulpe@atomar.de>
-  debuglib.inc is taken from him
-
-* Jan Wenzel <jan.wenzel@gonicus.de>
-  Implementation and research for samba munged dial support,
-  fixing of "Fiptehlers"(TM) in the german translations.
-
-* Leila El Hitori <leila.elhitori@opensides.be>
-  French online documentation
-  English online documentation
-  
-* Vincent Seynhaeve
-  Xls export plugin <vincent.seynhaeve@opensides.be>
-  
-* Wouter Verhelst <wouter@debian.org>
-  accept-to-gettext code that helps for language conversation
-
diff --git a/Changelog b/Changelog
deleted file mode 100644 (file)
index cba0fc9..0000000
--- a/Changelog
+++ /dev/null
@@ -1,526 +0,0 @@
-GOsa2 changelog
-===============
-
-* gosa 2.6beta1
-
-* gosa 2.5.13
-  - Re-added ISC DHCP support
-  - Fixes for the mail based bugtracker
-  - Fixed autouid problem with slashes
-  - Added list sorting for FAI script lists
-  - Added copy'n paste for mimetypes
-  - Cut'n paste objects are now greyed out
-  - Added swedish locale
-  - Improved language detection
-  - Added a statistic footer to lists
-  - Added the ssh plugin
-  - Layout fixes
-
-* gosa 2.5.12
-  - Fixed problems with automatic reverse zones
-  - Fixed several IE6 related Java-Script problems
-  - Removed png.js by default. Looks ugly, but performs. Take
-    a look at the FAQ on how to re-enable it for IE.
-  - Added non-login password change dialog
-  - Various spelling fixes
-  - Added some extra robustness to the PPD reader code
-  - FAI partition ordering fixed, partition sizes fixed
-  - FAI release management updates
-  - Fixed installations that fail the schema check
-  - Updated error messages to fade out the interface
-  - Repository cleanup
-  - Added feedback link to easily report PHP errors
-  - Added more content sorting where needed
-  - Made gidNumber be the current in posix check hook
-  - Removed inconsistency in gosa/gosa+samba3 schema
-  - Fixed multiple saving of "My account" data
-  - Don't allow moving of objects from administrative units to other
-    administrative units where ACL's permit it. Objects "seemed" to
-    disapear because the tagging changes.
-  - Added gosa-desktop package to be able to start it by link
-  - Added method to highlight tabs
-  - Generel translation update for de, es, fr, it, nl, pl, ru, zh
-
-* gosa 2.5.11a
-  - Added chinese translation
-  - Fixed language detection and removed line wraps in tab headers
-  - Fixed french translation
-
-* gosa 2.5.11
-  - Add workaround for failing is_php4() when using PHP5
-    with "zend.ze1_compatibility_mode" set to "On"
-  - Backported new sieve filter editor from trunk
-  - Backported new setup from trunk
-  - Fixed double loaded pages in gecko based browsers when js
-    is activated
-  - Replaced a set of PHP <? short tag occurences
-  - Updated locales (de/fr)
-
-* gosa 2.5.10
-  - Included hook to make use of dynamic uid-bases
-  - Included vacation date range specification
-  - Fixed non-saved Samba-Domain changes in groups
-  - Freezed application parameters are not editable anymore
-  - Fixed problem with removing commata based DN's
-  - Corrected setup generated perl mkntpasswd string
-  - Fixed month listing in fax reports - february was march
-  - Enabled 9 digits for gid-/uidNumbers
-  - Fixed acl's for saving printers
-  - Fixed saving of disabled samba acl's
-  - Added support for rfc2307bis compliant groups
-
-* gosa 2.5.9
-  - Fixed ldap tls connections when schema check was being used
-  - Updated italian translation
-  - Added the possiblility to choose a RDN style for DN's when
-    a CN is already in use
-  - Fixed a problem with cut'n paste for groups and ogroups
-  - Added new mail method "golab" which has some tweaks against
-    the standard kolab mode
-  - Fixed object tagging for workstation/printer assignement
-  - Fixed undefined index in FAI package lists
-  - Fixed copy'n paste for groups and object groups
-  - Enabled non ASCII characters in vacation messages
-  - Fixed "none" permissions in IMAP shared folders to be assignable
-
-* gosa 2.5.8
-  - Fixed problem with winstations shown in user list. 
-  - Allow basic regex ().*^$ in fax blocklist numbers.
-  - Fixed date of birth and shadow expire in template adaption
-  - Updated user mail account to search for CYRUSUNIXSTYLE in all
-    relevant sections of the config file
-  - Added support for sambaLogonHours 
-  - Security fix, that allows non priviledged users to change
-    several settings - including admin passwords
-
-* gosa 2.5.7
-  - Fixed login.tpl to display error msgs in the middle of the screen
-  - Fixed some error outputs in login.php to not break the screen
-  - Added auto scroll function to FAI-Create-Branch and Department tagging
-  - Fixed problems with workstations when fai.schema was not included
-  - Made gid-/uidNumbers 32 bit aware
-  - Replaced hardcoded config path /etc/gosa with CONFIG_DIR constant
-  - Included personal title in DN
-  - Added function to remove PPD's from disc
-  - Removed old cups dependencies
-  - Fixed saving of terminals printer service attribute
-  - Fixed a ACL naming bug, that avoids that an admin with non "all" ACLs
-    can edit specified objects.
-  - Fixed simultaneous move + rename for deparments
-  - Internally updated to smarty 2.6.16
-  - Removed asterisk status view in user display. This was too slow in
-    bigger installations.
-  - Re-enabled phone queues. They got optimized for invisibility.
-
-* gosa 2.5.6
-  - Copy & paste implemented into FAI
-  - Added setup fix to support GraphicsMagick
-  - Added several fixes for all user plugins to support Copy & Paste.
-  - Fixed malformed usage of $this>var in samba class. 
-  - Fixed checkbox selection in samba class.
-  - Connectivity netatalk: Moved plugin intialization from execute() to contructor().
-  - Fixes various issues with setup.php
-  - Avoid tab lables to have line feeds
-  - Activated missing checks for IP and MAC
-  - Fixed copy'n paste errors for netatalk
-  - Various W3C fixes
-  - Fixed "My Account" mode, where buttons disappear after saving
-  - Avoid removal of shares while they are used by users
-  - Added finer grained ACL settings for mail accounts
-  - Fixed day of birth problem in M$ IE
-  - Fixed setting of Kerberos passwords
-
-* gosa 2.5.5
-  - Added remove method for shared folder in kolab mode
-  - Added checkbox to decide if the shared folder should be deleted from IMAP
-    if the mail extension is removed from group mail account
-  - Updated request method for mail folders
-  - Resolved problem with infinite loop while storing sieve scripts
-  - Added subsearch checkbox to object group "add items" filter
-  - Fixed "missing PPD" configuration error, for newly created printer
-  - Corrected problem where the object base was sometimes broken when
-    saving object groups
-  - Fixed saving of terminal attribute gotoLpdEnable to contain "yes"
-    instead of "1"
-  - Avoid reset of several attributes from workstations when not
-    inherited from object groups
-  - Show error messages from password dialog
-  - Fixed a set of W3C problems
-  - Fixed multiple savings in addressbook (Closes: #23)
-  - Fixed shadow expire when using templates (Closes: #20)
-  - Made %uid, %sn, etc. available in templates using gosaMailAlternateAddress
-
-* gosa 2.5.4
-  - Included patch to choose the addressbook base
-  - Applied fixes for logviewer done by Mario Minati
-  - Updated locales, fixed a set of missing strings
-  - Fixed problems in FAI list handling
-  - Added "uid" to personal plugins for replacement in post events
-  - Fixed saving of user logon scripts
-  - Fixed non-FAI application mode
-  - More speed fixes applied, especially for users, objectgroups and
-    generic plugin loading
-  - Bug while saving FAI partitions fixed
-  - Don't save PPD if none is not selected bug fixed
-  - Saving of non revisioned applications fixed
-
-* gosa 2.5.3
-  - Fixed problem in reloading departments when we've PHP4
-  - Fixed gotoPrinter membership problem.
-  - Fixed environment shares, only available shares will be displayed (gosaUnitTag was ignored)
-  - Fixed saving of inherited workstation settings
-  - Removed error when no FAI repositories were present
-  - Fixed posix group add dialog, filter wasn't working.
-  - Fixed get_printer_list undefined index warnings while editing a user.
-  - Fixed ogroup non-static method error
-  - Fixed user membership for gotoPrinter, if membership was edited 
-    via user environemnt, some numeric values were stored too
-  - Fixed mail account, mail server string possibly was an array
-  - Fixed typos
-  - Fixed upper/lowcase ou's for groups/people when using an
-    unclean LDAP database
-  - Fixed ACL handling to *not* show the admin user dialog
-    when configured for self modify only
-  - Fixed problem when changing passwords via "My account"
-  - Added more information to hotplug devices.
-
-* gosa 2.5.2
-  - Fixed current main base not beeing set when editing non tabbed
-    plugins
-  - Fixed filtering for divlists
-  - Fixed deletion of shares in environment tabs
-  - Updated french online help
-  - Updated german online help
-  - Fixed display of FAI partitions
-  - Removed Quota warnings for existing accounts without quota limits
-  - Worked around PHP4 session problems when creating new departments
-  - Fixed problems when moving around departments including a comma
-  - Unified bool values in gosa.conf. true/yes and false/no are valid
-    now in upper and lower case.
-  - Avoid the try of creating already existing ou's
-  - Fixed non working printer removal
-
-* gosa 2.5.1
-  - Fixed problems with NFS shares and terminals
-  - Finalized polish translations
-  - Fixed problem with compressed gosa.conf in the debian package
-
-* gosa 2.5
-  - Improved FAI support
-    * Server and workstations are treated the same way
-    * Destination selector for new devices
-    * Summary tab introduced
-  - Improved robustness while operating whith the LDAP
-  - Several Kolab related fixes
-  - Tagging of departments introduced
-  - Global check hooks allow user defined testing
-    of single plugins
-  - Major speedups with large databases
-  - Added english and french online help
-  - Unified plugin "head" selectors, (re-)added subtree
-    support
-  - Fixed PPD parsing for several commercial PPD's
-  - Tune LDAP error messages
-  - Moved from "guru mediation style" to div-popups
-  - Several css fixes
-  - Fixed series of bugs that lead to not shown groups
-
-* gosa 2.4
-  - Updated layout to work cleanly with IE6+, Firefox 1.0.4+, khtml 3.4+
-  - Added FAI (Fully Automatted Installation) support
-  - Added mail queue management
-  - Added many missing acl informations
-  - Added help browser and initial french help
-  - Fixed templating for samba and unix users
-  - Applied hundreds of smaller bugfixes
-  - Improved speed by switching to directory style dialogs and performing
-    sub searches.
-  - Per user language selector in generic tab
-  - New connectivity plugins (PHPscheduleit/PPTP/glpi)
-
-* gosa 2.4beta3
-  - Updated layout
-  - Fixed application removal
-  - Improved accessibility for disabled persons
-  - Added intranet account to list of connectivity plugins
-  - Several kolab related fixes for server objects
-  - Corrected contributed slapd.conf
-  - Fixed kolab mode where GOsa saves KB quotas, interprets quotas as kolab MB
-  - Increased robustnes for non set fields
-  - Fixed IE issues with W3C compatibilty where IE posts disabled fields
-  - Fixed problems with existing samba accounts and password changed fields
-  - Removed login problems with undefined ldap_conf variable
-  - Fixed problems where the GECOS field is not written correctly
-
-* gosa 2.4beta2
-  - Fixed error handler to be PHP 4.x compatible
-  - Fixed PHP compatibility problem in setup.php, using ini_get()
-    instead of ini_get_all()
-  - Fixed cases where ipHostAddress is required but not checked
-    by GOsa
-  - Fixed group dialog filters
-  - Fixed problems in setup which showed up with white pages if
-    PHP has been compiled without mbstring support
-  - Fixed layout if the rendered page does not cover 100% of the
-    browser window
-  - Improved phone plugin to respect IAX, CAPI and SIP phone
-    attributes
-    automatically if the revision changes
-  - Improved W3C compatibility
-  - Added checks that remove the contents of /var/spool/gosa/*
-  - Added postmodify for password change operations
-
-* gosa 2.4beta1
-  - Override automatically detected user bases if they don't exist
-  - Don't shred samba group ID's if they are not present in the
-    combobox
-  - Updated smarty to version 2.6.9
-  - Updated GOfon support to handle new features
-  - Replacement of most external programm calls
-  - Samba3 bugfixes for munged dial handling
-  - Updated LDIF export
-  - Improved setup checks to find more possible errors
-  - Fixed index ruler for long lists
-  - Completed system creation for servers, phones and misc components
-  - Added support for kolab users and kolab server settings
-  - Added server settings
-  - Added LDIF import
-  - Added CSV import
-  - Added italian translation (thanks to Alessandro Amici)
-  - Added subtree search checkbox in lists with potential higher
-    usage
-  - Added version indicator to make support more easy
-  - Added sample databases for fax, phone and system logging
-  - Added error handler for normal PHP errors
-
-* gosa 2.3
-  - Updated smarty to version 2.6.7
-  - Added dutch translations (thanks to Niels Klomp)
-  - Added webdav and phpgroupware accounts
-  - Fixed french translation
-  - Fixed error in shadowExpire attribute
-  - Unified all filters in dialogs to use the internationalized choosers
-  - Added option to do non subtree searches with filters
-  - Fixed sample configuration files to be unproblematic when used in
-    conjunction with OpenLDAP 2.2
-  - Added experimental support for editing LDAP trees that contain referrals
-  - Updated Altlinux contributions, including themes and scripts
-  - Worked around a possible problem with sizelimit in php-ldap
-  - Improved big ldap support by size limits and non sub searches
-  - Various smaller fixes
-  - Added global TLS switch for LDAP connections
-  - Fixed SELECT queries to be mysql 3.x _and_ 4.x compatible
-  - Made departments movable
-
-* gosa 2.2
-  - Removed DHCP/DNS plugins, they will be replaced by
-    the terminal/server/workstation plugins.
-  - Added case sensitivity check for login names
-  - Made bases set to users "home" department when creating new objects
-  - Moved sieve-*.txt config files to /etc/gosa
-  - Told IMAP plugin to remove mail accounts when the user is deleted
-  - Interface cleanups
-  - Added simple log file viewer
-  - Added support for asterisk
-  - Included javascript magic to improve usability (doubleclicks in
-    lists, disabling of fields, warning messages, etc.)
-  - More filtering and sizelimits for speed optimizations
-  - Mail handling is now pluggable
-  - Added possibility to bundle objects to object groups
-  - Added a reference tab to track relation ships of different objects
-  - Improved samba 3 support (terminal server support)
-  - Updated translations and added a french one
-
-* gosa 2.1.3
-  - Fixed problem with initial password setting
-  - Increase number in version.inc
-  - Add a workaround to fix problem with groups not beeing displayed
-    with openldap. Here the server reacts with empty results if searching
-    for non existing objectClass "sambaGroupMapping" in case of using samba2
-  - Fix the homeDirectory check which is a bit too harsh with templates
-
-* gosa 2.1.2
-  - Fixed problem with uppercase login names
-  - Extensive speed increasements in ldap searches
-  - Fixed gettext problem on older installations
-  - Corrected sieve login which was broken due to a library switch
-  - Made in_array act case insensitive for is_account check
-  - Fixed location of DMODE and HASH in config file
-  - Fixed general problems with password hash generation if not
-    specified
-  - Complete move to unicode which removes all active encoding/decoding
-    of contents from GOsa itself
-  - Made GOsa run smooth on PHP 5
-  - Added complete russian translation contributed by Igor Muratov
-  - Migrated phone list to (global) addressbook
-  - Filtering fixes
-
-* gosa 2.1.1
-  - Enabled mail-account-less fax accounts
-  - Fixed upper/lower case problem in mail templates
-  - Fixed typo in generic plugin error message
-  - Made template dialog work again
-  - Fixed headpage for application management which tends to do no
-    proper display of used applications
-  - Added command line interface to use GOsa without web interface
-  - Updated debian control to be aware of apache2 based installations
-  - Transferd tab variables in group dialog, so the primary mail 
-    address can be checked
-  - Fixed possible case problem with is_account
-  - Made base selector contain newly added departments in department
-    dialog
-  
-* gosa 2.1
-  Bugfix release
-  - size of homeDirectory attribute increased
-  - FAQ/README/INSTALL updated
-  - spec file updated
-
-* gosa 2.1rc2
-  Bugfix release
-  - Made user dn configurable
-  - Fixed memory usage check
-  - Fixed size of alternate mail address field
-  - Fixed sorting of group in posix tab
-  - Made GOsa keep group membership even if user has no posix
-    account
-  - Fixed typo in blocklist spelling
-  - Fixed error message when trying to filter users without a
-    valid uid
-  - Made posix account visible, even if there are no shadow
-    attributes inside this entry
-  - Included setup
-  - Translation updates
-
-* gosa 2.1rc1
-  Bugfix release
-  - Fixed annoying ACL bug in template mode
-  - Fixed possible privilege escalation problem in password
-    routine (thanks to Henning Schmiedehausen)
-  - Removed password storage from user info class (thanks to
-    Rainer Herbst)
-  - Various interface cleanups
-  - Templatization finished
-  - Reworked user headpage
-  - Made GOsa more robust in detecting errors in config
-  - Added additional error messages reported by LDAP server
-  - Added schmemacheck hook
-  - Started with setup implementation
-
-* gosa 2.1beta3
-  Bugfix release
-  - Made template mode remember the templates primary group
-  - Templatized posix plugin
-  - Added option to disable strict checking of uid/gid names
-  - Massive samba3 updates
-  - Made ou=people and ou=groups configurable
-  - Fixed user/group lists to react on filter changes
-
-* gosa 2.1beta2
-  Bugfix and feature enhancement release.
-  - Made GOsa remove object locks when changing plugins during edit
-    process.
-  - Added DHCP plugin
-  - Gerneral speed tunig, reduced the number of unessasary ldap
-    accesses
-  - Added syslog output for actions "save" and "remove"
-  - Fixed handling for multiple ACL's per base
-  - Fixed listboxes to unify output / sort output
-  - Fixed annoying bug in tab_groups.inc when removing the mailtab
-  - Bases did not get set in template mode
-  - Fixed user part
-  - Templatized faxaccount/pureftpd/samba and mail plugins
-  - Included calendar.js functionality in samba plugin
-
-* gosa 2.1beta1
-  This release has some feature enhancements and contains many
-  bugfixes and design cleanups
-  - Fixed many HTML related things. Pages are now perfectly validated
-    as html 4.01 transitional.
-  - Added dn cleaner to getDN() in order to fix problems with
-    "broken" ldap databases.
-  - Added schemata for iplanet, checked if it works.
-  - Rewrote phonelist, added vcard export.
-  - Added filters to allmost all plugins.
-  - Added DNS plugin.
-  - Generic userinterface cleanups, everything is a template now and can be
-    redesigned/stripped.
-  - Improved translations, added missing ones.
-  - Added choosable templates for mail vacation messages.
-  - Improved templating stuff to generate user defined auto uids.
-  - Made user interface more comprehensive, so its important for you
-    to start with a clean gosa.conf from contrib.
-  - Added external password change hook, so that its possible to synchronize
-    with a non samba PDC via scripts. (Some organizations tend to keep a
-    readable copy of their users password which possible now, too.)
-  - Updated FAQ
-
-* gosa 2.0.1
-  This release doesn't have feature enhancements (nearly), only
-  bugfixes reported by users are incorporated.
-  - Fixed oblivious fields when changing to subdialogs. All
-    user dialogs were affected
-  - Made facsimileTelephoneNumber beeing saved without the
-    need of a fax account
-  - Fixed printer sorting which destroyed the array index
-  - Removed redundant fields in terminal configuration
-  - Made terminal plugin save the terminal hardware information
-  - Added missing </html> tags to index.php/main.php
-  - Fixed debian debconf script not to touch uidbase/ridbase
-    values in gosa.conf
-  - Fixed "Force ID", which creates a group for the posix
-    user with forced ID.
-  - Finetuning in login window behaviour
-  - Code cleanup and templatized two more plugins
-  - As requested by some users, you can now advise GOsa not to
-    create a group for the user, but take an existing group
-    as primary one.
-  - Added 'dn cleaner' for the acl list. So syntactically
-    problematic dn's with strange commata get fixed.
-
-* gosa 2.0 final
-  - Made samba3 support work
-  - Fixed several small bugs with the templating stuff
-  - Fixed problem with shared folders, added missing attribute
-    gosaSharedFolderTarget needed in some setups
-  - Updated icons
-  - Renamed icons to have more logical names
-
-* gosa 2.0rc2
-  - Corrected mistakenly copied ui object in functions.inc
-  - Fixed errors when activating new terminals
-  - Removed krb warnings in class_user.inc
-  - Plugins user, apps, groups and departments didn't check for
-    already present entries. Now they do.
-  - Removed problem in terminal dialog where checkboxes are not
-    saved
-  - Fixed ACL handling for users primary group
-  - Replaced own template class by smarty, since only two files
-    were affected by this
-  - Changed basic layout to seperate public readable files from
-    templates
-  - Added FAQ, update TODO for next versions
-  - Made accounts movable between departments
-  - Added partial spanish translations
-  - Fixed mail group handling
-
-* gosa 2.0rc1
-  - Switched to XML based gosa.conf
-  - Cleaned all plugins, moved to children of plugin.conf
-  - Moved back to gettext for translations
-  - Added hooks for pre-/post-install scripts
-  - Cleaned LDAP class
-  - Added workarounds for MS-IE (>5.5) to render transparent
-    PNGs in a correct way
-  - Redesigned login screen / some plugins
-  - Added hooks for eGOsa, which is a java applet based
-    browsing tool
-  - Switched from user based ACLs to group based ACLs,
-    removed standalone ACL plugin in favor of new group tab.
-  - Fixed samba2 rid generation (btw. still missing is sid
-    support for samba3. But this will go into the final.)
-  - Fixed many minor bugs
-  - Introduced simple theming support
-  - Added 'dn'-renaming for accounts
-
-Changelog starts with latest Beta 1.99.97
diff --git a/bin/mkntpasswd b/bin/mkntpasswd
deleted file mode 100755 (executable)
index 1749958..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-if [ $# -ne 1 ]; then
-       echo "Usage: mkntpwd <password>"
-       exit 1
-fi
-
-# Render hash using perl
-perl -MCrypt::SmbHash -e "print join(q[:], ntlmgen $ARGV[0]), $/;"
-
-exit 0
diff --git a/contrib/altlinux/etc/cyrus.conf b/contrib/altlinux/etc/cyrus.conf
deleted file mode 100644 (file)
index 4ada843..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-# standard standalone server implementation
-
-START {
-       # do not delete this entry!
-       recover cmd="ctl_cyrusdb -r"
-
-       # this is only necessary if using idled for IMAP IDLE
-#      idled           cmd="idled"
-}
-
-# UNIX sockets start with a slash and are put into /var/lib/imap/socket
-SERVICES {
-       # add or remove based on preferences
-       imap            cmd="imapd" listen="imap" prefork=5
-#      imaps           cmd="imapd -s" listen="imaps" prefork=1
-       pop3            cmd="pop3d" listen="pop3" prefork=3
-#      pop3s           cmd="pop3d -s" listen="pop3s" prefork=1
-       sieve           cmd="timsieved" listen="sieve" prefork=0
-#      smmapd          cmd="smmapd" listen="/var/lib/imap/socket/smmapd" prefork=1
-
-       # these are only necessary if receiving/exporting usenet via NNTP
-#      nntp            cmd="nntpd" listen="nntp" prefork=3
-#      nntps           cmd="nntpd -s" listen="nntps" prefork=1
-
-       # at least one LMTP is required for delivery
-#      lmtp            cmd="lmtpd" listen="lmtp" prefork=0
-       lmtpunix        cmd="lmtpd" listen="/var/spool/postfix/public/lmtp" prefork=1
-
-       # this is only necessary if using notifications
-#      notify  cmd="notifyd" listen="/var/lib/imap/socket/notify" proto="udp" prefork=1
-}
-
-EVENTS {
-       # this is required
-       checkpoint      cmd="ctl_cyrusdb -c" period=30
-
-       # this is only necessary if using duplicate delivery suppression,
-       # Sieve or NNTP
-       delprune        cmd="cyr_expire -E 3" at=0400
-
-       # this is only necessary if caching TLS sessions
-       tlsprune        cmd="tls_prune" at=0400
-}
diff --git a/contrib/altlinux/etc/gosa/gosa.conf b/contrib/altlinux/etc/gosa/gosa.conf
deleted file mode 100644 (file)
index d1ceab3..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-<?xml version="1.0"?>
-<conf>
-       <menu>
-               <section name="My account">
-                       <plugin acl="default" class="user" icon="personal.png"
-                               path="plugins/personal/generic" />
-                       <plugin acl="default" class="posixAccount" icon="posix.png"
-                               path="plugins/personal/posix" />
-                       <plugin acl="default" class="mailAccount" icon="email.png"
-                               path="plugins/personal/mail" />
-                       <plugin acl="default" class="sambaAccount" icon="samba.png"
-                               path="plugins/personal/samba" />
-                       <plugin acl="default" class="proxyAccount" icon="proxy.png"
-                               path="plugins/personal/proxy" />
-                       <plugin acl="default" class="pureftpdAccount" icon="ftp.png"
-                               path="plugins/personal/pureftpd" />
-                       <plugin acl="default" class="gofaxAccount" icon="fax.png"
-                               path="plugins/gofax/faxaccount" />
-               <!--
-                       <plugin acl="default" class="phoneAccount" icon="phone.png"
-                               path="plugins/gofon/phoneaccount" />
-               -->
-                       <plugin acl="default" class="password" icon="password.png"
-                               path="plugins/personal/password" />
-               </section>
-               
-               <section name="Administration">
-                       <plugin acl="user" class="userManagement" icon="user.png"
-                               path="plugins/admin/users" />
-                       <plugin acl="group" class="groupManagement" icon="group.png"
-                               path="plugins/admin/groups" />
-                       <plugin acl="ogroup" class="ogroupManagement" icon="ogroup.png"
-                               path="plugins/admin/ogroups" />
-                       <plugin acl="department" class="departmentManagement" icon="department.png"
-                               path="plugins/admin/departments" />
-                       <plugin acl="application" class="applicationManagement"
-                               icon="application.png" path="plugins/admin/applications" />
-                       <plugin acl="blocklists" class="blocklist" icon="blocklists.png"
-                               path="plugins/gofax/blocklists" />
-               <!--
-                       <plugin acl="terminal" class="systems" icon="terminal.png"
-                               path="plugins/admin/terminals" />
-               -->
-               </section>
-
-               <section name="Addons">
-                       <plugin acl="default" class="addressbook" icon="addressbook.png"
-                               path="plugins/addons/addressbook" />
-                       <plugin acl="default" class="faxreport" icon="reports.png"
-                               path="plugins/gofax/reports" />
-               <!--
-                       <plugin acl="default" class="fonreport" icon="phonereports.png"
-                               path="plugins/gofon/reports" />
-               -->
-                       <plugin acl="logs" class="logview" icon="logview.png"
-                                path="plugins/addons/logview" />
-                       <plugin acl="ldif" class="export" icon="ldif.png"
-                               path="plugins/addons/ldifexport" />
-               </section>
-       </menu>
-
-       <usertabs>
-               <tab class="user" name="Generic" />
-               <tab class="posixAccount" name="Unix" />
-               <tab class="mailAccount" name="Mail" />
-               <tab class="sambaAccount" name="Samba" />
-               <tab class="proxyAccount" name="Proxy" />
-               <tab class="pureftpdAccount" name="FTP" />
-               <tab class="gofaxAccount" name="Fax" />
-               <!--
-               <tab class="phoneAccount" name="Phone" />
-               -->
-               <tab class="reference" name="References" />
-       </usertabs>
-
-       <grouptabs>
-               <tab class="group" name="Generic" />
-               <tab class="appgroup" name="Applications" />
-               <tab class="mailgroup" name="Mail" />
-               <tab class="acl" name="ACL" />
-               <tab class="reference" name="References" />
-       </grouptabs>
-
-       <appstabs>
-               <tab class="application" name="Generic" />
-               <tab class="applicationParameters" name="Options" />
-               <tab class="reference" name="References" />
-       </appstabs>
-
-       <termtabs>
-               <tab class="termgeneric" name="Generic" />
-               <tab class="termservice" name="Devices" />
-               <tab class="termstartup" name="Startup" />
-               <tab class="terminfo" name="Monitoring" 
-                       wakecmd="/usr/bin/sudo /usr/sbin/etherwake" />
-               <tab class="reference" name="References" />
-       </termtabs>
-
-       <worktabs>
-               <tab class="workgeneric" name="Generic" />
-               <tab class="termservice" name="Devices" />
-               <tab class="termstartup" name="Startup" />
-               <tab class="terminfo" name="Monitoring" 
-                       wakecmd="/usr/bin/sudo /usr/sbin/etherwake" />
-               <tab class="reference" name="References" />
-       </worktabs>
-
-       <printtabs>
-               <tab class="printgeneric" name="Generic" />
-               <tab class="reference" name="References" />
-       </printtabs>
-
-        <phonetabs>
-                <tab class="phonegeneric" name="Generic" />
-                <tab class="reference" name="References" />
-        </phonetabs>
-
-       <deptabs>
-               <tab class="department" name="Generic" />
-               <tab class="reference" name="References" />
-       </deptabs>
-
-       <ogrouptabs>
-               <tab class="ogroup" name="Generic" />
-               <tab class="reference" name="References" />
-       </ogrouptabs>
-
-       
-       <main default="EXAMPLE.COM"
-               compile="/var/spool/gosa"
-               lang=""
-               theme="default"
-               debuglevel="0"
-               forcessl="false"
-               warnssl="false"
-               iconsize="48x48"
-               pwminlen="6"
-               forceglobals="false"
-               smbhash='mkntpwd'>
-
-               <location name="EXAMPLE.COM"
-                       uidbase="1000"
-                       governmentmode="false"
-                       sambaversion="3"
-                       server="ldap://localhost:389"
-                       admin="cn=gosa,ou=Apps,dc=example,dc=com"
-                       mailMethod="Cyrus"
-                       hash="md5"
-                       password="gosa"
-                       dnmode="uid"
-                       base="dc=example,dc=com"
-                       people="People"
-                       groups="Groups"
-                       config="ou=gosa,ou=configs,ou=systems,dc=example,dc=com" />
-
-               <language name="Russian" tag="ru_RU" />
-               <language name="German" tag="de_DE" />
-               <language name="Spanish" tag="es_ES" />
-               <language name="French" tag="fr_FR" />
-               <language name="English" tag="en_EN" />
-
-               <faxformat type="pdf" />
-               <faxformat type="ps" />
-               <faxformat type="png" />
-               <faxformat type="mtiff" />
-               <faxformat type="tiff" />
-       </main>
-</conf>
-
-
diff --git a/contrib/altlinux/etc/imapd.conf b/contrib/altlinux/etc/imapd.conf
deleted file mode 100644 (file)
index 5ae2d9b..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-# In more detail to look in man 5 imapd.conf
-
-#@include: <none>
-
-admins: cyrus
-
-#afspts_localrealms: <none>
-#afspts_mycell: <none>
-
-#allowallsubscribe: 0
-#allowanonymouslogin: 0
-allowapop: 0
-#allownewnews: 0
-allowplaintext: 1
-#allowusermoves: 0
-#altnamespace: 0
-sasl_mech_list: plain
-
-annotation_db: skiplist
-
-autocreatequota: 10240
-#createonpost: 0
-#autocreateinboxfolders: <none>
-#autosubscribeinboxfolders: <none>
-#autosubscribesharedfolders: <none>
-
-#berkeley_cachesize: 512
-#berkeley_locks_max: 50000
-#berkeley_txns_max: 100
-
-
-configdirectory: /var/lib/imap
-#debug_command: <none>
-#defaultacl: anyone lrs
-
-#defaultdomain: taf.ru
-#defaultpartition: default
-#deleteright: c
-
-duplicate_db: berkeley-nosync
-duplicatesuppression: 0
-
-#foolstupidclients: 0
-#force_sasl_client_mech: <none>
-#fulldirhash: 0
-
-hashimapspool: 1
-#hostname_mechs: <none>
-#hostname_password: <none>
-
-idlesocket: /var/lib/imap/socket/idle
-#ignorereference: 0
-#imapidlepoll: 60
-imapidresponse: 0
-#imapmagicplus: 0
-#implicit_owner_rights: lca
-
-#ldap_authz: <none>
-#ldap_base: <none>
-#ldap_bind_dn: <none>
-#ldap_deref: never
-#ldap_filter: <none>
-#ldap_group_base: <empty string>
-#ldap_group_filter: (cn=%u)
-#ldap_group_scope: sub
-#ldap_id: <none>
-#ldap_mech: <none>
-#ldap_member_attribute: <none>
-#ldap_member_base: <empty string>
-#ldap_member_filter: (member=%D)
-#ldap_member_method: attribute
-#ldap_member_scope: sub
-#ldap_password: <none>
-#ldap_realm: <none>
-#ldap_referrals: 0
-#ldap_restart: 1
-#ldap_sasl: 1
-#ldap_sasl_authc: <none>
-#ldap_sasl_authz: <none>
-#ldap_sasl_mech: <none>
-#ldap_sasl_password: <none>
-#ldap_sasl_realm: <none>
-#ldap_scope: sub
-#ldap_servers: ldap://localhost/
-#ldap_size_limit: 1
-#ldap_start_tls: 0
-#ldap_time_limit: 5
-#ldap_timeout: 5
-#ldap_tls_cacert_dir: <none>
-#ldap_tls_cacert_file: <none>
-#ldap_tls_cert: <none>
-#ldap_tls_check_peer: 0
-#ldap_tls_ciphers: <none>
-#ldap_tls_key: <none>
-#ldap_uri: <none>
-#ldap_version: 3
-
-
-
-lmtp_downcase_rcpt: 1
-lmtp_over_quota_perm_failure: yes 
-#lmtpsocket: {configdirectory}/socket/lmtp
-lmtpsocket: /var/spool/postfix/public/lmtp
-
-#loginrealms: <empty string>
-#loginuseacl: 0
-#logtimestamps: 0
-
-#mailnotifier: <none>
-#maxmessagesize: 0
-
-mboxlist_db: skiplist
-
-#mupdate_connections_max: 128
-#mupdate_authname: <none>
-#mupdate_password: <none>
-#mupdate_port: 3905
-#mupdate_realm: <none>
-#mupdate_retry_delay: 20
-#mupdate_server: <none>
-#mupdate_workers_start: 5
-#mupdate_workers_minspare: 2
-#mupdate_workers_maxspare: 10
-#mupdate_workers_max: 50
-#mupdate_username: <empty string>
-
-#netscapeurl: http://asg.web.cmu.edu/cyrus/imapd/netscape-admin.html
-
-#newsmaster: news
-#newspeer: <none>
-#newspostuser: <none>
-#newsprefix: <none>
-#notifysocket: {configdirectory}/socket/notify
-
-partition-default: /var/spool/imap
-#partition-name: <none>
-#plaintextloginpause: 0
-
-#popexpiretime: -1
-#popminpoll: 0
-poptimeout: 5
-#postmaster: postmaster
-#postuser: <empty string>
-#proxy_authname: proxy
-#proxy_password: <none>
-#proxy_realm: <none>
-#proxyd_allow_status_referral: 0
-#proxyservers: <none>
-
-#ptloader_sock: <none>
-
-#ptscache_db: berkeley
-#ptscache_timeout: 10800
-#ptskrb5_convert524: 1
-
-#quota_db: quotalegacy
-#quotawarn: 90
-#quotawarnkb: 0
-
-# If you want to have 8-bit symbols in 'Subject' the
-# reject8bit should matter 0
-reject8bit: 0
-
-#rfc2046_strict: 0
-#rfc3028_strict: 1
-
-#sasl_auto_transition: 0
-#sasl_maximum_layer: 256
-#sasl_minimum_layer: 0
-#sasl_option: 0
-sasl_pwcheck_method: saslauthd
-
-seenstate_db: skiplist
-
-sendmail: /usr/sbin/sendmail
-servername: example.com
-
-#sharedprefix: Shared Folders
-#sieve_maxscriptsize: 32
-#sieve_maxscripts: 5
-sievedir: /var/lib/imap/sieve
-#sievenotifier: <none>
-#sieveusehomedir: 0
-
-#singleinstancestore: 1
-#skiplist_unsafe: 0
-#soft_noauth: 1
-#srvtab: <empty string>
-
-subscription_db: flat
-
-#syslog_prefix: <none>
-
-#temp_path: /tmp
-#timeout: 30
-#tls_ca_file: <none>
-#tls_ca_path: <none>
-#tlscache_db: berkeley-nosync
-#tls_cert_file: /var/lib/ssl/certs/cyrus-imapd.pem
-#tls_cipher_list: DEFAULT
-#tls_key_file: /var/lib/ssl/certs/cyrus-imapd.pem
-#tls_require_cert: 0
-#tls_session_timeout: 1440
-
-#umask: 077
-username_tolower: 1
-#userprefix: Other Users
-#unix_group_enable: 1
-#unixhierarchysep: 0
-#virtdomains: on
diff --git a/contrib/altlinux/etc/ldap.conf b/contrib/altlinux/etc/ldap.conf
deleted file mode 100644 (file)
index c245047..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-# @(#)$Id: ldap.conf,v 1.1 2004/09/16 06:46:19 migor-guest Exp $
-#
-# This is the configuration file for the LDAP nameservice
-# switch library and the LDAP PAM module.
-#
-# PADL Software
-# http://www.padl.com
-#
-
-# Your LDAP server. Must be resolvable without using LDAP.
-# Multiple hosts may be specified, each separated by a 
-# space. How long nss_ldap takes to failover depends on
-# whether your LDAP client library supports configurable
-# network or connect timeouts (see bind_timelimit).
-#host 127.0.0.1
-
-# The distinguished name of the search base.
-base dc=example,dc=com
-
-# Another way to specify your LDAP server is to provide an
-# uri with the server name. This allows to use
-# Unix Domain Sockets to connect to a local LDAP Server.
-uri ldap://127.0.0.1/
-#uri ldaps://127.0.0.1/   
-#uri ldapi://%2fvar%2frun%2fldapi_sock/
-# Note: %2f encodes the '/' used as directory separator
-
-# The LDAP version to use (defaults to 3
-# if supported by client library)
-ldap_version 3
-
-# The distinguished name to bind to the server with.
-# Optional: default is to bind anonymously.
-#binddn cn=proxyuser,dc=example,dc=com
-
-# The credentials to bind with. 
-# Optional: default is no credential.
-#bindpw secret
-
-# The distinguished name to bind to the server with
-# if the effective user ID is root. Password is
-# stored in /etc/ldap.secret (mode 600)
-#rootbinddn cn=manager,dc=example,dc=com
-
-# The port.
-# Optional: default is 389.
-#port 389
-
-# The search scope.
-#scope sub
-#scope one
-#scope base
-
-# Search timelimit
-#timelimit 30
-
-# Bind/connect timelimit
-#bind_timelimit 30
-
-# Reconnect policy: hard (default) will retry connecting to
-# the software with exponential backoff, soft will fail
-# immediately.
-#bind_policy hard
-
-# Idle timelimit; client will close connections
-# (nss_ldap only) if the server has not been contacted
-# for the number of seconds specified below.
-#idle_timelimit 3600
-
-# Filter to AND with uid=%s
-#pam_filter objectclass=account
-
-# The user ID attribute (defaults to uid)
-#pam_login_attribute uid
-
-# Search the root DSE for the password policy (works
-# with Netscape Directory Server)
-#pam_lookup_policy yes
-
-# Group to enforce membership of
-#pam_groupdn cn=PAM,ou=Groups,dc=example,dc=com
-
-# Group member attribute
-#pam_member_attribute uniquemember
-
-# Template login attribute, default template user
-# (can be overriden by value of former attribute
-# in user's entry)
-#pam_login_attribute userPrincipalName
-#pam_template_login_attribute uid
-#pam_template_login nobody
-
-# HEADS UP: the pam_crypt, pam_nds_passwd,
-# and pam_ad_passwd options are no
-# longer supported.
-
-# Do not hash the password at all; presume
-# the directory server will do it, if
-# necessary. This is the default.
-#pam_password clear
-
-# Hash password locally; required for University of
-# Michigan LDAP server, and works with Netscape
-# Directory Server if you're using the UNIX-Crypt
-# hash mechanism and not using the NT Synchronization
-# service. 
-#pam_password crypt
-
-# Remove old password first, then update in
-# cleartext. Necessary for use with Novell
-# Directory Services (NDS)
-#pam_password nds
-
-# Update Active Directory password, by
-# creating Unicode password and updating
-# unicodePwd attribute.
-#pam_password ad
-
-# Use the OpenLDAP password change
-# extended operation to update the password.
-#pam_password exop
-
-# RFC2307bis naming contexts
-# Syntax:
-# nss_base_XXX         base?scope?filter
-# where scope is {base,one,sub}
-# and filter is a filter to be &'d with the
-# default filter.
-# You can omit the suffix eg:
-# nss_base_passwd      ou=People,
-# to append the default base DN but this
-# may incur a small performance impact.
-#nss_base_passwd       ou=People,dc=example,dc=com?one
-#nss_base_shadow       ou=People,dc=example,dc=com?one
-#nss_base_group                ou=Groups,dc=example,dc=com?one
-#nss_base_hosts                ou=Hosts,dc=example,dc=com?one
-#nss_base_services     ou=Services,dc=example,dc=com?one
-#nss_base_networks     ou=Networks,dc=example,dc=com?one
-#nss_base_protocols    ou=Protocols,dc=example,dc=com?one
-#nss_base_rpc          ou=Rpc,dc=example,dc=com?one
-#nss_base_ethers       ou=Ethers,dc=example,dc=com?one
-#nss_base_netmasks     ou=Networks,dc=example,dc=com?ne
-#nss_base_bootparams   ou=Ethers,dc=example,dc=com?one
-#nss_base_aliases      ou=Aliases,dc=example,dc=com?one
-#nss_base_netgroup     ou=Netgroup,dc=example,dc=com?one
-
-# attribute/objectclass mapping
-# Syntax:
-#nss_map_attribute     rfc2307attribute        mapped_attribute
-#nss_map_objectclass   rfc2307objectclass      mapped_objectclass
-
-# configure --enable-nds is no longer supported.
-# For NDS now do:
-#nss_map_attribute uniqueMember member
-
-# configure --enable-mssfu-schema is no longer supported.
-# For MSSFU now do:
-#nss_map_objectclass posixAccount User
-#nss_map_attribute uid msSFUName
-#nss_map_attribute uniqueMember posixMember
-#nss_map_attribute userPassword msSFUPassword
-#nss_map_attribute homeDirectory msSFUHomeDirectory
-#nss_map_objectclass posixGroup Group
-#nss_map_attribute cn msSFUName
-#pam_login_attribute msSFUName
-#pam_filter objectclass=User
-#pam_password ad
-
-# Alternatively, if you wish to equivalence W2K and POSIX
-# groups, change the uniqueMember mapping line to:
-#nss_map_attribute uniqueMember member
-
-# configure --enable-authpassword is no longer supported
-# For authPassword support, now do:
-#nss_map_attribute userPassword authPassword
-#pam_password nds
-
-# For IBM AIX SecureWay support, do:
-#nss_map_objectclass posixAccount aixAccount
-#nss_base_passwd ou=aixaccount,?one
-#nss_map_attribute uid userName
-#nss_map_attribute gidNumber gid
-#nss_map_attribute uidNumber uid
-#nss_map_attribute userPassword passwordChar
-#nss_map_objectclass posixGroup aixAccessGroup
-#nss_base_group ou=aixgroup,?one
-#nss_map_attribute cn groupName
-#nss_map_attribute uniqueMember member
-#pam_login_attribute userName
-#pam_filter objectclass=aixAccount
-#pam_password clear
-
-# Netscape SDK LDAPS
-#ssl on
-
-# Netscape SDK SSL options
-#sslpath /etc/ssl/certs/cert7.db
-
-# OpenLDAP SSL mechanism
-# start_tls mechanism uses the normal LDAP port, LDAPS typically 636
-#ssl start_tls
-#ssl on
-
-# OpenLDAP SSL options
-# Require and verify server certificate (yes/no)
-# Default is "no"
-#tls_checkpeer yes
-
-# CA certificates for server certificate verification
-# At least one of these are required if tls_checkpeer is "yes"
-#tls_cacertfile /etc/ssl/ca.cert
-#tls_cacertdir /etc/ssl/certs
-
-# SSL cipher suite
-# See man ciphers for syntax
-#tls_ciphers TLSv1
-
-# Client certificate and key
-# Use these, if your server requires client authentication.
-#tls_cert
-#tls_key
-
-# Disable SASL security layers. This is needed for AD.
-#sasl_secprops maxssf=0
-
-# Override the default Kerberos ticket cache location.
-#krb5_ccname FILE:/etc/.ldapcache
diff --git a/contrib/altlinux/etc/nsswitch.conf b/contrib/altlinux/etc/nsswitch.conf
deleted file mode 100644 (file)
index 5f0d1eb..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# Please refer to nsswitch.conf(5) for more information on this file.
-#
-# This is the Name Service Switch configuration file.  This file should
-# be sorted with the most-used databases at the beginning.
-#
-# Specifying '[NOTFOUND=return]' means that the search for an entry
-# should stop if the search with the previous service turned up nothing.
-# Note that if the search failed due to some other reason (like no NIS
-# server responding) then the search continues with the next service.
-#
-# Legal name services are:
-#
-#      files                   Use local files
-#      tcb                     Use local tcb shadow files, see tcb(5)
-#      db                      Use local database files under /var/db
-#      nis or yp               Use NIS (NIS version 2), also called YP
-#      nisplus or nis+         Use NIS+ (NIS version 3)
-#      dns                     Use DNS (Domain Name Service)
-#      compat                  Use NIS in compatibility mode
-#      hesiod                  Use Hesiod for user lookups
-#      [NOTFOUND=return]       Stop searching if not found so far
-#
-
-passwd:     files ldap 
-shadow:     tcb ldap
-group:      files ldap
-
-hosts:      files nisplus nis dns
-
-# To use db, put the "db" in front of "files" for things you want to be
-# looked up first in the db files.
-#
-#passwd:    db files nisplus nis
-#shadow:    db tcb files nisplus nis
-#group:     db files nisplus nis
-#
-#hosts:     db files nisplus nis dns
-
-ethers:     files
-netmasks:   files
-networks:   files
-protocols:  files
-rpc:        files
-services:   files
-
-# Example - obey only what nisplus tells us...
-#services:  nisplus [NOTFOUND=return] files
-#networks:  nisplus [NOTFOUND=return] files
-#protocols: nisplus [NOTFOUND=return] files
-#rpc:       nisplus [NOTFOUND=return] files
-#ethers:    nisplus [NOTFOUND=return] files
-#netmasks:  nisplus [NOTFOUND=return] files
-
-bootparams: nisplus [NOTFOUND=return] files
-
-netgroup:   nisplus
-
-publickey:  nisplus
-
-automount:  files nisplus
-aliases:    files nisplus
diff --git a/contrib/altlinux/etc/openldap/ldap.conf b/contrib/altlinux/etc/openldap/ldap.conf
deleted file mode 100644 (file)
index eac6d22..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# $OpenLDAP: pkg/ldap/libraries/libldap/ldap.conf,v 1.9 2000/09/04 19:57:01 kurt Exp $
-#
-# LDAP Defaults
-#
-
-# See ldap.conf(5) for details
-# This file should be world readable but not world writable.
-
-BASE   dc=example,dc=com
-URI    ldap://localhost
-
-#URI    ldap://ldap.example.com ldap://ldap-master.example.com:666
-
-#SIZELIMIT      12
-#TIMELIMIT      15
-#DEREF          never
-
diff --git a/contrib/altlinux/etc/openldap/slapd.conf b/contrib/altlinux/etc/openldap/slapd.conf
deleted file mode 100644 (file)
index 37ee301..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-# $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.23.2.8 2003/05/24 23:19:14 kurt Exp $
-#
-# See slapd.conf(5) for details on configuration options.
-# This file should NOT be world readable.
-#
-# [ GLOBAL SETTINGS ]
-# Default schemas
-include                /etc/openldap/schema/core.schema
-include                /etc/openldap/schema/cosine.schema
-include                /etc/openldap/schema/inetorgperson.schema
-include                /etc/openldap/schema/openldap.schema
-include                /etc/openldap/schema/nis.schema
-#include               /etc/openldap/schema/misc.schema
-#include               /etc/openldap/schema/rfc822-MailMember.schema
-#include               /etc/openldap/schema/kerberosobject.schema
-#include               /etc/openldap/schema/corba.schema
-#include               /etc/openldap/schema/java.schema
-# Addon schemas
-#include               /etc/openldap/schema/autofs.schema
-#include               /etc/openldap/schema/courier.schema
-#include               /etc/openldap/schema/dnszone.schema
-#include               /etc/openldap/schema/qmail.schema
-#include               /etc/openldap/schema/qmailControl.schema
-#include               /etc/openldap/schema/samba2.schema
-include                /etc/openldap/schema/samba3.schema
-# Experementel schemas
-#include               /etc/openldap/schema/cron.schema
-#include               /etc/openldap/schema/trust.schema
-#include               /etc/openldap/schema/turbo.schema
-# Netscape roaming
-#include               /etc/openldap/schema/mull.schema
-#include               /etc/openldap/schema/netscape-profile.schema
-# Local schema
-
-# GOSA2 schemas
-#include               /etc/openldap/schema/local.schema
-include                /etc/openldap/schema/gohard.schema
-include                /etc/openldap/schema/goto.schema
-include                /etc/openldap/schema/gofax.schema
-include                /etc/openldap/schema/goserver.schema
-include                /etc/openldap/schema/gosa+samba3.schema
-#include               /etc/openldap/schema/gosa.schema
-
-# Specify  a  set  of features (separated by white space) to allow.
-allow bind_v2
-
-# Do not enable referrals until AFTER you have a working directory
-# service AND an understanding of referrals.
-#referral ldap://root.openldap.org
-
-# Specify a desired level of concurrency. Provided to the underlying thread
-# system as a hint. The default is not to provide any hint.
-concurency 20
-
-# Specify  the maximum number of pending requests for an anonymous session.  If
-# requests are submitted faster than the  server  can process them, they will
-# be queued up to this limit. If the limit is exceeded, the session is closed.
-#conn_max_pending 100
-
-# Specify  the  maximum  number  of  pending   requests   for   an
-# authenticated session.
-#conn_max_pending 1000 
-
-# Specify  a default search base to use when client submits a non-base search
-# request with an empty base DN.
-defaultsearchbase "dc=example,dc=com"
-
-# A SIGHUP signal will only  cause  a  'gentle'  shutdown-attempt: Slapd  will
-# stop  listening  for  new connections, but will not close the connections to
-# the  current  clients.
-gentlehup on
-
-# Specify the number of seconds to wait before forcibly closing an idle client
-# connection. A idletimeout of 0 disables this feature.
-#idletimeout 0
-
-# Specify time and size limits based on who initiated an operation.
-#sizelimit 500
-#timelimit 60
-#limits anonymous time.soft=60 time.hard=120
-#limits anonymous size.soft=1000 size.hard=1100 size.unchecked=1000
-#limits users time.soft=60 time.hard=120
-#limits users size=1000
-#limits dn.base="ou=People,dc=example,dc=com" size=100
-
-# Specify the level at which debugging statements and operation statistics
-# should be syslogged (currently logged to the syslogd(8) LOG_LOCAL4 facility).
-# Log levels are additive, and available levels are:
-#    -1  full
-#     0  none
-#     1  trace function calls
-#     2  debug packet handling
-#     4  heavy trace debugging
-#     8  connection management
-#    16  print out packets sent and received
-#    32  search filter processing
-#    64  configuration file processing
-#   128  access control list processing
-#   256  stats log connections/operations/results
-#   512  stats log entries sent
-#  1024  print communication with shell backends
-#  2048  entry parsing
-#loglevel 256
-
-# This option sets the hash to be used in generation of user passwords, stored
-# in userPassword, during processing of LDAP Password Modify Extended
-# Operations (RFC 3062). The <hash> must be one of {SSHA}, {SHA}, {SMD5},
-# {MD5}, {CRYPT}, and {CLEARTEXT}. The default is {SSHA}.
-#password-hash {SSHA}
-
-# The ( absolute ) name of a file that will hold the server's process ID
-# if started without the debugging command line option.
-pidfile                        /var/run/slapd.pid
-argsfile               /var/run/slapd.args
-replica-pidfile                /var/run/slurpd.pid
-replica-argsfile       /var/run/slurpd.args
-
-# Specify a set of conditions (separated by white space) to require (default
-# none). The directive may be specified globally and/or per-database. bind
-# requires bind operation prior to directory operations. LDAPv3 requires
-# session to be using LDAP version 3. authc requires authentication prior to
-# directory operations. SASL requires SASL authentication prior to directory
-# operations. strong requires strong authentication prior to directory
-# operations. The strong keyword allows protected "simple" authentication as
-# well as SASL authentication. none may be used to require no conditions
-# (useful for clearly globally set conditions within a particular database).
-#require none
-
-# Specify the name of an LDIF(5) file containing user defined attributes for
-# the root DSE. These attributes are returned in addition to the attributes
-# normally produced by slapd.
-#rootDSE /etc/openldap/rootdse.ldif
-
-# Specify a set of factors (separated by white space) to require. An integer
-# value is associated with each factor and is roughly equivalent of the
-# encryption key length to require. A value of 112 is equivalent to 3DES, 128
-# to Blowfish, etc..
-#      Require integrity protection (prevent hijacking)
-#      Require 112-bit (3DES or better) encryption for updates
-#      Require 63-bit encryption for simple bind
-#security ssf=1 update_ssf=112 simple_bind=64
-
-# Specify the maximum size of the primary thread pool. The default is 16.
-#threads 16
-
-
-#
-# [ TLS OPTIONS ]
-#
-# Permits configuring what ciphers will be accepted and the preference order.
-# <cipher-suite-spec> should be a cipher specification for OpenSSL.
-#TLSCipherSuite HIGH:MEDIUM:+SSLv2
-
-# Specifies the path of a directory that contains Certificate Authority
-# certificates in separate individual files. Usually only one of this or the
-# TLSCACertificateFile is used.
-#TLSCACertificateFile /etc/openldap/ssl/slapd.pem
-#TLSCACertificatePath /etc/openldap/ssl
-
-# Specifies the file that contains the slapd server certificate.
-#TLSCertificateFile /etc/openldap/ssl/slapd.pem
-
-# Specifies the file that contains the slapd server private key that matches
-# the certificate stored in the TLSCertificateFile file. Currently, the private
-# key must not be protected with a password, so it is of critical importance
-# that it is protected carefully.
-#TLSCertificateKeyFile /etc/openldap/ssl/slapd.pem
-
-# Specifies what checks to perform on client certificates in an incoming TLS
-# session, if any.
-#TLSVerifyClient never
-
-
-#
-# [ ACCESS CONTROL ]
-#
-# See slapd.access(5) for details
-#access to attrs=userPassword
-#      by self write
-#      by anonymous auth
-#      by * none
-
-
-#
-# [ BACKEND OPTIONS ]
-#
-# Load dynamic backend modules:
-modulepath     /usr/lib/openldap
-#moduleload    back_dnssrv.la
-#moduleload    back_ldap.la
-moduleload     back_bdb.la
-#moduleload    back_ldbm.la
-#moduleload    back_meta.la
-#moduleload    back_monitor.la
-#moduleload    back_null.la
-#moduleload    back_passwd.la
-#moduleload    back_shell.la
-#moduleload    back_perl.la
-#moduleload    back_sql.la
-
-# Options in this section only apply to the configuration file section for the
-# specified backend. They are supported by every type of backend.
-#backend ldbm
-#cachesize 1000
-#dbcachesize 100000
-#dbsync 10 12 5
-
-
-#
-# [ DATABASE OPTIONS ]
-#
-# Mark the beginning of a new database instance definition.
-#database ldbm
-
-# Specify the DN suffix of queries that will be passed to this backend
-# database. Multiple suffix lines can be given and at least one is required for
-# each database definition. If the suffix of one database is "inside" that of
-# another, the database with the inner suffix must come first in the
-# configuration file.
-#suffix "dc=example,dc=com"
-
-# Specify the distinguished name that is not subject to access control or
-# administrative limit restrictions for operations on this database. An empty
-# root DN (the default) specifies no root access is to be granted. It is
-# recommended that the rootdn only be specified when needed (such as when
-# initially populating a database).
-#rootdn "cn=admin,dc=example,dc=com"
-
-# Specify a password (or hash of the password) for the rootdn. This option
-# accepts all RFC 2307 userPassword formats known to the server (see
-# password-hash desription) as well as cleartext.
-#rootpw secret
-
-# Controls whether slapd will automatically maintain the modifiersName,
-# modifyTimestamp, creatorsName, and createTimestamp attributes for entries.
-#lastmod on
-
-# Specifies the maximum number of aliases to dereference when trying to resolve
-# an entry, used to avoid inifinite alias loops.
-#maxderefdepth 1
-
-# This option puts the database into "read-only" mode. Any attempts to modify
-# the database will return an "unwilling to perform" error.
-#readonly on
-
-# Specify a replication site for this database. Refer to the "OpenLDAP
-# Administrator's Guide" for detailed information on setting up a replicated
-# slapd directory service.
-#replica uri=ldaps://ldap2.example.com/
-
-# Specify the name of the replication log file to log changes to.
-#replogfile /var/lib/ldap/replica/example.com.replog
-
-# Specify that the current backend database is a subordinate of another backend
-# database. A subordinate database may have only one suffix. This option may be
-# used to glue multiple databases into a single namingContext.
-#subordinate
-
-# This option is only applicable in a slave slapd. It specifies the DN allowed
-# to make changes to the replica
-#updatedn "cn=slave,dc=example,dc=com"
-
-# Specify the referral to pass back when slapd(8) is asked to modify a
-# replicated local database. If specified multiple times, each url is provided.
-#updateref "uri=ldap://ldap2.example.com"
-
-# Specify the directory where the LDBM files containing this database and
-# associated indexes live.
-#directory /var/lib/ldap/bases/example.com
-
-# Specify the indexes to maintain for the given attribute (or list of
-# attributes). Some attributes only support a subset of indexes.Specify the
-# indexes to maintain for the given attribute (or list of attributes). Some
-# attributes only support a subset of indexes.
-#index objectClass eq
-#index uid pres,eq,sub
-#index cn pres,eq,sub,subany
-
-#access to *
-#      by * read
-
-
-#
-# Next database instance
-#
-database bdb
-suffix "dc=example,dc=com"
-#rootdn "cn=admin,dc=example,dc=com"
-#rootpw secret
-directory /var/lib/ldap/bases/example.com
-
-index objectClass eq
-index uid pres,eq
-index cn pres,eq,sub,subany
-index mail pres,eq
-index gosaMailDeliveryMode pres,eq,sub
-
-access to userPassword
-       by dn=".*,ou=Admins,dc=example,dc=com" write
-       by dn="cn=gosa,ou=Apps,dc=example,dc=com" write
-       by dn="cn=smbpasswd,ou=Apps,dc=example,dc=com" write
-       by self write
-       by anonymous auth
-       by * none
-
-access to *
-       by dn=".*,ou=Admins,dc=example,dc=com" write
-       by dn="cn=gosa,ou=Apps,dc=example,dc=com" write
-       by dn="cn=smbpasswd,ou=Apps,dc=example,dc=com" write
-       by * read
-
diff --git a/contrib/altlinux/etc/postfix/main.cf b/contrib/altlinux/etc/postfix/main.cf
deleted file mode 100644 (file)
index 225bea7..0000000
+++ /dev/null
@@ -1,596 +0,0 @@
-# Global Postfix configuration file. This file lists only a subset
-# of all 300+ parameters. See the samples/xxx.cf files for a full list.
-# 
-# The general format is lines with parameter = value pairs. Lines
-# that begin with whitespace continue the previous line. A value can
-# contain references to other $names or ${name}s.
-#
-# NOTE - CHANGE NO MORE THAN 2-3 PARAMETERS AT A TIME, AND TEST IF
-# POSTFIX STILL WORKS AFTER EVERY CHANGE.
-
-# SOFT BOUNCE
-#
-# The soft_bounce parameter provides a limited safety net for
-# testing.  When soft_bounce is enabled, mail will remain queued that
-# would otherwise bounce. This parameter disables locally-generated
-# bounces, and prevents the SMTP server from rejecting mail permanently
-# (by changing 5xx replies into 4xx replies). However, soft_bounce
-# is no cure for address rewriting mistakes or mail routing mistakes.
-#
-#soft_bounce = no
-
-# INTERNET HOST AND DOMAIN NAMES
-# 
-# The myhostname parameter specifies the internet hostname of this
-# mail system. The default is to use the fully-qualified domain name
-# from gethostname(). $myhostname is used as a default value for many
-# other configuration parameters.
-#
-#myhostname = host.domain.tld
-#myhostname = virtual.domain.tld
-
-# The mydomain parameter specifies the local internet domain name.
-# The default is to use $myhostname minus the first component.
-# $mydomain is used as a default value for many other configuration
-# parameters.
-#
-#mydomain = domain.tld
-
-# SENDING MAIL
-# 
-# The myorigin parameter specifies the domain that locally-posted
-# mail appears to come from. The default is to append $myhostname,
-# which is fine for small sites.  If you run a domain with multiple
-# machines, you should (1) change this to $mydomain and (2) set up
-# a domain-wide alias database that aliases each user to
-# user@that.users.mailhost.
-#
-# For the sake of consistency between sender and recipient addresses,
-# myorigin also specifies the default domain name that is appended
-# to recipient addresses that have no @domain part.
-#
-#myorigin = $myhostname
-#myorigin = $mydomain
-
-# RECEIVING MAIL
-
-# The inet_interfaces parameter specifies the network interface
-# addresses that this mail system receives mail on.  By default,
-# the software claims all active interfaces on the machine. The
-# parameter also controls delivery of mail to user@[ip.address].
-#
-# See also the proxy_interfaces parameter, for network addresses that
-# are forwarded to us via a proxy or network address translator.
-#
-# Note: you need to stop/start Postfix when this parameter changes.
-#
-#inet_interfaces = all
-#inet_interfaces = $myhostname
-#inet_interfaces = $myhostname, localhost
-
-# The proxy_interfaces parameter specifies the network interface
-# addresses that this mail system receives mail on by way of a
-# proxy or network address translation unit. This setting extends
-# the address list specified with the inet_interfaces parameter.
-#
-# You must specify your proxy/NAT addresses when your system is a
-# backup MX host for other domains, otherwise mail delivery loops
-# will happen when the primary MX host is down.
-#
-#proxy_interfaces =
-#proxy_interfaces = 1.2.3.4
-
-# The mydestination parameter specifies the list of domains that this
-# machine considers itself the final destination for.
-#
-# These domains are routed to the delivery agent specified with the
-# local_transport parameter setting. By default, that is the UNIX
-# compatible delivery agent that lookups all recipients in /etc/passwd
-# and /etc/aliases or their equivalent.
-#
-# The default is $myhostname + localhost.$mydomain.  On a mail domain
-# gateway, you should also include $mydomain.
-#
-# Do not specify the names of virtual domains - those domains are
-# specified elsewhere (see samples/virtual.cf).
-#
-# Do not specify the names of domains that this machine is backup MX
-# host for. Specify those names via the relay_domains settings for
-# the SMTP server, or use permit_mx_backup if you are lazy (see
-# samples/smtpd.cf).
-#
-# The local machine is always the final destination for mail addressed
-# to user@[the.net.work.address] of an interface that the mail system
-# receives mail on (see the inet_interfaces parameter).
-#
-# Specify a list of host or domain names, /file/name or type:table
-# patterns, separated by commas and/or whitespace. A /file/name
-# pattern is replaced by its contents; a type:table is matched when
-# a name matches a lookup key (the right-hand side is ignored).
-# Continue long lines by starting the next line with whitespace.
-#
-# DO NOT LIST RELAY DESTINATIONS IN MYDESTINATION.
-# SPECIFY RELAY DESTINATIONS IN RELAY_DOMAINS.
-#
-# See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
-#
-#mydestination = $myhostname, localhost.$mydomain
-#mydestination = $myhostname, localhost.$mydomain $mydomain
-#mydestination = $myhostname, localhost.$mydomain, $mydomain,
-#      mail.$mydomain, www.$mydomain, ftp.$mydomain
-mydestination = localhost, $myhostname, localhost.$mydomain, $config_directory/mydestination
-
-# REJECTING MAIL FOR UNKNOWN LOCAL USERS
-#
-# The local_recipient_maps parameter specifies optional lookup tables
-# with all names or addresses of users that are local with respect
-# to $mydestination and $inet_interfaces.
-#
-# If this parameter is defined, then the SMTP server will reject
-# mail for unknown local users. This parameter is defined by default.
-#
-# To turn off local recipient checking in the SMTP server, specify
-# local_recipient_maps = (i.e. empty).
-#
-# The default setting assumes that you use the default Postfix local
-# delivery agent for local delivery. You need to update the
-# local_recipient_maps setting if:
-#
-# - You define $mydestination domain recipients in files other than
-#   /etc/passwd, /etc/postfix/aliases, or the $virtual_alias_maps files.
-#   For example, you define $mydestination domain recipients in    
-#   the $virtual_mailbox_maps files.
-#
-# - You redefine the local delivery agent in master.cf.
-#
-# - You redefine the "local_transport" setting in main.cf.
-#
-# - You use the "luser_relay", "mailbox_transport", or "fallback_transport"
-#   feature of the Postfix local delivery agent (see samples/local.cf).
-#
-# Details are described in the LOCAL_RECIPIENT_README file.
-#
-# Beware: if the Postfix SMTP server runs chrooted, you probably have
-# to access the passwd file via the proxymap service, in order to
-# overcome chroot restrictions. The alternative, having a copy of
-# the system passwd file in the chroot jail is just not practical.
-#
-# The right-hand side of the lookup tables is conveniently ignored.
-# In the left-hand side, specify a bare username, an @domain.tld
-# wild-card, or specify a user@domain.tld address.
-# 
-#local_recipient_maps = unix:passwd.byname $alias_maps
-#local_recipient_maps = proxy:unix:passwd.byname $alias_maps
-#local_recipient_maps =
-
-# The unknown_local_recipient_reject_code specifies the SMTP server
-# response code when a recipient domain matches $mydestination or
-# $inet_interfaces, while $local_recipient_maps is non-empty and the
-# recipient address or address local-part is not found.
-#
-# The default setting is 550 (reject mail) but it is safer to start
-# with 450 (try again later) until you are certain that your
-# local_recipient_maps settings are OK.
-#
-unknown_local_recipient_reject_code = 550
-
-# TRUST AND RELAY CONTROL
-
-# The mynetworks parameter specifies the list of "trusted" SMTP
-# clients that have more privileges than "strangers".
-#
-# In particular, "trusted" SMTP clients are allowed to relay mail
-# through Postfix.  See the smtpd_recipient_restrictions parameter
-# in file samples/smtpd.cf.
-#
-# You can specify the list of "trusted" network addresses by hand
-# or you can let Postfix do it for you (which is the default).
-#
-# By default (mynetworks_style = host), Postfix "trusts" SMTP
-# clients of the local machine only.
-# 
-# Specify "mynetworks_style = class" when Postfix should "trust" SMTP
-# clients in the same IP class A/B/C networks as the local machine.
-# Don't do this with a dialup site - it would cause Postfix to "trust"
-# your entire provider's network.  Instead, specify an explicit
-# mynetworks list by hand, as described below.
-#  
-# Specify "mynetworks_style = subnet" when Postfix should "trust" SMTP
-# clients in the same IP subnetworks as the local machine.
-# 
-#mynetworks_style = class
-#mynetworks_style = subnet
-#mynetworks_style = host
-
-# Alternatively, you can specify the mynetworks list by hand, in
-# which case Postfix ignores the mynetworks_style setting.
-#
-# Specify an explicit list of network/netmask patterns, where the
-# mask specifies the number of bits in the network part of a host
-# address.
-#
-# You can also specify the absolute pathname of a pattern file instead
-# of listing the patterns here. Specify type:table for table-based lookups
-# (the value on the table right-hand side is not used).
-#
-#mynetworks = 168.100.189.0/28, 127.0.0.0/8
-#mynetworks = $config_directory/mynetworks
-#mynetworks = hash:/etc/postfix/network_table
-
-# The relay_domains parameter restricts what destinations this system will
-# relay mail to.  See the smtpd_recipient_restrictions restriction in the
-# file samples/smtpd.cf for detailed information.
-#
-# By default, Postfix relays mail
-# - from "trusted" clients (IP address matches $mynetworks) to any destination,
-# - from "untrusted" clients to destinations that match $relay_domains or
-#   subdomains thereof, except addresses with sender-specified routing.
-# The default relay_domains value is $mydestination.
-# 
-# In addition to the above, the Postfix SMTP server by default accepts mail
-# that Postfix is final destination for:
-# - destinations that match $inet_interfaces,
-# - destinations that match $mydestination
-# - destinations that match $virtual_alias_domains,
-# - destinations that match $virtual_mailbox_domains.
-# These destinations do not need to be listed in $relay_domains.
-# 
-# Specify a list of hosts or domains, /file/name patterns or type:name
-# lookup tables, separated by commas and/or whitespace.  Continue
-# long lines by starting the next line with whitespace. A file name
-# is replaced by its contents; a type:name table is matched when a
-# (parent) domain appears as lookup key.
-#
-# NOTE: Postfix will not automatically forward mail for domains that
-# list this system as their primary or backup MX host. See the
-# permit_mx_backup restriction in the file samples/smtpd.cf.
-#
-#relay_domains = $mydestination
-
-# INTERNET OR INTRANET
-
-# The relayhost parameter specifies the default host to send mail to
-# when no entry is matched in the optional transport(5) table. When
-# no relayhost is given, mail is routed directly to the destination.
-#
-# On an intranet, specify the organizational domain name. If your
-# internal DNS uses no MX records, specify the name of the intranet
-# gateway host instead.
-#
-# In the case of SMTP, specify a domain, host, host:port, [host]:port,
-# [address] or [address]:port; the form [host] turns off MX lookups.
-#
-# If you're connected via UUCP, see also the default_transport parameter.
-#
-#relayhost = $mydomain
-#relayhost = gateway.my.domain
-#relayhost = uucphost
-#relayhost = [an.ip.add.ress]
-
-# REJECTING UNKNOWN RELAY USERS
-#
-# The relay_recipient_maps parameter specifies optional lookup tables
-# with all addresses in the domains that match $relay_domains.
-#
-# If this parameter is defined, then the SMTP server will reject
-# mail for unknown relay users. This feature is off by default.
-#
-# The right-hand side of the lookup tables is conveniently ignored.
-# In the left-hand side, specify an @domain.tld wild-card, or specify
-# a user@domain.tld address.
-# 
-#relay_recipient_maps = hash:/etc/postfix/relay_recipients
-
-# INPUT RATE CONTROL
-#
-# The in_flow_delay configuration parameter implements mail input
-# flow control. This feature is turned on by default, although it
-# still needs further development (it's disabled on SCO UNIX due
-# to an SCO bug).
-# 
-# A Postfix process will pause for $in_flow_delay seconds before
-# accepting a new message, when the message arrival rate exceeds the
-# message delivery rate. With the default 100 SMTP server process
-# limit, this limits the mail inflow to 100 messages a second more
-# than the number of messages delivered per second.
-# 
-# Specify 0 to disable the feature. Valid delays are 0..10.
-# 
-#in_flow_delay = 1s
-
-# ADDRESS REWRITING
-#
-# Insert text from samples/rewrite.cf if you need to do address
-# masquerading.
-#
-# Insert text from samples/canonical.cf if you need to do address
-# rewriting, or if you need username->Firstname.Lastname mapping.
-
-# ADDRESS REDIRECTION (VIRTUAL DOMAIN)
-#
-# Insert text from samples/virtual.cf if you need virtual domain support.
-
-# "USER HAS MOVED" BOUNCE MESSAGES
-#
-# Insert text from samples/relocated.cf if you need "user has moved"
-# style bounce messages. Alternatively, you can bounce recipients
-# with an SMTP server access table. See samples/smtpd.cf.
-
-# TRANSPORT MAP
-#
-# Insert text from samples/transport.cf if you need explicit routing.
-
-# ALIAS DATABASE
-#
-# The alias_maps parameter specifies the list of alias databases used
-# by the local delivery agent. The default list is system dependent.
-#
-# On systems with NIS, the default is to search the local alias
-# database, then the NIS alias database. See aliases(5) for syntax
-# details.
-# 
-# If you change the alias database, run "postalias /etc/postfix/aliases" (or
-# wherever your system stores the mail alias file), or simply run
-# "newaliases" to build the necessary DBM or DB file.
-#
-# It will take a minute or so before changes become visible.  Use
-# "postfix reload" to eliminate the delay.
-#
-#alias_maps = dbm:/etc/postfix/aliases
-alias_maps = hash:/etc/postfix/aliases
-#, hash:/var/lib/mailman/etc/aliases
-#alias_maps = hash:/etc/postfix/aliases, nis:mail.aliases
-#alias_maps = netinfo:/aliases
-
-# The alias_database parameter specifies the alias database(s) that
-# are built with "newaliases" or "sendmail -bi".  This is a separate
-# configuration parameter, because alias_maps (see above) may specify
-# tables that are not necessarily all under control by Postfix.
-#
-#alias_database = dbm:/etc/postfix/aliases
-alias_database = hash:/etc/postfix/aliases
-#alias_database = hash:/etc/postfix/aliases, hash:/opt/majordomo/aliases
-#virtual_maps = hash:/var/lib/mailman/etc/virtual-mailman
-
-# ADDRESS EXTENSIONS (e.g., user+foo)
-#
-# The recipient_delimiter parameter specifies the separator between
-# user names and address extensions (user+foo). See canonical(5),
-# local(8), relocated(5) and virtual(5) for the effects this has on
-# aliases, canonical, virtual, relocated and .forward file lookups.
-# Basically, the software tries user+foo and .forward+foo before
-# trying user and .forward.
-#
-#recipient_delimiter = +
-
-# DELIVERY TO MAILBOX
-#
-# The home_mailbox parameter specifies the optional pathname of a
-# mailbox file relative to a user's home directory. The default
-# mailbox file is /var/spool/mail/user or /var/mail/user.  Specify
-# "Maildir/" for qmail-style delivery (the / is required).
-#
-#home_mailbox = Mailbox
-#home_mailbox = Maildir/
-
-# The mail_spool_directory parameter specifies the directory where
-# UNIX-style mailboxes are kept. The default setting depends on the
-# system type.
-#
-#mail_spool_directory = /var/mail
-#mail_spool_directory = /var/spool/mail
-
-# The mailbox_command parameter specifies the optional external
-# command to use instead of mailbox delivery. The command is run as
-# the recipient with proper HOME, SHELL and LOGNAME environment settings.
-# Exception:  delivery for root is done as $default_user.
-#
-# Other environment variables of interest: USER (recipient username),
-# EXTENSION (address extension), DOMAIN (domain part of address),
-# and LOCAL (the address localpart).
-#
-# Unlike other Postfix configuration parameters, the mailbox_command
-# parameter is not subjected to $parameter substitutions. This is to
-# make it easier to specify shell syntax (see example below).
-#
-# Avoid shell meta characters because they will force Postfix to run
-# an expensive shell process. Procmail alone is expensive enough.
-#
-# IF YOU USE THIS TO DELIVER MAIL SYSTEM-WIDE, YOU MUST SET UP AN
-# ALIAS THAT FORWARDS MAIL FOR ROOT TO A REAL USER.
-#
-#mailbox_command = /usr/bin/procmail -a "$EXTENSION"
-mailbox_command = /usr/bin/procmail -a $DOMAIN -d $LOGNAME
-
-# The mailbox_transport specifies the optional transport in master.cf
-# to use after processing aliases and .forward files. This parameter
-# has precedence over the mailbox_command, fallback_transport and
-# luser_relay parameters.
-#
-# Specify a string of the form transport:nexthop, where transport is
-# the name of a mail delivery transport defined in master.cf.  The
-# :nexthop part is optional. For more details see the sample transport
-# configuration file.
-#
-# NOTE: if you use this feature for accounts not in the UNIX password
-# file, then you must update the "local_recipient_maps" setting in
-# the main.cf file, otherwise the SMTP server will reject mail for    
-# non-UNIX accounts with "User unknown in local recipient table".
-#
-mailbox_transport = lmtp:unix:/public/lmtp
-#mailbox_transport = cyrus
-
-# The fallback_transport specifies the optional transport in master.cf
-# to use for recipients that are not found in the UNIX passwd database.
-# This parameter has precedence over the luser_relay parameter.
-#
-# Specify a string of the form transport:nexthop, where transport is
-# the name of a mail delivery transport defined in master.cf.  The
-# :nexthop part is optional. For more details see the sample transport
-# configuration file.
-#
-# NOTE: if you use this feature for accounts not in the UNIX password
-# file, then you must update the "local_recipient_maps" setting in
-# the main.cf file, otherwise the SMTP server will reject mail for    
-# non-UNIX accounts with "User unknown in local recipient table".
-#
-#fallback_transport = lmtp:unix:/private/lmtp
-fallback_transport = cyrus
-#fallback_transport =
-
-# The luser_relay parameter specifies an optional destination address
-# for unknown recipients.  By default, mail for unknown@$mydestination
-# and unknown@[$inet_interfaces] is returned as undeliverable.
-#
-# The following expansions are done on luser_relay: $user (recipient
-# username), $shell (recipient shell), $home (recipient home directory),
-# $recipient (full recipient address), $extension (recipient address
-# extension), $domain (recipient domain), $local (entire recipient
-# localpart), $recipient_delimiter. Specify ${name?value} or
-# ${name:value} to expand value only when $name does (does not) exist.
-#
-# luser_relay works only for the default Postfix local delivery agent.
-#
-# NOTE: if you use this feature for accounts not in the UNIX password
-# file, then you must specify "local_recipient_maps =" (i.e. empty) in
-# the main.cf file, otherwise the SMTP server will reject mail for    
-# non-UNIX accounts with "User unknown in local recipient table".
-#
-#luser_relay = $user@other.host
-#luser_relay = $local@other.host
-#luser_relay = admin+$local
-
-# JUNK MAIL CONTROLS
-# 
-# The controls listed here are only a very small subset. See the file
-# samples/smtpd.cf for an elaborate list of anti-UCE controls.
-
-# The header_checks parameter specifies an optional table with patterns
-# that each logical message header is matched against, including
-# headers that span multiple physical lines.
-#
-# By default, these patterns also apply to MIME headers and to the
-# headers of attached messages. With older Postfix versions, MIME and
-# attached message headers were treated as body text.
-#
-# For details, see the samples/filter.cf file.
-#
-#header_checks = regexp:/etc/postfix/header_checks
-
-# FAST ETRN SERVICE
-#
-# Postfix maintains per-destination logfiles with information about
-# deferred mail, so that mail can be flushed quickly with the SMTP
-# "ETRN domain.tld" command, or by executing "sendmail -qRdomain.tld".
-# 
-# By default, Postfix maintains deferred mail logfile information
-# only for destinations that Postfix is willing to relay to (as
-# specified in the relay_domains parameter). For other destinations,
-# Postfix attempts to deliver ALL queued mail after receiving the
-# SMTP "ETRN domain.tld" command, or after execution of "sendmail
-# -qRdomain.tld". This can be slow when a lot of mail is queued.
-# 
-# The fast_flush_domains parameter controls what destinations are
-# eligible for this "fast ETRN/sendmail -qR" service.
-# 
-#fast_flush_domains = $relay_domains
-#fast_flush_domains =
-
-# SHOW SOFTWARE VERSION OR NOT
-#
-# The smtpd_banner parameter specifies the text that follows the 220
-# code in the SMTP server's greeting banner. Some people like to see
-# the mail version advertised. By default, Postfix shows no version.
-#
-# You MUST specify $myhostname at the start of the text. That is an
-# RFC requirement. Postfix itself does not care.
-#
-#smtpd_banner = $myhostname ESMTP $mail_name
-#smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
-
-# The smtpd_etrn_restrictions parameter restricts what clients are
-# allowed to issue the ETRN command.
-#
-# The Postfix ETRN command accepts only destinations that are eligible
-# for the Postfix "fast flush" service. See the samples/flush.cf file
-# for details.
-#
-# The default is to allow ETRN from any host.  The following restrictions
-# are available:
-#
-#   reject_unknown_client: reject the request if the client hostname is unknown.
-#   permit_mynetworks: permit if the client address matches $mynetworks.
-#   check_client_access maptype:mapname
-#      look up client name, parent domains, client address,
-#      or networks obtained by stripping octets.
-#      see access(5) for possible lookup results.
-#   reject_rbl_client domain.tld: reject if the reverse client network
-#      address is listed in an A record under domain.tld.
-#   reject_rhsbl_client domain.tld: reject if the client hostname is listed
-#      in an A record under domain.tld.
-#   reject: reject the request. Place this at the end of a restriction.
-#   permit: permit the request. Place this at the end of a restriction.
-#   warn_if_reject: next restriction logs a warning instead of rejecting.
-#
-# You may also list any helo or client restrictions here (see below).
-#
-smtpd_etrn_restrictions = permit_mynetworks, reject
-
-# The smtpd_helo_required parameter optionally turns on the requirement
-# that SMTP clients must introduce themselves at the beginning of an
-# SMTP session.
-#
-smtpd_helo_required = yes
-
-# PARALLEL DELIVERY TO THE SAME DESTINATION
-#
-# How many parallel deliveries to the same user or domain? With local
-# delivery, it does not make sense to do massively parallel delivery
-# to the same user, because mailbox updates must happen sequentially,
-# and expensive pipelines in .forward files can cause disasters when
-# too many are run at the same time. With SMTP deliveries, 10
-# simultaneous connections to the same domain could be sufficient to
-# raise eyebrows.
-# 
-# Each message delivery transport has its XXX_destination_concurrency_limit
-# parameter.  The default is $default_destination_concurrency_limit for
-# most delivery transports. For the local delivery agent the default is 2.
-
-#local_destination_concurrency_limit = 2
-#default_destination_concurrency_limit = 20
-
-# INSTALL-TIME CONFIGURATION INFORMATION
-readme_directory = /etc/postfix/README_FILES
-sample_directory = /etc/postfix/samples
-sendmail_path = /usr/sbin/sendmail
-setgid_group = postdrop
-command_directory = /usr/sbin
-manpage_directory = /usr/share/man
-daemon_directory = /usr/lib/postfix
-newaliases_path = /usr/bin/newaliases
-mailq_path = /usr/bin/mailq
-queue_directory = /var/spool/postfix
-mail_owner = postfix
-
-# SASL authenticated SMTPD
-#smtpd_sasl_auth_enable = yes
-#broken_sasl_auth_clients = yes
-#smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, check_relay_domains
-#smtpd_etrn_restrictions = permit_mynetworks, reject
-
-# Virtual users
-virtual_maps = hash:/etc/postfix/virtual
-virtual_alias_maps = ldap:vlocal, ldap:vforward
-
-# Delivery for Local, Local/Forward and Alias
-vlocal_server_host = localhost
-vlocal_search_base = dc=example,dc=com
-vlocal_query_filter = (&(objectClass=gosaMailAccount)(gosaMailDeliveryMode=[*L*])(|(mail=%s)(gosaMailAlternateAddress=%s)))
-vlocal_result_attribute = uid,gosaMailForwardingAddress,memberUid
-
-# Delivery when Forward only
-vforward_server_host = localhost
-vforward_search_base = dc=example,dc=com
-vforward_query_filter = (&(objectClass=gosaMailAccount)(!(gosaMailDeliveryMode=[*L*]))(|(mail=%s)(gosaMailAlternateAddress=%s)))
-vforward_result_attribute = gosaMailForwardingAddress
-
diff --git a/contrib/altlinux/etc/samba/smb.conf b/contrib/altlinux/etc/samba/smb.conf
deleted file mode 100644 (file)
index 6910adb..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#======================= Global Settings =====================================
-[global]
-       ldap server = localhost
-       ldap port = 389
-       ldap suffix = dc=example,dc=com
-       ldap admin dn = cn=smbpasswd,ou=Apps,dc=example,dc=com
-       
-       ldap user suffix = ou=People
-       ldap group suffix = ou=Groups
-       ldap machine suffix = ou=Computers
-       ldap passwd sync = Yes
-
-       workgroup = EXAMPLE
-       netbios name = PDC
-       server string =  Samba server on %h (v. %v)
-       #realm = PDC.EXAMPLE.TLD
-       announce version = 4.8
-       time server = Yes
-
-       log file = /var/log/samba/log.%m
-       max log size = 50
-
-       security = user
-       hosts allow = 192.168.1. 127.
-       encrypt passwords = yes
-       null passwords = No
-       min passwd length = 6
-       smb passwd file = /etc/samba/smbpasswd
-       socket options = TCP_NODELAY
-       os level = 254
-       nt acl support = No
-       passdb backend = ldapsam:ldap://localhost
-
-       domain master = yes 
-       preferred master = yes
-       domain logons = yes
-       dns proxy = no 
-
-       #dos charset = CP866
-       #unix charset = KOI8-R
-       #display charset = KOI8-R
-       use sendfile = yes
-       preserve case = Yes
-       short preserve case = Yes
-       case sensitive = Yes
-       hide dot files = Yes
-
-#============================ Share Definitions ==============================
-[homes]
-   comment = Home Directory for '%u'
-   browseable = no
-   writable = yes
-
-# Un-comment the following and create the netlogon directory for Domain Logons
-[netlogon]
-   comment = Network Logon Service
-   path = /var/lib/samba/netlogon
-   guest ok = yes
-   browsable = no
-   writable = no
-
-#Uncomment the following 2 lines if you would like your login scripts to
-#be created dynamically by ntlogon (check that you have it in the correct
-#location (the default of the ntlogon rpm available in contribs)
-;root preexec = /usr/bin/ntlogon -u %U -g %G -o %a -d /var/lib/samba/netlogon
-;root postexec = rm -f /var/lib/samba/netlogon/%U.bat
-
-# Un-comment the following to provide a specific roving profile share
-# the default is to use the user's home directory
-;[Profiles]
-;    path = /var/lib/samba/profiles
-;    browseable = no
-;    guest ok = yes
diff --git a/contrib/altlinux/etc/sasl2/imapd.conf b/contrib/altlinux/etc/sasl2/imapd.conf
deleted file mode 100644 (file)
index 993c2b0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-pwcheck_method: saslauthd
-mech_list: login plain
diff --git a/contrib/altlinux/etc/sasl2/saslauthd.conf b/contrib/altlinux/etc/sasl2/saslauthd.conf
deleted file mode 100644 (file)
index f713903..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-ldap_servers: ldap://localhost/
-ldap_bind_dn: cn=saslauthd,ou=Apps,dc=example,dc=com
-ldap_bind_pw: saslauthd
-ldap_version: 3
-# <2|3>
-#      Specify the LDAP protocol version to use.
-
-ldap_timeout: 5
-#      Specify a number of seconds a search can take before timing out.
-
-ldap_time_limit: 5
-#      Specify a number of seconds for a search request to complete.
-
-#ldap_deref: <none> <search|find|always|never>
-#      Specify how aliases dereferencing is handled during a search.
-
-#ldap_referrals: <no>
-#      Specify whether or not the client should follow referrals.
-
-#ldap_restart: <yes>
-#      Specify whether or not LDAP I/O operations are automatically restarted
-#      if they abort prematurely.
-
-#ldap_cache_ttl: <0>
-#      Non zero enables client side caching.  Cached results will expire after
-#      specified number seconds, e.g. 30.  Use this option with care.
-#      OpenLDAP folks consider this feature experimental.
-
-#ldap_cache_mem: <0>
-#      If client side caching is enabled, the value specifies the cache size
-#      in bytes,  e.g. 32768.
-       
-#ldap_scope: <sub> <sub|one|base>
-#      Search scope.
-
-ldap_search_base: dc=iph,dc=ras,dc=ru
-#      Specify a starting point for the search.  e.g. dc=foo,dc=com
-
-#ldap_auth_method: <bind> <bind|custom>
-#      Specify an authentication method.  The default 'bind' method uses the
-#      LDAP simple bind facility to verify the password.  The custom method
-#      uses userPassword attribute to verify the password.  Currently, {CRYPT}
-#      hash is supported.
-
-ldap_filter: (|(uid=%u)(cn=%u))
-#      Specify a filter.  Use the %u and %r tokens for the username and realm
-#      substitution.  The %u token has to be used at minimum for the filter to
-#      be useful.  If ldap_auth_method is 'bind', the filter will search for
-#      the DN (distinguished name) attribute.  Otherwise, the search will look
-#      for the userPassword attribute.
-
-#ldap_debug: <0>
-#      Specify a debugging level in the OpenLDAP libraries.  See
-#      ldap_set_option(3) for more (LDAP_OPT_DEBUG_LEVEL).
-#
-#ldap_tls_check_peer: <no> <yes|no>
-#      Require and verify server certificate.  If this option is yes,
-#      you must specify ldap_tls_cacert_file or ldap_tls_cacert_dir.
-
-#ldap_tls_cacert_file: <none>
-#      File containing CA (Certificate Authority) certificate(s).
-
-#ldap_tls_cacert_dir: <none>
-#      Path to directory with CA (Certificate Authority) certificates.
-
-#ldap_tls_ciphers: <DEFAULT>
-#      List of SSL/TLS ciphers to allow.  The format of the string is
-#      described in ciphers(1).
-
-#ldap_tls_cert: <none>
-#      File containing the client certificate.
-
-#ldap_tls_key: <none>
-#      File containing the private client key.
diff --git a/contrib/altlinux/etc/services b/contrib/altlinux/etc/services
deleted file mode 100644 (file)
index 9251a48..0000000
+++ /dev/null
@@ -1,557 +0,0 @@
-# /etc/services:
-# $Id: services,v 1.1 2004/12/08 07:22:10 migor-guest Exp $
-#
-# Network services, Internet style
-#
-# Note that it is presently the policy of IANA to assign a single well-known
-# port number for both TCP and UDP; hence, most entries here have two entries
-# even if the protocol doesn't support UDP operations.
-# Updated from RFC 1700, ``Assigned Numbers'' (October 1994).  Not all ports
-# are included, only the more common ones.
-#
-# The latest IANA port assignments can be gotten from
-#      http://www.iana.org/assignments/port-numbers
-# The Well Known Ports are those from 0 through 1023.
-# The Registered Ports are those from 1024 through 49151
-# The Dynamic and/or Private Ports are those from 49152 through 65535
-#
-# Each line describes one service, and is of the form:
-# 
-# service-name  port/protocol  [aliases ...]   [# comment]
-
-tcpmux         1/tcp                           # TCP port service multiplexer
-tcpmux         1/udp                           # TCP port service multiplexer
-rje            5/tcp                           # Remote Job Entry
-rje            5/udp                           # Remote Job Entry
-echo           7/tcp
-echo           7/udp
-discard                9/tcp           sink null
-discard                9/udp           sink null
-systat         11/tcp          users           # Active Users
-systat         11/udp          users           # Active Users
-daytime                13/tcp
-daytime                13/udp
-qotd           17/tcp          quote           # Quote of the Day
-qotd           17/udp          quote           # Quote of the Day
-msp            18/tcp                          # Message Send Protocol
-msp            18/udp                          # Message Send Protocol
-chargen                19/tcp          ttytst source   # Character Generator
-chargen                19/udp          ttytst source   # Character Generator
-ftp-data       20/tcp                          # File Transfer [Default Data]
-ftp-data       20/udp                          # File Transfer [Default Data]
-# 21 is registered to ftp, but also used by fsp
-ftp            21/tcp                          # File Transfer [Control]
-ftp            21/udp          fsp fspd        # File Transfer [Control]
-ssh            22/tcp                          # SSH Remote Login Protocol
-ssh            22/udp                          # SSH Remote Login Protocol
-telnet         23/tcp
-telnet         23/udp
-# 24 - private mail system
-smtp           25/tcp          mail            # Simple Mail Transfer Protocol
-smtp           25/udp          mail            # Simple Mail Transfer Protocol
-time           37/tcp          timserver
-time           37/udp          timserver
-rlp            39/tcp          resource        # Resource Location Protocol
-rlp            39/udp          resource        # Resource Location Protocol
-nameserver     42/tcp          name            # Host Name Server
-nameserver     42/udp          name            # Host Name Server
-nicname                43/tcp          whois
-nicname                43/udp          whois
-tacacs         49/tcp                          # Login Host Protocol (TACACS)
-tacacs         49/udp                          # Login Host Protocol (TACACS)
-re-mail-ck     50/tcp                          # Remote Mail Checking Protocol
-re-mail-ck     50/udp                          # Remote Mail Checking Protocol
-domain         53/tcp                          # Domain Name Server
-domain         53/udp                          # Domain Name Server
-whois++                63/tcp
-whois++                63/udp
-bootps         67/tcp                          # BOOTP server
-bootps         67/udp
-bootpc         68/tcp                          # BOOTP client
-bootpc         68/udp
-tftp           69/tcp                          # Trivial File Transfer
-tftp           69/udp                          # Trivial File Transfer
-gopher         70/tcp                          # Internet Gopher
-gopher         70/udp
-netrjs-1       71/tcp                          # Remote Job Service
-netrjs-1       71/udp                          # Remote Job Service
-netrjs-2       72/tcp                          # Remote Job Service
-netrjs-2       72/udp                          # Remote Job Service
-netrjs-3       73/tcp                          # Remote Job Service
-netrjs-3       73/udp                          # Remote Job Service
-netrjs-4       74/tcp                          # Remote Job Service
-netrjs-4       74/udp                          # Remote Job Service
-finger         79/tcp
-finger         79/udp
-http           80/tcp          www www-http    # World Wide Web HTTP
-http           80/udp          www www-http    # HyperText Transfer Protocol
-kerberos       88/tcp          kerberos5 krb5  # Kerberos v5
-kerberos       88/udp          kerberos5 krb5  # Kerberos v5
-supdup         95/tcp
-supdup         95/udp
-hostname       101/tcp         hostnames       # usually from sri-nic
-hostname       101/udp         hostnames       # usually from sri-nic
-iso-tsap       102/tcp         tsap            # part of ISODE.
-csnet-ns       105/tcp         cso             # also used by CSO name server
-csnet-ns       105/udp         cso
-# unfortunately the poppassd (Eudora) uses a port which has already
-# been assigned to a different service. We list the poppassd as an
-# alias here. This should work for programs asking for this service.
-# (due to a bug in inetd the 3com-tsmux line is disabled)
-#3com-tsmux    106/tcp         poppassd
-#3com-tsmux    106/udp         poppassd
-rtelnet                107/tcp                         # Remote Telnet
-rtelnet                107/udp
-pop2           109/tcp         pop-2   postoffice      # POP version 2
-pop2           109/udp         pop-2
-pop3           110/tcp         pop-3           # POP version 3
-pop3           110/udp         pop-3
-sunrpc         111/tcp         portmapper      # RPC 4.0 portmapper TCP
-sunrpc         111/udp         portmapper      # RPC 4.0 portmapper UDP
-auth           113/tcp         authentication tap ident
-auth           113/udp         authentication tap ident
-sftp           115/tcp
-sftp           115/udp
-uucp-path      117/tcp
-uucp-path      117/udp
-nntp           119/tcp         readnews untp   # USENET News Transfer Protocol
-nntp           119/udp         readnews untp   # USENET News Transfer Protocol
-ntp            123/tcp
-ntp            123/udp                         # Network Time Protocol
-pwdgen         129/tcp                         # Password Generator Protocol
-pwdgen         129/udp                         # Password Generator Protocol
-netbios-ns     137/tcp                         # NETBIOS Name Service
-netbios-ns     137/udp
-netbios-dgm    138/tcp                         # NETBIOS Datagram Service
-netbios-dgm    138/udp
-netbios-ssn    139/tcp                         # NETBIOS session service
-netbios-ssn    139/udp
-imap           143/tcp         imap2           # Interim Mail Access Proto v2
-imap           143/udp         imap2
-snmp           161/tcp                         # Simple Net Mgmt Proto
-snmp           161/udp                         # Simple Net Mgmt Proto
-snmptrap       162/udp         snmp-trap       # Traps for SNMP
-cmip-man       163/tcp                         # ISO mgmt over IP (CMOT)
-cmip-man       163/udp
-cmip-agent     164/tcp
-cmip-agent     164/udp
-mailq          174/tcp                         # MAILQ
-mailq          174/udp                         # MAILQ
-xdmcp          177/tcp                         # X Display Mgr. Control Proto
-xdmcp          177/udp
-nextstep       178/tcp         NeXTStep NextStep       # NeXTStep window
-nextstep       178/udp         NeXTStep NextStep       # server
-bgp            179/tcp                         # Border Gateway Proto.
-bgp            179/udp
-prospero       191/tcp                         # Cliff Neuman's Prospero
-prospero       191/udp
-irc            194/tcp                         # Internet Relay Chat
-irc            194/udp
-smux           199/tcp                         # SNMP Unix Multiplexer
-smux           199/udp
-at-rtmp                201/tcp                         # AppleTalk routing
-at-rtmp                201/udp
-at-nbp         202/tcp                         # AppleTalk name binding
-at-nbp         202/udp
-at-echo                204/tcp                         # AppleTalk echo
-at-echo                204/udp
-at-zis         206/tcp                         # AppleTalk zone information
-at-zis         206/udp
-qmtp           209/tcp                         # Quick Mail Transfer Protocol
-qmtp           209/udp                         # Quick Mail Transfer Protocol
-z39.50         210/tcp         z3950 wais      # NISO Z39.50 database 
-z39.50         210/udp         z3950 wais
-ipx            213/tcp                         # IPX
-ipx            213/udp
-imap3          220/tcp                         # Interactive Mail Access
-imap3          220/udp                         # Protocol v3
-link           245/tcp         ttylink
-link           245/ucp         ttylink
-fatserv                347/tcp                         # Fatmen Server
-fatserv                347/udp                         # Fatmen Server
-rsvp_tunnel    363/tcp
-rsvp_tunnel    363/udp
-rpc2portmap    369/tcp
-rpc2portmap    369/udp                         # Coda portmapper
-codaauth2      370/tcp
-codaauth2      370/udp                         # Coda authentication server
-ulistproc      372/tcp         ulistserv       # UNIX Listserv
-ulistproc      372/udp         ulistserv
-ldap           389/tcp
-ldap           389/udp
-svrloc          427/tcp                                # Server Location Protocl
-svrloc          427/udp                                # Server Location Protocl
-mobileip-agent 434/tcp
-mobileip-agent 434/udp
-mobilip-mn     435/tcp
-mobilip-mn     435/udp
-https          443/tcp                         # MCom
-https          443/udp                         # MCom
-snpp           444/tcp                         # Simple Network Paging Protocol
-snpp           444/udp                         # Simple Network Paging Protocol
-microsoft-ds   445/tcp
-microsoft-ds   445/udp
-kpasswd                464/tcp         kpwd            # Kerberos "passwd"
-kpasswd                464/udp         kpwd            # Kerberos "passwd"
-photuris       468/tcp
-photuris       468/udp
-saft           487/tcp                         # Simple Asynchronous File Transfer
-saft           487/udp                         # Simple Asynchronous File Transfer
-gss-http       488/tcp
-gss-http       488/udp
-pim-rp-disc    496/tcp
-pim-rp-disc    496/udp
-isakmp         500/tcp
-isakmp         500/udp
-gdomap         538/tcp                         # GNUstep distributed objects
-gdomap         538/udp                         # GNUstep distributed objects
-iiop           535/tcp
-iiop           535/udp
-dhcpv6-client  546/tcp
-dhcpv6-client  546/udp
-dhcpv6-server  547/tcp
-dhcpv6-server  547/udp
-rtsp           554/tcp                         # Real Time Stream Control Protocol
-rtsp           554/udp                         # Real Time Stream Control Protocol
-nntps          563/tcp                         # NNTP over SSL
-nntps          563/udp                         # NNTP over SSL
-whoami         565/tcp
-whoami         565/udp
-submission     587/tcp         msa             # mail message submission
-submission     587/udp         msa             # mail message submission
-npmp-local     610/tcp         dqs313_qmaster  # npmp-local / DQS
-npmp-local     610/udp         dqs313_qmaster  # npmp-local / DQS
-npmp-gui       611/tcp         dqs313_execd    # npmp-gui / DQS
-npmp-gui       611/udp         dqs313_execd    # npmp-gui / DQS
-hmmp-ind       612/tcp         dqs313_intercell # HMMP Indication / DQS
-hmmp-ind       612/udp         dqs313_intercell # HMMP Indication / DQS
-ipp            631/tcp                         # Internet Printing Protocol
-ipp            631/ucp                         # Internet Printing Protocol
-ldaps          636/tcp                         # LDAP over SSL
-ldaps          636/udp                         # LDAP over SSL
-acap           674/tcp
-acap           674/udp
-ha-cluster     694/tcp                         # Heartbeat HA-cluster
-ha-cluster     694/udp                         # Heartbeat HA-cluster
-kerberos-adm   749/tcp                         # Kerberos `kadmin' (v5)
-kerberos-iv    750/udp         kerberos4 kerberos-sec kdc
-kerberos-iv    750/tcp         kerberos4 kerberos-sec kdc
-webster                765/tcp                         # Network dictionary
-webster                765/udp
-phonebook      767/tcp                         # Network phonebook
-phonebook      767/udp
-rsync          873/tcp                         # rsync
-rsync          873/udp                         # rsync
-telnets                992/tcp
-telnets                992/udp
-imaps          993/tcp                         # IMAP over SSL
-imaps          993/udp                         # IMAP over SSL
-ircs           994/tcp
-ircs           994/udp
-pop3s          995/tcp                         # POP-3 over SSL
-pop3s          995/udp                         # POP-3 over SSL
-
-#
-# UNIX specific services
-#
-exec           512/tcp
-biff           512/udp         comsat
-login          513/tcp
-who            513/udp         whod
-shell          514/tcp         cmd             # no passwords used
-syslog         514/udp
-printer                515/tcp         spooler         # line printer spooler
-printer                515/udp         spooler         # line printer spooler
-talk           517/udp
-ntalk          518/udp
-utime          519/tcp         unixtime
-utime          519/udp         unixtime
-efs            520/tcp
-router         520/udp         route routed    # RIP
-ripng          521/tcp
-ripng          521/udp
-timed          525/tcp         timeserver
-timed          525/udp         timeserver
-tempo          526/tcp         newdate
-courier                530/tcp         rpc
-conference     531/tcp         chat
-netnews                532/tcp
-netwall                533/udp                         # -for emergency broadcasts
-uucp           540/tcp         uucpd           # uucp daemon
-klogin         543/tcp                         # Kerberized `rlogin' (v5)
-kshell         544/tcp         krcmd           # Kerberized `rsh' (v5)
-afpovertcp     548/tcp                         # AFP over TCP
-afpovertcp     548/udp                         # AFP over TCP
-remotefs       556/tcp         rfs_server rfs  # Brunhoff remote filesystem
-
-#
-# From ``PORT NUMBERS'':
-#
-#>REGISTERED PORT NUMBERS
-#>
-#>The Registered Ports are listed by the IANA and on most systems can be
-#>used by ordinary user processes or programs executed by ordinary
-#>users.
-#>
-#>Ports are used in the TCP [RFC793] to name the ends of logical
-#>connections which carry long term conversations.  For the purpose of
-#>providing services to unknown callers, a service contact port is
-#>defined.  This list specifies the port used by the server process as
-#>its contact port.
-#>
-#>The IANA registers uses of these ports as a convienence to the
-#>community.
-#
-socks          1080/tcp                        # socks proxy server
-socks          1080/udp                        # socks proxy server
-h323hostcallsc 1300/tcp                        # H323 Host Call Secure
-h323hostcallsc 1300/udp                        # H323 Host Call Secure
-ms-sql-s       1433/tcp                        # Microsoft-SQL-Server 
-ms-sql-s       1433/udp                        # Microsoft-SQL-Server 
-ms-sql-m       1434/tcp                        # Microsoft-SQL-Monitor
-ms-sql-m       1434/udp                        # Microsoft-SQL-Monitor          
-ica            1494/tcp                        # Citrix ICA Client
-ica            1494/udp                        # Citrix ICA Client
-wins           1512/tcp                        # Microsoft's Windows Internet Name Service
-wins           1512/udp                        # Microsoft's Windows Internet Name Service
-ingreslock     1524/tcp
-ingreslock     1524/udp
-prospero-np    1525/tcp                        # Prospero non-privileged
-prospero-np    1525/udp
-datametrics    1645/tcp        old-radius      # datametrics / old radius entry
-datametrics    1645/udp        old-radius      # datametrics / old radius entry
-sa-msg-port    1646/tcp        old-radacct     # sa-msg-port / old radacct entry
-sa-msg-port    1646/udp        old-radacct     # sa-msg-port / old radacct entry
-kermit         1649/tcp
-kermit         1649/udp
-l2tp           1701/tcp        l2f
-l2tp           1701/udp        l2f
-h323gatedisc   1718/tcp
-h323gatedisc   1718/udp
-h323gatestat   1719/tcp
-h323gatestat   1719/udp
-h323hostcall   1720/tcp
-h323hostcall   1720/udp
-tftp-mcast     1758/tcp
-tftp-mcast     1758/udp
-hello          1789/tcp
-hello          1789/udp
-radius         1812/tcp                        # Radius
-radius         1812/udp                        # Radius
-radius-acct    1813/tcp        radacct         # Radius Accounting
-radius-acct    1813/udp        radacct         # Radius Accounting
-mtp            1911/tcp                        #
-mtp            1911/udp                        #
-hsrp           1985/tcp                        # Cisco Hot Standby Router Protocol
-hsrp           1985/udp                        # Cisco Hot Standby Router Protocol
-licensedaemon  1986/tcp
-licensedaemon  1986/udp
-gdp-port       1997/tcp                        # Cisco Gateway Discovery Protocol
-gdp-port       1997/udp                        # Cisco Gateway Discovery Protocol
-nfs            2049/tcp        nfsd
-nfs            2049/udp        nfsd
-zephyr-srv     2102/tcp                        # Zephyr server
-zephyr-srv     2102/udp                        # Zephyr server
-zephyr-clt     2103/tcp                        # Zephyr serv-hm connection
-zephyr-clt     2103/udp                        # Zephyr serv-hm connection
-zephyr-hm      2104/tcp                        # Zephyr hostmanager
-zephyr-hm      2104/udp                        # Zephyr hostmanager
-cvspserver     2401/tcp                        # CVS client/server operations
-cvspserver     2401/udp                        # CVS client/server operations
-venus          2430/tcp                        # codacon port
-venus          2430/udp                        # Venus callback/wbc interface
-venus-se       2431/tcp                        # tcp side effects
-venus-se       2431/udp                        # udp sftp side effect
-codasrv                2432/tcp                        # not used
-codasrv                2432/udp                        # server port
-codasrv-se     2433/tcp                        # tcp side effects
-codasrv-se     2433/udp                        # udp sftp side effectQ
-
-# Ports numbered 2600 through 2606 are used by the zebra package.  The primary
-# names are the registered names, and the zebra names are listed as aliases.
-hpstgmgr       2600/tcp        zebrasrv        # HPSTGMGR
-hpstgmgr       2600/udp                        # HPSTGMGR
-discp-client   2601/tcp        zebra           # discp client
-discp-client   2601/udp                        # discp client
-discp-server   2602/tcp        ripd            # discp server
-discp-server   2602/udp                        # discp server
-servicemeter   2603/tcp        ripngd          # Service Meter
-servicemeter   2603/udp                        # Service Meter
-nsc-ccs                2604/tcp        ospfd           # NSC CCS
-nsc-ccs                2604/udp                        # NSC CCS
-nsc-posa       2605/tcp        bgpd            # NSC POSA
-nsc-posa       2605/udp                        # NSC POSA
-netmon         2606/tcp        ospf6d          # Dell Netmon
-netmon         2606/udp                        # Dell Netmon
-
-corbaloc       2809/tcp                        # CORBA naming service locator
-icpv2          3130/tcp                        # Internet Cache Protocol V2 (Squid)
-icpv2          3130/udp                        # Internet Cache Protocol V2 (Squid)
-mysql          3306/tcp                        # MySQL
-mysql          3306/udp                        # MySQL
-trnsprntproxy   3346/tcp                       # Trnsprnt Proxy
-trnsprntproxy   3346/udp                       # Trnsprnt Proxy
-rwhois         4321/tcp                        # Remote Who Is
-rwhois         4321/udp                        # Remote Who Is
-krb524         4444/tcp                        # Kerberos 5 to 4 ticket xlator
-krb524         4444/udp                        # Kerberos 5 to 4 ticket xlator
-rfe            5002/tcp                        # Radio Free Ethernet
-rfe            5002/udp                        # Actually uses UDP only
-jabber-client  5222/tcp                        # Jabber Client Connection
-jabber-client  5222/udp                        # Jabber Client Connection
-jabber-server  5269/tcp                        # Jabber Server Connection
-jabber-server  5269/udp                        # Jabber Server Connection
-cfengine       5308/tcp                        # CFengine
-cfengine       5308/udp                        # CFengine
-cvsup           5999/tcp       CVSup           # CVSup file transfer/John Polstra/FreeBSD
-cvsup           5999/udp       CVSup           # CVSup file transfer/John Polstra/FreeBSD
-x11            6000/tcp        X               # the X Window System
-afs3-fileserver 7000/tcp                       # file server itself
-afs3-fileserver 7000/udp                       # file server itself
-afs3-callback   7001/tcp                       # callbacks to cache managers
-afs3-callback   7001/udp                       # callbacks to cache managers
-afs3-prserver   7002/tcp                       # users & groups database
-afs3-prserver   7002/udp                       # users & groups database
-afs3-vlserver   7003/tcp                       # volume location database
-afs3-vlserver   7003/udp                       # volume location database
-afs3-kaserver   7004/tcp                       # AFS/Kerberos authentication service
-afs3-kaserver   7004/udp                       # AFS/Kerberos authentication service
-afs3-volser     7005/tcp                       # volume managment server
-afs3-volser     7005/udp                       # volume managment server
-afs3-errors     7006/tcp                       # error interpretation service
-afs3-errors     7006/udp                       # error interpretation service
-afs3-bos        7007/tcp                       # basic overseer process
-afs3-bos        7007/udp                       # basic overseer process
-afs3-update     7008/tcp                       # server-to-server updater
-afs3-update     7008/udp                       # server-to-server updater
-afs3-rmtsys     7009/tcp                       # remote cache manager service
-afs3-rmtsys     7009/udp                       # remote cache manager service
-sd             9876/tcp                        # Session Director
-sd             9876/udp                        # Session Director
-amanda         10080/tcp                       # amanda backup services
-amanda         10080/udp                       # amanda backup services
-pgpkeyserver   11371/tcp                       # PGP/GPG public keyserver
-pgpkeyserver   11371/udp                       # PGP/GPG public keyserver
-h323callsigalt 11720/tcp                       # H323 Call Signal Alternate
-h323callsigalt 11720/udp                       # H323 Call Signal Alternate
-
-# This port is registered as wnn6, but also used under the name "wnn4" by the
-# FreeWnn package.
-wnn6           22273/tcp       wnn4
-wnn6           22273/ucp       wnn4
-
-quake          26000/tcp
-quake          26000/udp
-wnn6-ds                26208/tcp
-wnn6-ds                26208/udp
-traceroute     33434/tcp
-traceroute     33434/udp
-
-#
-# Datagram Delivery Protocol services
-#
-rtmp           1/ddp                           # Routing Table Maintenance Protocol
-nbp            2/ddp                           # Name Binding Protocol
-echo           4/ddp                           # AppleTalk Echo Protocol
-zip            6/ddp                           # Zone Information Protocol
-
-#
-# Kerberos (Project Athena/MIT) services
-# Note that these are for Kerberos v4, and are unofficial.  Sites running
-# v4 should uncomment these and comment out the v5 entries above.
-#
-kerberos_master        751/udp                         # Kerberos authentication
-kerberos_master        751/tcp                         # Kerberos authentication
-passwd_server  752/udp                         # Kerberos passwd server
-krbupdate      760/tcp         kreg            # Kerberos registration
-kpop           1109/tcp                        # Pop with Kerberos
-knetd          2053/tcp                        # Kerberos de-multiplexor
-
-#
-# Kerberos 5 services, also not registered with IANA
-#
-krb5_prop      754/tcp                         # Kerberos slave propagation
-eklogin                2105/tcp                        # Kerberos encrypted rlogin
-
-#
-# Unregistered but necessary (for NetBSD) services
-#
-supfilesrv     871/tcp                         # SUP server
-supfiledbg     1127/tcp                        # SUP debugging
-
-#
-# Unregistered but useful/necessary other services
-#
-netstat                15/tcp                          # (was once asssigned, no more)
-linuxconf      98/tcp                          # Linuxconf HTML access
-poppassd       106/tcp                         # Eudora
-poppassd       106/udp                         # Eudora
-smtps          465/tcp                         # SMTP over SSL (TLS)
-gii            616/tcp                         # gated interactive interface
-omirr          808/tcp         omirrd          # online mirror
-omirr          808/udp         omirrd          # online mirror
-swat           901/tcp                         # Samba Web Administration Tool
-rndc           953/tcp                         # rndc control sockets (BIND 9)
-rndc           953/udp                         # rndc control sockets (BIND 9)
-skkserv                1178/tcp                        # SKK Japanese input method
-rmtcfg         1236/tcp                        # Gracilis Packeten remote config server
-xtel           1313/tcp                        # french minitel
-lotusnote      1352/tcp        lotusnotes      # Lotus notes
-lotusnote      1352/udp        lotusnotes      # Lotus notes
-support                1529/tcp        prmsd gnatsd    # GNATS, cygnus bug tracker
-cfinger                2003/tcp                        # GNU Finger
-ninstall       2150/tcp                        # ninstall service
-ninstall       2150/udp                        # ninstall service
-afbackup       2988/tcp                        # Afbackup system
-afbackup       2988/udp                        # Afbackup system
-squid          3128/tcp                        # squid web proxy
-prsvp          3455/tcp                        # RSVP Port
-prsvp          3455/udp                        # RSVP Port
-postgres       5432/tcp                        # POSTGRES
-postgres       5432/udp                        # POSTGRES
-fax            4557/tcp                        # FAX transmission service        (old)
-hylafax                4559/tcp                        # HylaFAX client-server protocol  (new)
-sgi-dgl                5232/tcp                        # SGI Distributed Graphics
-sgi-dgl                5232/udp
-noclog         5354/tcp                        # noclogd with TCP (nocol)
-noclog         5354/udp                        # noclogd with UDP (nocol)
-hostmon                5355/tcp                        # hostmon uses TCP (nocol)
-hostmon                5355/udp                        # hostmon uses TCP (nocol)
-canna          5680/tcp
-x11-ssh-offset 6010/tcp                        # SSH X11 forwarding offset
-ircd           6667/tcp                        # Internet Relay Chat
-ircd           6667/udp                        # Internet Relay Chat
-xfs            7100/tcp                        # X font server
-tircproxy      7666/tcp                        # Tircproxy
-http-alt       8008/tcp
-http-alt       8008/udp
-webcache       8080/tcp                        # WWW caching service
-webcache       8080/udp                        # WWW caching service
-tproxy         8081/tcp                        # Transparent Proxy
-tproxy         8081/udp                        # Transparent Proxy
-jetdirect      9100/tcp        laserjet hplj   #
-mandelspawn    9359/udp        mandelbrot      # network mandelbrot
-kamanda                10081/tcp                       # amanda backup services (Kerberos)
-kamanda                10081/udp                       # amanda backup services (Kerberos)
-amandaidx      10082/tcp                       # amanda backup services
-amidxtape      10083/tcp                       # amanda backup services
-ladcca         14541/tcp                       # LADCCA client/server protocol
-isdnlog                20011/tcp                       # isdn logging system
-isdnlog                20011/udp                       # isdn logging system
-vboxd          20012/tcp                       # voice box system
-vboxd          20012/udp                       # voice box system
-wnn4_Kr                22305/tcp                       # used by the kWnn package
-wnn4_Cn                22289/tcp                       # used by the cWnn package
-wnn4_Tw                22321/tcp                       # used by the tWnn package
-binkp          24554/tcp                       # Binkley
-binkp          24554/udp                       # Binkley
-asp            27374/tcp                       # Address Search Protocol
-asp            27374/udp                       # Address Search Protocol
-tfido          60177/tcp                       # Ifmail
-tfido          60177/udp                       # Ifmail
-fido           60179/tcp                       # Ifmail
-fido           60179/udp                       # Ifmail
-
-# Cyrus SIEVE service
-sieve          2000/tcp
-sieve          2000/udp
diff --git a/contrib/altlinux/etc/squid/squid.conf b/contrib/altlinux/etc/squid/squid.conf
deleted file mode 100644 (file)
index 5d2459b..0000000
+++ /dev/null
@@ -1,3303 +0,0 @@
-
-#      WELCOME TO SQUID 2
-#      ------------------
-#
-#      This is the default Squid configuration file. You may wish
-#      to look at the Squid home page (http://www.squid-cache.org/)
-#      for the FAQ and other documentation.
-#
-#      The default Squid config file shows what the defaults for
-#      various options happen to be.  If you don't need to change the
-#      default, you shouldn't uncomment the line.  Doing so may cause
-#      run-time problems.  In some cases "none" refers to no default
-#      setting at all, while in other cases it refers to a valid
-#      option - the comments for that keyword indicate if this is the
-#      case.
-#
-
-
-# NETWORK OPTIONS
-# -----------------------------------------------------------------------------
-
-#  TAG: http_port
-#      Usage:  port
-#              hostname:port
-#              1.2.3.4:port
-#
-#      The socket addresses where Squid will listen for HTTP client
-#      requests.  You may specify multiple socket addresses.
-#      There are three forms: port alone, hostname with port, and
-#      IP address with port.  If you specify a hostname or IP
-#      address, then Squid binds the socket to that specific
-#      address.  This replaces the old 'tcp_incoming_address'
-#      option.  Most likely, you do not need to bind to a specific
-#      address, so you can use the port number alone.
-#
-#      The default port number is 3128.
-#
-#      If you are running Squid in accelerator mode, then you
-#      probably want to listen on port 80 also, or instead.
-#
-#      The -a command line option will override the *first* port
-#      number listed here.   That option will NOT override an IP
-#      address, however.
-#
-#      You may specify multiple socket addresses on multiple lines.
-#
-#      If you run Squid on a dual-homed machine with an internal
-#      and an external interface then we recommend you to specify the
-#      internal address:port in http_port. This way Squid will only be
-#      visible on the internal address.
-#
-#Default:
-# http_port 3128
-
-#  TAG: https_port
-#        Usage:  [ip:]port cert=certificate.pem [key=key.pem] [options...]
-#
-#        The socket address where Squid will listen for HTTPS client
-#        requests.
-#
-#        This is really only useful for situations where you are running
-#        squid in accelerator mode and you want to do the SSL work at the
-#        accelerator level.
-#
-#      You may specify multiple socket addresses on multiple lines,
-#      each with their own SSL certificate and/or options.
-#                            
-#      Options:
-#
-#         cert=        Path to SSL certificate (PEM format)
-#              
-#         key=         Path to SSL private key file (PEM format)
-#                      if not specified, the certificate file is
-#                      assumed to be a combined certificate and
-#                      key file
-#
-#         version=     The version of SSL/TLS supported
-#                          1   automatic (default)
-#                          2   SSLv2 only
-#                          3   SSLv3 only
-#                          4   TLSv1 only
-#
-#         cipher=      Colon separated list of supported ciphers
-#
-#         options=     Varions SSL engine options. The most important
-#                      being:
-#                          NO_SSLv2  Disallow the use of SSLv2
-#                          NO_SSLv3  Disallow the use of SSLv3
-#                          NO_TLSv1  Disallow the use of TLSv1
-#                      See src/ssl_support.c or OpenSSL documentation
-#                      for a more complete list.
-#
-#Default:
-# none
-
-#  TAG: ssl_unclean_shutdown
-#      Some browsers (especially MSIE) bugs out on SSL shutdown
-#      messages.
-#
-#Default:
-# ssl_unclean_shutdown off
-
-#  TAG: icp_port
-#      The port number where Squid sends and receives ICP queries to
-#      and from neighbor caches.  Default is 3130.  To disable use
-#      "0".  May be overridden with -u on the command line.
-#
-#Default:
-# icp_port 3130
-
-#  TAG: htcp_port
-# Note: This option is only available if Squid is rebuilt with the
-#       --enable-htcp option
-#
-#      The port number where Squid sends and receives HTCP queries to
-#      and from neighbor caches.  Default is 4827.  To disable use
-#      "0".
-#
-#Default:
-# htcp_port 4827
-
-#  TAG: mcast_groups
-#      This tag specifies a list of multicast groups which your server
-#      should join to receive multicasted ICP queries.
-#
-#      NOTE!  Be very careful what you put here!  Be sure you
-#      understand the difference between an ICP _query_ and an ICP
-#      _reply_.  This option is to be set only if you want to RECEIVE
-#      multicast queries.  Do NOT set this option to SEND multicast
-#      ICP (use cache_peer for that).  ICP replies are always sent via
-#      unicast, so this option does not affect whether or not you will
-#      receive replies from multicast group members.
-#
-#      You must be very careful to NOT use a multicast address which
-#      is already in use by another group of caches.
-#
-#      If you are unsure about multicast, please read the Multicast
-#      chapter in the Squid FAQ (http://www.squid-cache.org/FAQ/).
-#
-#      Usage: mcast_groups 239.128.16.128 224.0.1.20
-#
-#      By default, Squid doesn't listen on any multicast groups.
-#
-#Default:
-# none
-
-#  TAG: udp_incoming_address
-#  TAG: udp_outgoing_address
-#      udp_incoming_address    is used for the ICP socket receiving packets
-#                              from other caches.
-#      udp_outgoing_address    is used for ICP packets sent out to other
-#                              caches.
-#
-#      The default behavior is to not bind to any specific address.
-#
-#      A udp_incoming_address value of 0.0.0.0 indicates that Squid should
-#      listen for UDP messages on all available interfaces.
-#
-#      If udp_outgoing_address is set to 255.255.255.255 (the default)
-#      then it will use the same socket as udp_incoming_address. Only
-#      change this if you want to have ICP queries sent using another
-#      address than where this Squid listens for ICP queries from other
-#      caches.
-#
-#      NOTE, udp_incoming_address and udp_outgoing_address can not
-#      have the same value since they both use port 3130.
-#
-#Default:
-# udp_incoming_address 0.0.0.0
-# udp_outgoing_address 255.255.255.255
-
-
-# OPTIONS WHICH AFFECT THE NEIGHBOR SELECTION ALGORITHM
-# -----------------------------------------------------------------------------
-
-#  TAG: cache_peer
-#      To specify other caches in a hierarchy, use the format:
-#
-#              cache_peer hostname type http_port icp_port
-#
-#      For example,
-#
-#      #                                        proxy  icp
-#      #          hostname             type     port   port  options
-#      #          -------------------- -------- ----- -----  -----------
-#      cache_peer parent.foo.net       parent    3128  3130  [proxy-only]
-#      cache_peer sib1.foo.net         sibling   3128  3130  [proxy-only]
-#      cache_peer sib2.foo.net         sibling   3128  3130  [proxy-only]
-#
-#            type:  either 'parent', 'sibling', or 'multicast'.
-#
-#      proxy_port:  The port number where the cache listens for proxy
-#                   requests.
-#
-#        icp_port:  Used for querying neighbor caches about
-#                   objects.  To have a non-ICP neighbor
-#                   specify '7' for the ICP port and make sure the
-#                   neighbor machine has the UDP echo port
-#                   enabled in its /etc/inetd.conf file.
-#
-#          options: proxy-only
-#                   weight=n
-#                   ttl=n
-#                   no-query
-#                   default
-#                   round-robin
-#                   multicast-responder
-#                   closest-only
-#                   no-digest
-#                   no-netdb-exchange
-#                   no-delay
-#                   login=user:password | PASS | *:password
-#                   connect-timeout=nn
-#                   digest-url=url
-#                   allow-miss
-#                   max-conn
-#                   htcp
-#                   carp-load-factor
-#
-#                   use 'proxy-only' to specify that objects fetched
-#                   from this cache should not be saved locally.
-#
-#                   use 'weight=n' to specify a weighted parent.
-#                   The weight must be an integer.  The default weight
-#                   is 1, larger weights are favored more.
-#
-#                   use 'ttl=n' to specify a IP multicast TTL to use
-#                   when sending an ICP queries to this address.
-#                   Only useful when sending to a multicast group.
-#                   Because we don't accept ICP replies from random
-#                   hosts, you must configure other group members as
-#                   peers with the 'multicast-responder' option below.
-#
-#                   use 'no-query' to NOT send ICP queries to this
-#                   neighbor.
-#
-#                   use 'default' if this is a parent cache which can
-#                   be used as a "last-resort." You should probably
-#                   only use 'default' in situations where you cannot
-#                   use ICP with your parent cache(s).
-#
-#                   use 'round-robin' to define a set of parents which
-#                   should be used in a round-robin fashion in the
-#                   absence of any ICP queries.
-#
-#                   'multicast-responder' indicates that the named peer
-#                   is a member of a multicast group.  ICP queries will
-#                   not be sent directly to the peer, but ICP replies
-#                   will be accepted from it.
-#
-#                   'closest-only' indicates that, for ICP_OP_MISS
-#                   replies, we'll only forward CLOSEST_PARENT_MISSes
-#                   and never FIRST_PARENT_MISSes.
-#
-#                   use 'no-digest' to NOT request cache digests from
-#                   this neighbor.
-#
-#                   'no-netdb-exchange' disables requesting ICMP
-#                   RTT database (NetDB) from the neighbor.
-#
-#                   use 'no-delay' to prevent access to this neighbor
-#                   from influencing the delay pools.
-#
-#                   use 'login=user:password' if this is a personal/workgroup
-#                   proxy and your parent requires proxy authentication.
-#                   Note: The string can include URL escapes (i.e. %20 for
-#                   spaces). This also means that % must be written as %%.
-#
-#                   use 'login=PASS' if users must authenticate against
-#                   the upstream proxy. This will pass the users credentials
-#                   as they are to the peer proxy. This only works for the
-#                   Basic HTTP authentication sheme. Note: To combine this
-#                   with proxy_auth both proxies must share the same user
-#                   database as HTTP only allows for one proxy login.
-#                   Also be warned that this will expose your users proxy
-#                   password to the peer. USE WITH CAUTION
-#
-#                   use 'login=*:password' to pass the username to the
-#                   upstream cache, but with a fixed password. This is meant
-#                   to be used when the peer is in another administrative
-#                   domain, but it is still needed to identify each user.
-#                   The star can optionally be followed by some extra
-#                   information which is added to the username. This can
-#                   be used to identify this proxy to the peer, similar to
-#                   the login=username:password option above.
-#
-#                   use 'connect-timeout=nn' to specify a peer
-#                   specific connect timeout (also see the
-#                   peer_connect_timeout directive)
-#
-#                   use 'digest-url=url' to tell Squid to fetch the cache
-#                   digest (if digests are enabled) for this host from
-#                   the specified URL rather than the Squid default
-#                   location.
-#
-#                   use 'allow-miss' to disable Squid's use of only-if-cached
-#                   when forwarding requests to siblings. This is primarily
-#                   useful when icp_hit_stale is used by the sibling. To
-#                   extensive use of this option may result in forwarding
-#                   loops, and you should avoid having two-way peerings
-#                   with this option. (for example to deny peer usage on
-#                   requests from peer by denying cache_peer_access if the
-#                   source is a peer)
-#
-#                   use 'max-conn' to limit the amount of connections Squid
-#                   may open to this peer.
-#
-#                   use 'htcp' to send HTCP, instead of ICP, queries
-#                   to the neighbor.  You probably also want to
-#                   set the "icp port" to 4827 instead of 3130.
-#
-#                   use 'carp-load-factor=f' to define a parent
-#                   cache as one participating in a CARP array.
-#                   The 'f' values for all CARP parents must add
-#                   up to 1.0.
-#               
-#
-#      NOTE: non-ICP/HTCP neighbors must be specified as 'parent'.
-#
-#Default:
-# none
-
-#  TAG: cache_peer_domain
-#      Use to limit the domains for which a neighbor cache will be
-#      queried.  Usage:
-#
-#      cache_peer_domain cache-host domain [domain ...]
-#      cache_peer_domain cache-host !domain
-#
-#      For example, specifying
-#
-#              cache_peer_domain parent.foo.net        .edu
-#
-#      has the effect such that UDP query packets are sent to
-#      'bigserver' only when the requested object exists on a
-#      server in the .edu domain.  Prefixing the domainname
-#      with '!' means that the cache will be queried for objects
-#      NOT in that domain.
-#
-#      NOTE:   * Any number of domains may be given for a cache-host,
-#                either on the same or separate lines.
-#              * When multiple domains are given for a particular
-#                cache-host, the first matched domain is applied.
-#              * Cache hosts with no domain restrictions are queried
-#                for all requests.
-#              * There are no defaults.
-#              * There is also a 'cache_peer_access' tag in the ACL
-#                section.
-#
-#Default:
-# none
-
-#  TAG: neighbor_type_domain
-#      usage: neighbor_type_domain neighbor parent|sibling domain domain ...
-#
-#      Modifying the neighbor type for specific domains is now
-#      possible.  You can treat some domains differently than the the
-#      default neighbor type specified on the 'cache_peer' line.
-#      Normally it should only be necessary to list domains which
-#      should be treated differently because the default neighbor type
-#      applies for hostnames which do not match domains listed here.
-#
-#EXAMPLE:
-#      cache_peer  parent cache.foo.org 3128 3130
-#      neighbor_type_domain cache.foo.org sibling .com .net
-#      neighbor_type_domain cache.foo.org sibling .au .de
-#
-#Default:
-# none
-
-#  TAG: icp_query_timeout      (msec)
-#      Normally Squid will automatically determine an optimal ICP
-#      query timeout value based on the round-trip-time of recent ICP
-#      queries.  If you want to override the value determined by
-#      Squid, set this 'icp_query_timeout' to a non-zero value.  This
-#      value is specified in MILLISECONDS, so, to use a 2-second
-#      timeout (the old default), you would write:
-#
-#              icp_query_timeout 2000
-#
-#Default:
-# icp_query_timeout 0
-
-#  TAG: maximum_icp_query_timeout      (msec)
-#      Normally the ICP query timeout is determined dynamically.  But
-#      sometimes it can lead to very large values (say 5 seconds).
-#      Use this option to put an upper limit on the dynamic timeout
-#      value.  Do NOT use this option to always use a fixed (instead
-#      of a dynamic) timeout value. To set a fixed timeout see the
-#      'icp_query_timeout' directive.
-#
-#Default:
-# maximum_icp_query_timeout 2000
-
-#  TAG: mcast_icp_query_timeout        (msec)
-#      For Multicast peers, Squid regularly sends out ICP "probes" to
-#      count how many other peers are listening on the given multicast
-#      address.  This value specifies how long Squid should wait to
-#      count all the replies.  The default is 2000 msec, or 2
-#      seconds.
-#
-#Default:
-# mcast_icp_query_timeout 2000
-
-#  TAG: dead_peer_timeout      (seconds)
-#      This controls how long Squid waits to declare a peer cache
-#      as "dead."  If there are no ICP replies received in this
-#      amount of time, Squid will declare the peer dead and not
-#      expect to receive any further ICP replies.  However, it
-#      continues to send ICP queries, and will mark the peer as
-#      alive upon receipt of the first subsequent ICP reply.
-#
-#      This timeout also affects when Squid expects to receive ICP
-#      replies from peers.  If more than 'dead_peer' seconds have
-#      passed since the last ICP reply was received, Squid will not
-#      expect to receive an ICP reply on the next query.  Thus, if
-#      your time between requests is greater than this timeout, you
-#      will see a lot of requests sent DIRECT to origin servers
-#      instead of to your parents.
-#
-#Default:
-# dead_peer_timeout 10 seconds
-
-#  TAG: hierarchy_stoplist
-#      A list of words which, if found in a URL, cause the object to
-#      be handled directly by this cache.  In other words, use this
-#      to not query neighbor caches for certain objects.  You may
-#      list this option multiple times.
-#We recommend you to use at least the following line.
-hierarchy_stoplist cgi-bin ?
-
-#  TAG: no_cache
-#      A list of ACL elements which, if matched, cause the request to
-#      not be satisfied from the cache and the reply to not be cached.
-#      In other words, use this to force certain objects to never be cached.
-#
-#      You must use the word 'DENY' to indicate the ACL names which should
-#      NOT be cached.
-#
-#We recommend you to use the following two lines.
-acl QUERY urlpath_regex cgi-bin \?
-no_cache deny QUERY
-
-
-# OPTIONS WHICH AFFECT THE CACHE SIZE
-# -----------------------------------------------------------------------------
-
-#  TAG: cache_mem      (bytes)
-#      NOTE: THIS PARAMETER DOES NOT SPECIFY THE MAXIMUM PROCESS SIZE.
-#      IT ONLY PLACES A LIMIT ON HOW MUCH ADDITIONAL MEMORY SQUID WILL
-#      USE AS A MEMORY CACHE OF OBJECTS. SQUID USES MEMORY FOR OTHER
-#      THINGS AS WELL. SEE THE SQUID FAQ SECTION 8 FOR DETAILS.
-#
-#      'cache_mem' specifies the ideal amount of memory to be used
-#      for:
-#              * In-Transit objects
-#              * Hot Objects
-#              * Negative-Cached objects
-#
-#      Data for these objects are stored in 4 KB blocks.  This
-#      parameter specifies the ideal upper limit on the total size of
-#      4 KB blocks allocated.  In-Transit objects take the highest
-#      priority.
-#
-#      In-transit objects have priority over the others.  When
-#      additional space is needed for incoming data, negative-cached
-#      and hot objects will be released.  In other words, the
-#      negative-cached and hot objects will fill up any unused space
-#      not needed for in-transit objects.
-#
-#      If circumstances require, this limit will be exceeded.
-#      Specifically, if your incoming request rate requires more than
-#      'cache_mem' of memory to hold in-transit objects, Squid will
-#      exceed this limit to satisfy the new requests.  When the load
-#      decreases, blocks will be freed until the high-water mark is
-#      reached.  Thereafter, blocks will be used to store hot
-#      objects.
-#
-#Default:
-# cache_mem 8 MB
-
-#  TAG: cache_swap_low (percent, 0-100)
-#  TAG: cache_swap_high        (percent, 0-100)
-#
-#      The low- and high-water marks for cache object replacement.
-#      Replacement begins when the swap (disk) usage is above the
-#      low-water mark and attempts to maintain utilization near the
-#      low-water mark.  As swap utilization gets close to high-water
-#      mark object eviction becomes more aggressive.  If utilization is
-#      close to the low-water mark less replacement is done each time.
-#      
-#      Defaults are 90% and 95%. If you have a large cache, 5% could be
-#      hundreds of MB. If this is the case you may wish to set these
-#      numbers closer together.
-#
-#Default:
-# cache_swap_low 90
-# cache_swap_high 95
-
-#  TAG: maximum_object_size    (bytes)
-#      Objects larger than this size will NOT be saved on disk.  The
-#      value is specified in kilobytes, and the default is 4MB.  If
-#      you wish to get a high BYTES hit ratio, you should probably
-#      increase this (one 32 MB object hit counts for 3200 10KB
-#      hits).  If you wish to increase speed more than your want to
-#      save bandwidth you should leave this low.
-#
-#      NOTE: if using the LFUDA replacement policy you should increase
-#      this value to maximize the byte hit rate improvement of LFUDA!
-#      See replacement_policy below for a discussion of this policy.
-#
-#Default:
-# maximum_object_size 4096 KB
-
-#  TAG: minimum_object_size    (bytes)
-#      Objects smaller than this size will NOT be saved on disk.  The
-#      value is specified in kilobytes, and the default is 0 KB, which
-#      means there is no minimum.
-#
-#Default:
-# minimum_object_size 0 KB
-
-#  TAG: maximum_object_size_in_memory  (bytes)
-#        Objects greater than this size will not be attempted to kept in
-#        the memory cache. This should be set high enough to keep objects
-#        accessed frequently in memory to improve performance whilst low
-#        enough to keep larger objects from hoarding cache_mem .
-#
-#Default:
-# maximum_object_size_in_memory 8 KB
-
-#  TAG: ipcache_size   (number of entries)
-#  TAG: ipcache_low    (percent)
-#  TAG: ipcache_high   (percent)
-#      The size, low-, and high-water marks for the IP cache.
-#
-#Default:
-# ipcache_size 1024
-# ipcache_low 90
-# ipcache_high 95
-
-#  TAG: fqdncache_size (number of entries)
-#      Maximum number of FQDN cache entries.
-#
-#Default:
-# fqdncache_size 1024
-
-#  TAG: cache_replacement_policy
-#      The cache replacement policy parameter determines which
-#      objects are evicted (replaced) when disk space is needed.
-#
-#          lru       : Squid's original list based LRU policy
-#          heap GDSF : Greedy-Dual Size Frequency
-#          heap LFUDA: Least Frequently Used with Dynamic Aging
-#          heap LRU  : LRU policy implemented using a heap
-#
-#      Applies to any cache_dir lines listed below this.
-#
-#      The LRU policies keeps recently referenced objects.
-#
-#      The heap GDSF policy optimizes object hit rate by keeping smaller
-#      popular objects in cache so it has a better chance of getting a
-#      hit.  It achieves a lower byte hit rate than LFUDA though since
-#      it evicts larger (possibly popular) objects.
-#
-#      The heap LFUDA policy keeps popular objects in cache regardless of
-#      their size and thus optimizes byte hit rate at the expense of
-#      hit rate since one large, popular object will prevent many
-#      smaller, slightly less popular objects from being cached.
-#
-#      Both policies utilize a dynamic aging mechanism that prevents
-#      cache pollution that can otherwise occur with frequency-based
-#      replacement policies.
-#
-#      NOTE: if using the LFUDA replacement policy you should increase
-#      the value of maximum_object_size above its default of 4096 KB to
-#      to maximize the potential byte hit rate improvement of LFUDA.
-#
-#      For more information about the GDSF and LFUDA cache replacement
-#      policies see http://www.hpl.hp.com/techreports/1999/HPL-1999-69.html
-#      and http://fog.hpl.external.hp.com/techreports/98/HPL-98-173.html.
-#
-#Default:
-# cache_replacement_policy lru
-
-#  TAG: memory_replacement_policy
-#      The memory replacement policy parameter determines which
-#      objects are purged from memory when memory space is needed.
-#
-#      See cache_replacement_policy for details.
-#
-#Default:
-# memory_replacement_policy lru
-
-
-# LOGFILE PATHNAMES AND CACHE DIRECTORIES
-# -----------------------------------------------------------------------------
-
-#  TAG: cache_dir
-#      Usage:
-#      
-#      cache_dir Type Directory-Name Fs-specific-data [options]
-#
-#      You can specify multiple cache_dir lines to spread the
-#      cache among different disk partitions.
-#
-#      Type specifies the kind of storage system to use. Only "ufs"
-#      is built by default. To eanble any of the other storage systems
-#      see the --enable-storeio configure option.
-#
-#      'Directory' is a top-level directory where cache swap
-#      files will be stored.  If you want to use an entire disk
-#      for caching, then this can be the mount-point directory.
-#      The directory must exist and be writable by the Squid
-#      process.  Squid will NOT create this directory for you.
-#
-#      The ufs store type:
-#
-#      "ufs" is the old well-known Squid storage format that has always
-#      been there.
-#
-#      cache_dir ufs Directory-Name Mbytes L1 L2 [options]
-#
-#      'Mbytes' is the amount of disk space (MB) to use under this
-#      directory.  The default is 100 MB.  Change this to suit your
-#      configuration.  Do NOT put the size of your disk drive here.
-#      Instead, if you want Squid to use the entire disk drive,
-#      subtract 20% and use that value.
-#
-#      'Level-1' is the number of first-level subdirectories which
-#      will be created under the 'Directory'.  The default is 16.
-#
-#      'Level-2' is the number of second-level subdirectories which
-#      will be created under each first-level directory.  The default
-#      is 256.
-#
-#      The aufs store type:
-#
-#      "aufs" uses the same storage format as "ufs", utilizing
-#      POSIX-threads to avoid blocking the main Squid process on
-#      disk-I/O. This was formerly known in Squid as async-io.
-#
-#      cache_dir aufs Directory-Name Mbytes L1 L2 [options]
-#
-#      see argument descriptions under ufs above
-#
-#      The diskd store type:
-#
-#      "diskd" uses the same storage format as "ufs", utilizing a
-#      separate process to avoid blocking the main Squid process on
-#      disk-I/O.
-#
-#      cache_dir diskd Directory-Name Mbytes L1 L2 [options] [Q1=n] [Q2=n]
-#
-#      see argument descriptions under ufs above
-#
-#      Q1 specifies the number of unacknowledged I/O requests when Squid
-#      stops opening new files. If this many messages are in the queues,
-#      Squid won't open new files. Default is 64
-#
-#      Q2 specifies the number of unacknowledged messages when Squid
-#      starts blocking.  If this many messages are in the queues,
-#      Squid blocks until it recevies some replies. Default is 72
-#
-#      The coss store type:
-#
-#      block-size=n defines the "block size" for COSS cache_dir's.
-#      Squid uses file numbers as block numbers.  Since file numbers
-#      are limited to 24 bits, the block size determines the maximum
-#      size of the COSS partition.  The default is 512 bytes, which
-#      leads to a maximum cache_dir size of 512<<24, or 8 GB.  Note
-#      that you should not change the coss block size after Squid
-#      has written some objects to the cache_dir.
-#
-#      Common options:
-#
-#      read-only, this cache_dir is read only.
-#
-#      max-size=n, refers to the max object size this storedir supports.
-#      It is used to initially choose the storedir to dump the object.
-#      Note: To make optimal use of the max-size limits you should order
-#      the cache_dir lines with the smallest max-size value first and the
-#      ones with no max-size specification last.
-#
-#      Note that for coss, max-size must be less than COSS_MEMBUF_SZ
-#      (hard coded at 1 MB).
-#
-#Default:
-# cache_dir ufs /var/spool/squid 100 16 256
-
-#  TAG: cache_access_log
-#      Logs the client request activity.  Contains an entry for
-#      every HTTP and ICP queries received. To disable, enter "none".
-#
-#Default:
-# cache_access_log /var/log/squid/access.log
-
-#  TAG: cache_log
-#      Cache logging file. This is where general information about
-#      your cache's behavior goes. You can increase the amount of data
-#      logged to this file with the "debug_options" tag below.
-#
-#Default:
-# cache_log /var/log/squid/cache.log
-
-#  TAG: cache_store_log
-#      Logs the activities of the storage manager.  Shows which
-#      objects are ejected from the cache, and which objects are
-#      saved and for how long.  To disable, enter "none". There are
-#      not really utilities to analyze this data, so you can safely
-#      disable it.
-#
-#Default:
-# cache_store_log /var/log/squid/store.log
-
-#  TAG: cache_swap_log
-#      Location for the cache "swap.log."  This log file holds the
-#      metadata of objects saved on disk.  It is used to rebuild the
-#      cache during startup.  Normally this file resides in each
-#      'cache_dir' directory, but you may specify an alternate
-#      pathname here.  Note you must give a full filename, not just
-#      a directory. Since this is the index for the whole object
-#      list you CANNOT periodically rotate it!
-#
-#      If %s can be used in the file name then it will be replaced with a
-#      a representation of the cache_dir name where each / is replaced
-#      with '.'. This is needed to allow adding/removing cache_dir
-#      lines when cache_swap_log is being used.
-#      
-#      If have more than one 'cache_dir', and %s is not used in the name
-#      then these swap logs will have names such as:
-#
-#              cache_swap_log.00
-#              cache_swap_log.01
-#              cache_swap_log.02
-#
-#      The numbered extension (which is added automatically)
-#      corresponds to the order of the 'cache_dir' lines in this
-#      configuration file.  If you change the order of the 'cache_dir'
-#      lines in this file, then these log files will NOT correspond to
-#      the correct 'cache_dir' entry (unless you manually rename
-#      them).  We recommend that you do NOT use this option.  It is
-#      better to keep these log files in each 'cache_dir' directory.
-#
-#Default:
-# none
-
-#  TAG: emulate_httpd_log      on|off
-#      The Cache can emulate the log file format which many 'httpd'
-#      programs use.  To disable/enable this emulation, set
-#      emulate_httpd_log to 'off' or 'on'.  The default
-#      is to use the native log format since it includes useful
-#      information that Squid-specific log analyzers use.
-#
-#Default:
-# emulate_httpd_log off
-
-#  TAG: log_ip_on_direct       on|off
-#      Log the destination IP address in the hierarchy log tag when going
-#      direct. Earlier Squid versions logged the hostname here. If you
-#      prefer the old way set this to off.
-#
-#Default:
-# log_ip_on_direct on
-
-#  TAG: mime_table
-#      Pathname to Squid's MIME table. You shouldn't need to change
-#      this, but the default file contains examples and formatting
-#      information if you do.
-#
-#Default:
-# mime_table /etc/squid/mime.conf
-
-#  TAG: log_mime_hdrs  on|off
-#      The Cache can record both the request and the response MIME
-#      headers for each HTTP transaction.  The headers are encoded
-#      safely and will appear as two bracketed fields at the end of
-#      the access log (for either the native or httpd-emulated log
-#      formats).  To enable this logging set log_mime_hdrs to 'on'.
-#
-#Default:
-# log_mime_hdrs off
-
-#  TAG: useragent_log
-#      Squid will write the User-Agent field from HTTP requests
-#      to the filename specified here.  By default useragent_log
-#      is disabled.
-#
-#Default:
-# none
-
-#  TAG: referer_log
-# Note: This option is only available if Squid is rebuilt with the
-#       --enable-referer-log option
-#
-#      Squid will write the Referer field from HTTP requests to the
-#      filename specified here.  By default referer_log is disabled.
-#
-#Default:
-# none
-
-#  TAG: pid_filename
-#      A filename to write the process-id to.  To disable, enter "none".
-#
-#Default:
-# pid_filename /var/run/squid.pid
-
-#  TAG: debug_options
-#      Logging options are set as section,level where each source file
-#      is assigned a unique section.  Lower levels result in less
-#      output,  Full debugging (level 9) can result in a very large
-#      log file, so be careful.  The magic word "ALL" sets debugging
-#      levels for all sections.  We recommend normally running with
-#      "ALL,1".
-#
-#Default:
-# debug_options ALL,1
-
-#  TAG: log_fqdn       on|off
-#      Turn this on if you wish to log fully qualified domain names
-#      in the access.log. To do this Squid does a DNS lookup of all
-#      IP's connecting to it. This can (in some situations) increase
-#      latency, which makes your cache seem slower for interactive
-#      browsing.
-#
-#Default:
-# log_fqdn off
-
-#  TAG: client_netmask
-#      A netmask for client addresses in logfiles and cachemgr output.
-#      Change this to protect the privacy of your cache clients.
-#      A netmask of 255.255.255.0 will log all IP's in that range with
-#      the last digit set to '0'.
-#
-#Default:
-# client_netmask 255.255.255.255
-
-
-# OPTIONS FOR EXTERNAL SUPPORT PROGRAMS
-# -----------------------------------------------------------------------------
-
-#  TAG: ftp_user
-#      If you want the anonymous login password to be more informative
-#      (and enable the use of picky ftp servers), set this to something
-#      reasonable for your domain, like wwwuser@somewhere.net
-#
-#      The reason why this is domainless by default is that the
-#      request can be made on the behalf of a user in any domain,
-#      depending on how the cache is used.
-#      Some ftp server also validate that the email address is valid
-#      (for example perl.com).
-#
-#Default:
-# ftp_user Squid@
-
-#  TAG: ftp_list_width
-#      Sets the width of ftp listings. This should be set to fit in
-#      the width of a standard browser. Setting this too small
-#      can cut off long filenames when browsing ftp sites.
-#
-#Default:
-# ftp_list_width 32
-
-#  TAG: ftp_passive
-#      If your firewall does not allow Squid to use passive
-#      connections, then turn off this option.
-#
-#Default:
-# ftp_passive on
-
-#  TAG: ftp_sanitycheck
-#      For security and data integrity reasons Squid by default performs
-#      sanity checks of the addresses of FTP data connections ensure the
-#      data connection is to the requested server. If you need to allow
-#      FTP connections to servers using another IP address for the data
-#      connection then turn this off.
-#
-#Default:
-# ftp_sanitycheck on
-
-#  TAG: ftp_telnet_protocol
-#      The FTP protocol is officially defined to use the telnet protocol
-#      as transport channel for the control connection. However, many
-#      implemenations are broken and does not respect this aspect of
-#      the FTP protocol.
-#
-#      If you have trouble accessing files with ASCII code 255 in the
-#      path or similar problems involving this ASCII code then you can
-#      try setting this directive to off. If that helps report to the
-#      operator of the FTP server in question that their FTP server
-#      is broken and does not follow the FTP standard.
-#
-#Default:
-# ftp_telnet_protocol on
-
-#  TAG: cache_dns_program
-# Note: This option is only available if Squid is rebuilt with the
-#       --disable-internal-dns option
-#
-#      Specify the location of the executable for dnslookup process.
-#
-#Default:
-# cache_dns_program /usr/lib/squid/dnsserver
-
-#  TAG: dns_children
-# Note: This option is only available if Squid is rebuilt with the
-#       --disable-internal-dns option
-#
-#      The number of processes spawn to service DNS name lookups.
-#      For heavily loaded caches on large servers, you should
-#      probably increase this value to at least 10.  The maximum
-#      is 32.  The default is 5.
-#
-#      You must have at least one dnsserver process.
-#
-#Default:
-# dns_children 5
-
-#  TAG: dns_retransmit_interval
-#      Initial retransmit interval for DNS queries. The interval is
-#      doubled each time all configured DNS servers have been tried.
-#
-#
-#Default:
-# dns_retransmit_interval 5 seconds
-
-#  TAG: dns_timeout
-#      DNS Query timeout. If no response is received to a DNS query
-#      within this time then all DNS servers for the queried domain
-#      is assumed to be unavailable.
-#
-#Default:
-# dns_timeout 2 minutes
-
-#  TAG: dns_defnames   on|off
-# Note: This option is only available if Squid is rebuilt with the
-#       --disable-internal-dns option
-#
-#      Normally the 'dnsserver' disables the RES_DEFNAMES resolver
-#      option (see res_init(3)).  This prevents caches in a hierarchy
-#      from interpreting single-component hostnames locally.  To allow
-#      dnsserver to handle single-component names, enable this
-#      option.
-#
-#Default:
-# dns_defnames off
-
-#  TAG: dns_nameservers
-#      Use this if you want to specify a list of DNS name servers
-#      (IP addresses) to use instead of those given in your
-#      /etc/resolv.conf file.
-#      On Windows platforms, if no value is specified here or in
-#      the /etc/resolv.conf file, the list of DNS name servers are
-#      taken from the Windows registry, both static and dynamic DHCP
-#      configurations are supported.
-#
-#      Example: dns_nameservers 10.0.0.1 192.172.0.4
-#
-#Default:
-# none
-
-#  TAG: hosts_file
-#      Location of the host-local IP name-address associations
-#      database.  Most Operating Systems have such a file: under
-#      Un*X it's by default in /etc/hosts MS-Windows NT/2000 places
-#      that in %SystemRoot%(by default
-#      c:\winnt)\system32\drivers\etc\hosts, while Windows 9x/ME
-#      places that in %windir%(usually c:\windows)\hosts
-#
-#      The file contains newline-separated definitions, in the
-#      form ip_address_in_dotted_form name [name ...] names are
-#      whitespace-separated.  lines beginnng with an hash (#)
-#      character are comments.
-#
-#      The file is checked at startup and upon configuration.  If
-#      set to 'none', it won't be checked.  If append_domain is
-#      used, that domain will be added to domain-local (i.e. not
-#      containing any dot character) host definitions.
-#
-#Default:
-# hosts_file /etc/hosts
-
-#  TAG: diskd_program
-#      Specify the location of the diskd executable.
-#      Note that this is only useful if you have compiled in
-#      diskd as one of the store io modules.
-#
-#Default:
-# diskd_program /usr/lib/squid/diskd
-
-#  TAG: unlinkd_program
-#      Specify the location of the executable for file deletion process.
-#
-#Default:
-# unlinkd_program /usr/lib/squid/unlinkd
-
-#  TAG: pinger_program
-#      Specify the location of the executable for the pinger process.
-#
-#Default:
-# pinger_program /usr/lib/squid/pinger
-
-#  TAG: redirect_program
-#      Specify the location of the executable for the URL redirector.
-#      Since they can perform almost any function there isn't one included.
-#      See the FAQ (section 15) for information on how to write one.
-#      By default, a redirector is not used.
-#
-#Default:
-# none
-
-#  TAG: redirect_children
-#      The number of redirector processes to spawn. If you start
-#      too few Squid will have to wait for them to process a backlog of
-#      URLs, slowing it down. If you start too many they will use RAM
-#      and other system resources.
-#
-#Default:
-# redirect_children 5
-
-#  TAG: redirect_rewrites_host_header
-#      By default Squid rewrites any Host: header in redirected
-#      requests.  If you are running an accelerator then this may
-#      not be a wanted effect of a redirector.
-#
-#Default:
-# redirect_rewrites_host_header on
-
-#  TAG: redirector_access
-#      If defined, this access list specifies which requests are
-#      sent to the redirector processes.  By default all requests
-#      are sent.
-#
-#Default:
-# none
-
-#  TAG: auth_param
-#      This is used to define parameters for the various authentication
-#      schemes supported by Squid.
-#
-#      format: auth_param scheme parameter [setting]
-#      
-#      The order that authentication schemes are presented to the client is
-#      dependant on the order the scheme first appears in config file. IE
-#      has a bug (it's not rfc 2617 compliant) in that it will use the basic
-#      scheme if basic is the first entry presented, even if more secure
-#      schemes are presented. For now use the order in the recommended
-#      settings section below. If other browsers have difficulties (don't
-#      recognise the schemes offered even if you are using basic) then either
-#      put basic first, or disable the other schemes (by commenting out their
-#      program entry).
-#
-#      Once an authentication scheme is fully configured, it can only be
-#      shutdown by shutting squid down and restarting. Changes can be made on
-#      the fly and activated with a reconfigure. I.E. You can change to a
-#      different helper, but not unconfigure the helper completely.
-#
-#      Please note that while this directive defines how Squid processes
-#      authentication it does not automatically activate authentication.
-#      To use authenticaiton you must in addition make use of acls based
-#      on login name in http_access (proxy_auth, proxy_auth_regex or
-#      external with %LOGIN used in the format tag). The browser will be
-#      challenged for authentication on the first such acl encountered
-#      in http_access processing and will also be rechallenged for new
-#      login credentials if the request is being denied by a proxy_auth
-#      type acl.
-#
-#      === Parameters for the basic scheme follow. ===
-#      
-#      "program" cmdline
-#      Specify the command for the external authenticator.  Such a program
-#      reads a line containing "username password" and replies "OK" or
-#      "ERR" in an endless loop.
-#
-#      By default, the basic authentication sheme is not used unless a
-#      program is specified.
-#
-#      If you want to use the traditional proxy authentication, jump over to
-#      the helpers/basic_auth/NCSA directory and type:
-#              % make
-#              % make install
-#
-#      Then, set this line to something like
-#
-#      auth_param basic program /usr/libexec/ncsa_auth /usr/etc/passwd
-#      
-#      "children" numberofchildren
-#      The number of authenticator processes to spawn.
-#      If you start too few Squid will have to wait for them to process a
-#      backlog of usercode/password verifications, slowing it down. When
-#      password verifications are done via a (slow) network you are likely to
-#      need lots of authenticator processes.
-#      auth_param basic children 5
-#
-#      "realm" realmstring
-#      Specifies the realm name which is to be reported to the client for
-#      the basic proxy authentication scheme (part of the text the user
-#      will see when prompted their username and password).
-#      auth_param basic realm Squid proxy-caching web server
-#
-#      "credentialsttl" timetolive
-#      Specifies how long squid assumes an externally validated
-#      username:password pair is valid for - in other words how often the
-#      helper program is called for that user. Set this low to force
-#      revalidation with short lived passwords.  Note that setting this high
-#      does not impact your susceptability to replay attacks unless you are
-#      using an one-time password system (such as SecureID). If you are using
-#      such a system, you will be vulnerable to replay attacks unless you
-#      also use the max_user_ip ACL in an http_access rule.
-#      auth_param basic credentialsttl 2 hours
-#
-#      === Parameters for the digest scheme follow ===
-#
-#      "program" cmdline
-#      Specify the command for the external authenticator.  Such a program
-#      reads a line containing "username":"realm" and replies with the
-#      appropriate H(A1) value base64 encoded.  See rfc 2616 for the
-#      definition of H(A1).
-#
-#      By default, the digest authentication scheme is not used unless a
-#      program is specified.
-#
-#      If you want to use a digest authenticator, jump over to the
-#      helpers/digest_auth/ directory and choose the authenticator to use.
-#      It it's directory type
-#              % make
-#              % make install
-#
-#      Then, set this line to something like
-#
-#      auth_param digest program /usr/libexec/digest_auth_pw /usr/etc/digpass
-#
-#
-#      "children" numberofchildren
-#      The number of authenticator processes to spawn (no default). If you
-#      start too few Squid will have to wait for them to process a backlog of
-#      H(A1) calculations, slowing it down.  When the H(A1) calculations are
-#      done via a (slow) network you are likely to need lots of authenticator
-#      processes.
-#      auth_param digest children 5
-#
-#      "realm" realmstring
-#      Specifies the realm name which is to be reported to the client for the
-#      digest proxy authentication scheme (part of the text the user will see
-#      when prompted their username and password).
-#      auth_param digest realm Squid proxy-caching web server
-#
-#      "nonce_garbage_interval" timeinterval
-#      Specifies the interval that nonces that have been issued to clients are
-#      checked for validity.
-#      auth_param digest nonce_garbage_interval 5 minutes
-#
-#      "nonce_max_duration" timeinterval
-#      Specifies the maximum length of time a given nonce will be valid for.
-#      auth_param digest nonce_max_duration 30 minutes
-#
-#      "nonce_max_count" number
-#      Specifies the maximum number of times a given nonce can be used.
-#      auth_param digest nonce_max_count 50
-#
-#      "nonce_strictness" on|off
-#      Determines if squid requires strict increment-by-1 behaviour for nonce
-#      counts, or just incrementing (off - for use when useragents generate
-#      nonce counts that occasionally miss 1 (ie, 1,2,4,6)).
-#      auth_param digest nonce_strictness off
-#
-#      "check_nonce_count" on|off
-#      This directive if set to off can disable the nonce count check
-#      completely to work around buggy digest qop implementations in certain
-#      mainstream browser versions. Default on to check the nonce count to
-#      protect from authentication replay attacks.
-#      auth_param digest check_nonce_count on
-#
-#      "post_workaround" on|off
-#      This is a workaround to certain buggy browsers who sends an incorrect
-#      request digest in POST requests when reusing the same nonce as aquired
-#              earlier in response to a GET request.
-#      auth_param digest post_workaround off
-#
-#      === NTLM scheme options follow ===
-#
-#      "program" cmdline
-#      Specify the command for the external ntlm authenticator. Such a
-#      program participates in the NTLMSSP exchanges between Squid and the
-#      client and reads commands according to the Squid ntlmssp helper
-#      protocol. See helpers/ntlm_auth/ for details. Recommended ntlm
-#      authenticator is ntlm_auth from Samba-3.X, but a number of other
-#      ntlm authenticators is available.
-#
-#      By default, the ntlm authentication scheme is not used unless a
-#      program is specified.
-#
-#      auth_param ntlm program /path/to/samba/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp
-#
-#      "children" numberofchildren
-#      The number of authenticator processes to spawn (no default). If you
-#      start too few Squid will have to wait for them to process a backlog
-#      of credential verifications, slowing it down. When crendential
-#      verifications are done via a (slow) network you are likely to need
-#      lots of authenticator processes.
-#      auth_param ntlm children 5
-#
-#      "max_challenge_reuses" number
-#      The maximum number of times a challenge given by a ntlm authentication
-#      helper can be reused. Increasing this number increases your exposure
-#      to replay attacks on your network. 0 (the default) means use the
-#      challenge is used only once. See also the max_ntlm_challenge_lifetime
-#      directive if enabling challenge reuses.
-#      auth_param ntlm max_challenge_reuses 0
-#
-#      "max_challenge_lifetime" timespan
-#      The maximum time period that a ntlm challenge is reused over. The
-#      actual period will be the minimum of this time AND the number of
-#      reused challenges.
-#      auth_param ntlm max_challenge_lifetime 2 minutes
-#
-#      "use_ntlm_negotiate" on|off
-#      Enables support for NTLM NEGOTIATE packet exchanges with the helper.
-#      The configured ntlm authenticator must be able to handle NTLM
-#      NEGOTIATE packet. See the authenticator programs documentation if
-#      unsure. ntlm_auth from Samba-3.0.2 or later supports the use of this
-#      option.
-#      The NEGOTIATE packet is required to support NTLMv2 and a
-#      number of other negotiable NTLMSSP options, and also makes it
-#      more likely the negotiation is successful. Enabling this parameter
-#      will also solve problems encountered when NT domain policies
-#      restrict users to access only certain workstations. When this is off,
-#      all users must be allowed to log on the proxy servers too, or they'll
-#      get "invalid workstation" errors - and access denied - when trying to
-#      use Squid's services.
-#      Use of ntlm NEGOTIATE is incompatible with challenge reuse, so
-#      enabling this parameter will OVERRIDE the max_challenge_reuses and
-#      max_challenge_lifetime parameters and set them to 0.
-#      auth_param ntlm use_ntlm_negotiate off
-#
-#Recommended minimum configuration:
-#auth_param digest program <uncomment and complete this line>
-#auth_param digest children 5
-#auth_param digest realm Squid proxy-caching web server
-#auth_param digest nonce_garbage_interval 5 minutes
-#auth_param digest nonce_max_duration 30 minutes
-#auth_param digest nonce_max_count 50
-#auth_param ntlm program /usr/lib/squid/ntlm_auth IPH\\PDC
-#auth_param ntlm children 5
-#auth_param ntlm max_challenge_reuses 0
-#auth_param ntlm max_challenge_lifetime 2 minutes
-#auth_param ntlm use_ntlm_negotiate off
-auth_param basic program /usr/lib/squid/squid_ldap_auth -b ou=People,dc=example,dc=com -f (&(uid=%s)(objectClass=gosaProxyAccount))
-auth_param basic children 5
-auth_param basic realm Squid proxy-caching web server
-auth_param basic credentialsttl 2 hours
-
-#  TAG: authenticate_cache_garbage_interval
-#      The time period between garbage collection across the username cache.
-#      This is a tradeoff between memory utilisation (long intervals - say
-#      2 days) and CPU (short intervals - say 1 minute). Only change if you
-#      have good reason to.
-#
-#Default:
-# authenticate_cache_garbage_interval 1 hour
-
-#  TAG: authenticate_ttl
-#      The time a user & their credentials stay in the logged in user cache
-#      since their last request. When the garbage interval passes, all user
-#      credentials that have passed their TTL are removed from memory.
-#
-#Default:
-# authenticate_ttl 1 hour
-
-#  TAG: authenticate_ip_ttl
-#      If you use proxy authentication and the 'max_user_ip' ACL, this
-#      directive controls how long Squid remembers the IP addresses
-#      associated with each user.  Use a small value (e.g., 60 seconds) if
-#      your users might change addresses quickly, as is the case with
-#      dialups. You might be safe using a larger value (e.g., 2 hours) in a
-#      corporate LAN environment with relatively static address assignments.
-#
-#Default:
-# authenticate_ip_ttl 0 seconds
-
-#  TAG: external_acl_type
-#      This option defines external acl classes using a helper program to
-#      look up the status
-#      
-#        external_acl_type name [options] FORMAT.. /path/to/helper [helper arguments..]
-#      
-#      Options:
-#
-#        ttl=n         TTL in seconds for cached results (defaults to 3600
-#                      for 1 hour)
-#        negative_ttl=n
-#                      TTL for cached negative lookups (default same
-#                      as ttl)
-#        children=n    Concurrency level / number of processes spawn
-#                      to service external acl lookups of this type.
-#                      Note: see compatibility note below
-#        cache=n       result cache size, 0 is unbounded (default)
-#      
-#      FORMAT specifications
-#
-#        %LOGIN        Authenticated user login name
-#        %IDENT        Ident user name
-#        %SRC          Client IP
-#        %DST          Requested host
-#        %PROTO        Requested protocol
-#        %PORT         Requested port
-#        %METHOD       Request method
-#        %{Header}     HTTP request header
-#        %{Hdr:member} HTTP request header list member
-#        %{Hdr:;member}
-#                      HTTP request header list member using ; as
-#                      list separator. ; can be any non-alphanumeric
-#                      character.
-#
-#      In addition, any string specified in the referencing acl will
-#      also be included in the helper request line, after the specified
-#      formats (see the "acl external" directive)
-#
-#      The helper receives lines per the above format specification,
-#      and returns lines starting with OK or ERR indicating the validity
-#      of the request and optionally followed by additional keywords with
-#      more details.
-#
-#      General result syntax:
-#      
-#        OK/ERR keyword=value ...
-#
-#      Defined keywords:
-#
-#        user=         The users name (login)
-#        error=        Error description (only defined for ERR results)
-#
-#      Keyword values need to be enclosed in quotes if they may contain
-#      whitespace, or the whitespace escaped using \. Any quotes or \
-#      characters within the keyword value must be \ escaped.
-#
-#      Compatibility Note: The children= option was named concurrency= in
-#      Squid-2.5.STABLE3 and earlier and such syntax is still accepted to
-#      keep compatibility within the Squid-2.5 release. However, the meaning
-#      of concurrency= option has changed in Squid-3 and the old syntax of
-#      the directive is therefore depreated from Squid-2.5.STABLE4 and later.
-#      If you want to be able to easily downgrade to earlier Squid-2.5
-#      releases then you may want to continue using the old name, if not
-#      please use the new name.
-#
-#Default:
-# none
-
-
-# OPTIONS FOR TUNING THE CACHE
-# -----------------------------------------------------------------------------
-
-#  TAG: wais_relay_host
-#  TAG: wais_relay_port
-#      Relay WAIS request to host (1st arg) at port (2 arg).
-#
-#Default:
-# wais_relay_port 0
-
-#  TAG: request_header_max_size        (KB)
-#      This specifies the maximum size for HTTP headers in a request.
-#      Request headers are usually relatively small (about 512 bytes).
-#      Placing a limit on the request header size will catch certain
-#      bugs (for example with persistent connections) and possibly
-#      buffer-overflow or denial-of-service attacks.
-#
-#Default:
-# request_header_max_size 10 KB
-
-#  TAG: request_body_max_size  (KB)
-#      This specifies the maximum size for an HTTP request body.
-#      In other words, the maximum size of a PUT/POST request.
-#      A user who attempts to send a request with a body larger
-#      than this limit receives an "Invalid Request" error message.
-#      If you set this parameter to a zero (the default), there will
-#      be no limit imposed.
-#
-#Default:
-# request_body_max_size 0 KB
-
-#  TAG: refresh_pattern
-#      usage: refresh_pattern [-i] regex min percent max [options]
-#
-#      By default, regular expressions are CASE-SENSITIVE.  To make
-#      them case-insensitive, use the -i option.
-#
-#      'Min' is the time (in minutes) an object without an explicit
-#      expiry time should be considered fresh. The recommended
-#      value is 0, any higher values may cause dynamic applications
-#      to be erroneously cached unless the application designer
-#      has taken the appropriate actions.
-#
-#      'Percent' is a percentage of the objects age (time since last
-#      modification age) an object without explicit expiry time
-#      will be considered fresh.
-#
-#      'Max' is an upper limit on how long objects without an explicit
-#      expiry time will be considered fresh.
-#
-#      options: override-expire
-#               override-lastmod
-#               reload-into-ims
-#               ignore-reload
-#
-#              override-expire enforces min age even if the server
-#              sent a Expires: header. Doing this VIOLATES the HTTP
-#              standard.  Enabling this feature could make you liable
-#              for problems which it causes.
-#
-#              override-lastmod enforces min age even on objects
-#              that was modified recently.
-#
-#              reload-into-ims changes client no-cache or ``reload''
-#              to If-Modified-Since requests. Doing this VIOLATES the
-#              HTTP standard. Enabling this feature could make you
-#              liable for problems which it causes.
-#
-#              ignore-reload ignores a client no-cache or ``reload''
-#              header. Doing this VIOLATES the HTTP standard. Enabling
-#              this feature could make you liable for problems which
-#              it causes.
-#              
-#      Basically a cached object is:
-#
-#              FRESH if expires < now, else STALE
-#              STALE if age > max
-#              FRESH if lm-factor < percent, else STALE
-#              FRESH if age < min
-#              else STALE
-#
-#      The refresh_pattern lines are checked in the order listed here.
-#      The first entry which matches is used.  If none of the entries
-#      match, then the default will be used.
-#
-#      Note, you must uncomment all the default lines if you want
-#      to change one. The default setting is only active if none is
-#      used.
-#
-#Suggested default:
-refresh_pattern ^ftp:          1440    20%     10080
-refresh_pattern ^gopher:       1440    0%      1440
-refresh_pattern .              0       20%     4320
-
-#  TAG: quick_abort_min        (KB)
-#  TAG: quick_abort_max        (KB)
-#  TAG: quick_abort_pct        (percent)
-#      The cache by default continues downloading aborted requests
-#      which are almost completed (less than 16 KB remaining). This
-#      may be undesirable on slow (e.g. SLIP) links and/or very busy
-#      caches.  Impatient users may tie up file descriptors and
-#      bandwidth by repeatedly requesting and immediately aborting
-#      downloads.
-#
-#      When the user aborts a request, Squid will check the
-#      quick_abort values to the amount of data transfered until
-#      then.
-#
-#      If the transfer has less than 'quick_abort_min' KB remaining,
-#      it will finish the retrieval.
-#
-#      If the transfer has more than 'quick_abort_max' KB remaining,
-#      it will abort the retrieval.
-#
-#      If more than 'quick_abort_pct' of the transfer has completed,
-#      it will finish the retrieval.
-#
-#      If you do not want any retrieval to continue after the client
-#      has aborted, set both 'quick_abort_min' and 'quick_abort_max'
-#      to '0 KB'.
-#
-#      If you want retrievals to always continue if they are being
-#      cached then set 'quick_abort_min' to '-1 KB'.
-#
-#Default:
-# quick_abort_min 16 KB
-# quick_abort_max 16 KB
-# quick_abort_pct 95
-
-#  TAG: negative_ttl   time-units
-#      Time-to-Live (TTL) for failed requests.  Certain types of
-#      failures (such as "connection refused" and "404 Not Found") are
-#      negatively-cached for a configurable amount of time.  The
-#      default is 5 minutes.  Note that this is different from
-#      negative caching of DNS lookups.
-#
-#Default:
-# negative_ttl 5 minutes
-
-#  TAG: positive_dns_ttl       time-units
-#      Upper limit on how long Squid will cache positive DNS responses.
-#      Default is 6 hours (360 minutes). This directive must be set
-#      larger than negative_dns_ttl.
-#
-#Default:
-# positive_dns_ttl 6 hours
-
-#  TAG: negative_dns_ttl       time-units
-#      Time-to-Live (TTL) for negative caching of failed DNS lookups.
-#      This also makes sets the lower cache limit on positive lookups.
-#      Minimum value is 1 second, and it is not recommendable to go
-#      much below 10 seconds.
-#
-#Default:
-# negative_dns_ttl 1 minute
-
-#  TAG: range_offset_limit     (bytes)
-#      Sets a upper limit on how far into the the file a Range request
-#      may be to cause Squid to prefetch the whole file. If beyond this
-#      limit then Squid forwards the Range request as it is and the result
-#      is NOT cached.
-#
-#      This is to stop a far ahead range request (lets say start at 17MB)
-#      from making Squid fetch the whole object up to that point before
-#      sending anything to the client.
-#
-#      A value of -1 causes Squid to always fetch the object from the
-#      beginning so that it may cache the result. (2.0 style)
-#
-#      A value of 0 causes Squid to never fetch more than the
-#      client requested. (default)
-#
-#Default:
-# range_offset_limit 0 KB
-
-
-# TIMEOUTS
-# -----------------------------------------------------------------------------
-
-#  TAG: forward_timeout        time-units
-#      This parameter specifies how long Squid should at most attempt in
-#      finding a forwarding path for the request before giving up.
-#
-#Default:
-# forward_timeout 4 minutes
-
-#  TAG: connect_timeout        time-units
-#      This parameter specifies how long to wait for the TCP connect to
-#      the requested server or peer to complete before Squid should
-#      attempt to find another path where to forward the request.
-#
-#Default:
-# connect_timeout 1 minute
-
-#  TAG: peer_connect_timeout   time-units
-#      This parameter specifies how long to wait for a pending TCP
-#      connection to a peer cache.  The default is 30 seconds.   You
-#      may also set different timeout values for individual neighbors
-#      with the 'connect-timeout' option on a 'cache_peer' line.
-#
-#Default:
-# peer_connect_timeout 30 seconds
-
-#  TAG: read_timeout   time-units
-#      The read_timeout is applied on server-side connections.  After
-#      each successful read(), the timeout will be extended by this
-#      amount.  If no data is read again after this amount of time,
-#      the request is aborted and logged with ERR_READ_TIMEOUT.  The
-#      default is 15 minutes.
-#
-#Default:
-# read_timeout 15 minutes
-
-#  TAG: request_timeout
-#      How long to wait for an HTTP request after initial
-#      connection establishment.
-#
-#Default:
-# request_timeout 5 minutes
-
-#  TAG: persistent_request_timeout
-#      How long to wait for the next HTTP request on a persistent
-#      connection after the previous request completes.
-#
-#Default:
-# persistent_request_timeout 1 minute
-
-#  TAG: client_lifetime        time-units
-#      The maximum amount of time that a client (browser) is allowed to
-#      remain connected to the cache process.  This protects the Cache
-#      from having a lot of sockets (and hence file descriptors) tied up
-#      in a CLOSE_WAIT state from remote clients that go away without
-#      properly shutting down (either because of a network failure or
-#      because of a poor client implementation).  The default is one
-#      day, 1440 minutes.
-#
-#      NOTE:  The default value is intended to be much larger than any
-#      client would ever need to be connected to your cache.  You
-#      should probably change client_lifetime only as a last resort.
-#      If you seem to have many client connections tying up
-#      filedescriptors, we recommend first tuning the read_timeout,
-#      request_timeout, persistent_request_timeout and quick_abort values.
-#
-#Default:
-# client_lifetime 1 day
-
-#  TAG: half_closed_clients
-#      Some clients may shutdown the sending side of their TCP
-#      connections, while leaving their receiving sides open.  Sometimes,
-#      Squid can not tell the difference between a half-closed and a
-#      fully-closed TCP connection.  By default, half-closed client
-#      connections are kept open until a read(2) or write(2) on the
-#      socket returns an error.  Change this option to 'off' and Squid
-#      will immediately close client connections when read(2) returns
-#      "no more data to read."
-#
-#Default:
-# half_closed_clients on
-
-#  TAG: pconn_timeout
-#      Timeout for idle persistent connections to servers and other
-#      proxies.
-#
-#Default:
-# pconn_timeout 120 seconds
-
-#  TAG: ident_timeout
-#      Maximum time to wait for IDENT lookups to complete.
-#      
-#      If this is too high, and you enabled IDENT lookups from untrusted
-#      users, then you might be susceptible to denial-of-service by having
-#      many ident requests going at once.
-#
-#Default:
-# ident_timeout 10 seconds
-
-#  TAG: shutdown_lifetime      time-units
-#      When SIGTERM or SIGHUP is received, the cache is put into
-#      "shutdown pending" mode until all active sockets are closed.
-#      This value is the lifetime to set for all open descriptors
-#      during shutdown mode.  Any active clients after this many
-#      seconds will receive a 'timeout' message.
-#
-#Default:
-# shutdown_lifetime 30 seconds
-
-
-# ACCESS CONTROLS
-# -----------------------------------------------------------------------------
-
-#  TAG: acl
-#      Defining an Access List
-#
-#      acl aclname acltype string1 ...
-#      acl aclname acltype "file" ...
-#
-#      when using "file", the file should contain one item per line
-#
-#      acltype is one of the types described below
-#
-#      By default, regular expressions are CASE-SENSITIVE.  To make
-#      them case-insensitive, use the -i option.
-#
-#      acl aclname src      ip-address/netmask ... (clients IP address)
-#      acl aclname src      addr1-addr2/netmask ... (range of addresses)
-#      acl aclname dst      ip-address/netmask ... (URL host's IP address)
-#      acl aclname myip     ip-address/netmask ... (local socket IP address)
-#
-#      acl aclname srcdomain   .foo.com ...    # reverse lookup, client IP
-#      acl aclname dstdomain   .foo.com ...    # Destination server from URL
-#      acl aclname srcdom_regex [-i] xxx ...   # regex matching client name
-#      acl aclname dstdom_regex [-i] xxx ...   # regex matching server
-#        # For dstdomain and dstdom_regex  a reverse lookup is tried if a IP
-#        # based URL is used. The name "none" is used if the reverse lookup
-#        # fails.
-#
-#      acl aclname time     [day-abbrevs]  [h1:m1-h2:m2]
-#          day-abbrevs:
-#              S - Sunday
-#              M - Monday
-#              T - Tuesday
-#              W - Wednesday
-#              H - Thursday
-#              F - Friday
-#              A - Saturday
-#          h1:m1 must be less than h2:m2
-#      acl aclname url_regex [-i] ^http:// ... # regex matching on whole URL
-#      acl aclname urlpath_regex [-i] \.gif$ ...       # regex matching on URL path
-#      acl aclname urllogin [-i] [^a-zA-Z0-9] ...      # regex matching on URL login field
-#      acl aclname port     80 70 21 ...
-#      acl aclname port     0-1024 ...         # ranges allowed
-#      acl aclname myport   3128 ...           # (local socket TCP port)
-#      acl aclname proto    HTTP FTP ...
-#      acl aclname method   GET POST ...
-#      acl aclname browser  [-i] regexp ...
-#        # pattern match on User-Agent header
-#        acl aclname referer_regex  [-i] regexp ...
-#          # pattern match on Referer header
-#          # Referer is highly unreliable, so use with care
-#      acl aclname ident    username ...
-#      acl aclname ident_regex [-i] pattern ...
-#        # string match on ident output.
-#        # use REQUIRED to accept any non-null ident.
-#      acl aclname src_as   number ...
-#      acl aclname dst_as   number ...
-#        # Except for access control, AS numbers can be used for
-#        # routing of requests to specific caches. Here's an
-#        # example for routing all requests for AS#1241 and only
-#        # those to mycache.mydomain.net:
-#        # acl asexample dst_as 1241
-#        # cache_peer_access mycache.mydomain.net allow asexample
-#        # cache_peer_access mycache_mydomain.net deny all
-#
-#      acl aclname proxy_auth username ...
-#      acl aclname proxy_auth_regex [-i] pattern ...
-#        # list of valid usernames
-#        # use REQUIRED to accept any valid username.
-#        #
-#        # NOTE: when a Proxy-Authentication header is sent but it is not
-#        # needed during ACL checking the username is NOT logged
-#        # in access.log.
-#        #
-#        # NOTE: proxy_auth requires a EXTERNAL authentication program
-#        # to check username/password combinations (see
-#        # auth_param directive).
-#        #
-#        # WARNING: proxy_auth can't be used in a transparent proxy. It
-#        # collides with any authentication done by origin servers. It may
-#        # seem like it works at first, but it doesn't.
-#
-#      acl aclname snmp_community string ...
-#        # A community string to limit access to your SNMP Agent
-#        # Example:
-#        #
-#        #     acl snmppublic snmp_community public
-#
-#      acl aclname maxconn number
-#        # This will be matched when the client's IP address has
-#        # more than <number> HTTP connections established.
-#
-#      acl aclname max_user_ip [-s] number
-#        # This will be matched when the user attempts to log in from more
-#        # than <number> different ip addresses. The authenticate_ip_ttl
-#        # parameter controls the timeout on the ip entries.
-#        # If -s is specified then the limit is strict, denying browsing
-#        # from any further IP addresses until the ttl has expired. Without
-#        # -s Squid will just annoy the user by "randomly" denying requests.
-#        # (the counter is then reset each time the limit is reached and a
-#        # request is denied)
-#        # NOTE: in acceleration mode or where there is mesh of child proxies,
-#        # clients may appear to come from multiple addresses if they are
-#        # going through proxy farms, so a limit of 1 may cause user problems.
-#
-#      acl aclname req_mime_type mime-type1 ...
-#        # regex match agains the mime type of the request generated
-#        # by the client. Can be used to detect file upload or some
-#        # types HTTP tunelling requests.
-#        # NOTE: This does NOT match the reply. You cannot use this
-#        # to match the returned file type.
-#
-#      acl aclname rep_mime_type mime-type1 ...
-#        # regex match against the mime type of the reply recieved by
-#        # squid. Can be used to detect file download or some
-#        # types HTTP tunelling requests.
-#        # NOTE: This has no effect in http_access rules. It only has
-#        # effect in rules that affect the reply data stream such as
-#        # http_reply_access.
-#
-#      acl acl_name external class_name [arguments...]
-#        # external ACL lookup via a helper class defined by the
-#        # external_acl_type directive.
-#
-#Examples:
-#acl myexample dst_as 1241
-#acl password proxy_auth REQUIRED
-#acl fileupload req_mime_type -i ^multipart/form-data$
-#acl javascript rep_mime_type -i ^application/x-javascript$
-#
-#Recommended minimum configuration:
-acl all src 0.0.0.0/0.0.0.0
-acl manager proto cache_object
-acl localhost src 127.0.0.1/255.255.255.255
-acl to_localhost dst 127.0.0.0/8
-acl SSL_ports port 443 563
-acl Jabber_ports port 5222
-acl Safe_ports port 80         # http
-acl Safe_ports port 21         # ftp
-acl Safe_ports port 443 563    # https, snews
-acl Safe_ports port 70         # gopher
-acl Safe_ports port 210                # wais
-acl Safe_ports port 1025-65535 # unregistered ports
-acl Safe_ports port 280                # http-mgmt
-acl Safe_ports port 488                # gss-http
-acl Safe_ports port 591                # filemaker
-acl Safe_ports port 777                # multiling http
-acl CONNECT method CONNECT
-
-#  TAG: http_access
-#      Allowing or Denying access based on defined access lists
-#
-#      Access to the HTTP port:
-#      http_access allow|deny [!]aclname ...
-#
-#      NOTE on default values:
-#
-#      If there are no "access" lines present, the default is to deny
-#      the request.
-#
-#      If none of the "access" lines cause a match, the default is the
-#      opposite of the last line in the list.  If the last line was
-#      deny, then the default is allow.  Conversely, if the last line
-#      is allow, the default will be deny.  For these reasons, it is a
-#      good idea to have an "deny all" or "allow all" entry at the end
-#      of your access lists to avoid potential confusion.
-#
-#Default:
-# http_access deny all
-#
-#Recommended minimum configuration:
-#
-# Only allow cachemgr access from localhost
-http_access allow manager localhost
-http_access deny manager
-# Deny requests to unknown ports
-http_access deny !Safe_ports
-# Deny CONNECT to other than SSL ports
-http_access deny CONNECT !SSL_ports !Jabber_ports
-#
-# We strongly recommend to uncomment the following to protect innocent
-# web applications running on the proxy server who think that the only
-# one who can access services on "localhost" is a local user
-#http_access deny to_localhost
-#
-# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
-
-# Example rule allowing access from your local networks. Adapt
-# to list your (internal) IP networks from where browsing should
-# be allowed
-acl password proxy_auth REQUIRED
-
-http_access allow password
-
-
-# And finally deny all other access to this proxy
-http_access allow localhost
-http_access deny all
-
-#  TAG: http_reply_access
-#        Allow replies to client requests. This is complementary to http_access.
-#
-#        http_reply_access allow|deny [!] aclname ...
-#
-#        NOTE: if there are no access lines present, the default is to allow
-#      all replies
-#
-#        If none of the access lines cause a match, then the opposite of the
-#        last line will apply. Thus it is good practice to end the rules
-#        with an "allow all" or "deny all" entry.
-#
-#Default:
-# http_reply_access allow all
-#
-#Recommended minimum configuration:
-#
-# Insert your own rules here.
-#
-#
-# and finally allow by default
-http_reply_access allow all
-
-#  TAG: icp_access
-#      Allowing or Denying access to the ICP port based on defined
-#      access lists
-#
-#      icp_access  allow|deny [!]aclname ...
-#
-#      See http_access for details
-#
-#Default:
-# icp_access deny all
-#
-#Allow ICP queries from everyone
-#icp_access allow all
-
-#  TAG: miss_access
-#      Use to force your neighbors to use you as a sibling instead of
-#      a parent.  For example:
-#
-#              acl localclients src 172.16.0.0/16
-#              miss_access allow localclients
-#              miss_access deny  !localclients
-#
-#      This means that only your local clients are allowed to fetch
-#      MISSES and all other clients can only fetch HITS.
-#
-#      By default, allow all clients who passed the http_access rules
-#      to fetch MISSES from us.
-#
-#Default setting:
-# miss_access allow all
-
-#  TAG: cache_peer_access
-#      Similar to 'cache_peer_domain' but provides more flexibility by
-#      using ACL elements.
-#
-#      cache_peer_access cache-host allow|deny [!]aclname ...
-#
-#      The syntax is identical to 'http_access' and the other lists of
-#      ACL elements.  See the comments for 'http_access' below, or
-#      the Squid FAQ (http://www.squid-cache.org/FAQ/FAQ-10.html).
-#
-#Default:
-# none
-
-#  TAG: ident_lookup_access
-#      A list of ACL elements which, if matched, cause an ident
-#      (RFC 931) lookup to be performed for this request.  For
-#      example, you might choose to always perform ident lookups
-#      for your main multi-user Unix boxes, but not for your Macs
-#      and PCs.  By default, ident lookups are not performed for
-#      any requests.
-#
-#      To enable ident lookups for specific client addresses, you
-#      can follow this example:
-#
-#      acl ident_aware_hosts src 198.168.1.0/255.255.255.0
-#      ident_lookup_access allow ident_aware_hosts
-#      ident_lookup_access deny all
-#
-#      Only src type ACL checks are fully supported.  A src_domain
-#      ACL might work at times, but it will not always provide
-#      the correct result.
-#
-#Default:
-# ident_lookup_access deny all
-
-#  TAG: tcp_outgoing_tos
-#      Allows you to select a TOS/Diffserv value to mark outgoing
-#      connections with, based on the username or source address
-#      making the request.
-#
-#      tcp_outgoing_tos ds-field [!]aclname ...
-#
-#      Example where normal_service_net uses the TOS value 0x00
-#      and normal_service_net uses 0x20
-#
-#      acl normal_service_net src 10.0.0.0/255.255.255.0
-#      acl good_service_net src 10.0.1.0/255.255.255.0
-#      tcp_outgoing_tos 0x00 normal_service_net 0x00
-#      tcp_outgoing_tos 0x20 good_service_net
-#
-#      TOS/DSCP values really only have local significance - so you should
-#      know what you're specifying. For more, see RFC 2474
-#
-#      The TOS/DSCP byte must be exactly that - a byte, value  0 - 255, or
-#      "default" to use whatever default your host has.
-#
-#      Processing proceeds in the order specified, and stops at first fully
-#      matching line.
-#
-#Default:
-# none
-
-#  TAG: tcp_outgoing_address
-#      Allows you to map requests to different outgoing IP addresses
-#      based on the username or sourceaddress of the user making
-#      the request.
-#      
-#      tcp_outgoing_address ipaddr [[!]aclname] ...
-#
-#      Example where requests from 10.0.0.0/24 will be forwareded
-#      with source address 10.1.0.1, 10.0.2.0/24 forwarded with 
-#      source address 10.1.0.2 and the rest will be forwarded with
-#      source address 10.1.0.3.
-#
-#      acl normal_service_net src 10.0.0.0/255.255.255.0
-#      acl good_service_net src 10.0.1.0/255.255.255.0
-#      tcp_outgoing_address 10.0.0.1 normal_service_net
-#      tcp_outgoing_address 10.0.0.2 good_service_net
-#      tcp_outgoing_address 10.0.0.3
-#
-#      Processing proceeds in the order specified, and stops at first fully
-#      matching line.
-#
-#Default:
-# none
-
-#  TAG: reply_body_max_size    bytes allow|deny acl acl...
-#        This option specifies the maximum size of a reply body in bytes.
-#      It can be used to prevent users from downloading very large files,
-#      such as MP3's and movies. When the reply headers are recieved,
-#      the reply_body_max_size lines are processed, and the first line with
-#      a result of "allow" is used as the maximum body size for this reply.
-#      This size is then checked twice. First when we get the reply headers,
-#      we check the content-length value.  If the content length value exists
-#      and is larger than the allowed size, the request is denied and the
-#      user receives an error message that says "the request or reply
-#      is too large." If there is no content-length, and the reply
-#      size exceeds this limit, the client's connection is just closed
-#      and they will receive a partial reply.
-#
-#      WARNING: downstream caches probably can not detect a partial reply
-#      if there is no content-length header, so they will cache
-#      partial responses and give them out as hits.  You should NOT
-#      use this option if you have downstream caches.
-#
-#      If you set this parameter to zero (the default), there will be
-#      no limit imposed.
-#
-#Default:
-# reply_body_max_size 0 allow all
-
-
-# ADMINISTRATIVE PARAMETERS
-# -----------------------------------------------------------------------------
-
-#  TAG: cache_mgr
-#      Email-address of local cache manager who will receive
-#      mail if the cache dies.  The default is "webmaster."
-#
-#Default:
-# cache_mgr webmaster
-
-#  TAG: cache_effective_user
-#  TAG: cache_effective_group
-#
-#      If you start Squid as root, it will change its effective/real
-#      UID/GID to the UID/GID specified below.  The default is to
-#      change to UID to nobody.  If you define cache_effective_user,
-#      but not cache_effective_group, Squid sets the GID the
-#      effective user's default group ID (taken from the password
-#      file).
-#
-#      If Squid is not started as root, the cache_effective_user
-#      value is ignored and the GID value is unchanged by default.
-#      However, you can make Squid change its GID to another group
-#      that the process owner is a member of.  Note that if Squid
-#      is not started as root then you cannot set http_port to a
-#      value lower than 1024.
-#
-#Default:
-# cache_effective_user squid
-# cache_effective_group squid
-
-#  TAG: visible_hostname
-#      If you want to present a special hostname in error messages, etc,
-#      then define this.  Otherwise, the return value of gethostname()
-#      will be used. If you have multiple caches in a cluster and
-#      get errors about IP-forwarding you must set them to have individual
-#      names with this setting.
-#
-#Default:
-# none
-
-#  TAG: unique_hostname
-#      If you want to have multiple machines with the same
-#      'visible_hostname' then you must give each machine a different
-#      'unique_hostname' so that forwarding loops can be detected.
-#
-#Default:
-# none
-
-#  TAG: hostname_aliases
-#      A list of other DNS names that your cache has.
-#
-#Default:
-# none
-
-
-# OPTIONS FOR THE CACHE REGISTRATION SERVICE
-# -----------------------------------------------------------------------------
-#
-#      This section contains parameters for the (optional) cache
-#      announcement service.  This service is provided to help
-#      cache administrators locate one another in order to join or
-#      create cache hierarchies.
-#
-#      An 'announcement' message is sent (via UDP) to the registration
-#      service by Squid.  By default, the announcement message is NOT
-#      SENT unless you enable it with 'announce_period' below.
-#
-#      The announcement message includes your hostname, plus the
-#      following information from this configuration file:
-#
-#              http_port
-#              icp_port
-#              cache_mgr
-#
-#      All current information is processed regularly and made
-#      available on the Web at http://www.ircache.net/Cache/Tracker/.
-
-#  TAG: announce_period
-#      This is how frequently to send cache announcements.  The
-#      default is `0' which disables sending the announcement
-#      messages.
-#
-#      To enable announcing your cache, just uncomment the line
-#      below.
-#
-#Default:
-# announce_period 0
-#
-#To enable announcing your cache, just uncomment the line below.
-#announce_period 1 day
-
-#  TAG: announce_host
-#  TAG: announce_file
-#  TAG: announce_port
-#      announce_host and announce_port set the hostname and port
-#      number where the registration message will be sent.
-#
-#      Hostname will default to 'tracker.ircache.net' and port will
-#      default default to 3131.  If the 'filename' argument is given,
-#      the contents of that file will be included in the announce
-#      message.
-#
-#Default:
-# announce_host tracker.ircache.net
-# announce_port 3131
-
-
-# HTTPD-ACCELERATOR OPTIONS
-# -----------------------------------------------------------------------------
-
-#  TAG: httpd_accel_host
-#  TAG: httpd_accel_port
-#      If you want to run Squid as an httpd accelerator, define the
-#      host name and port number where the real HTTP server is.
-#
-#      If you want IP based virtual host support then specify the
-#      hostname as "virtual". This will make Squid use the IP address
-#      where it accepted the request as hostname in the URL.
-#
-#      If you want virtual port support then specify the port as "0".
-#
-#      NOTE: enabling httpd_accel_host disables proxy-caching and
-#      ICP.  If you want these features enabled also, then set
-#      the 'httpd_accel_with_proxy' option.
-#
-#Default:
-# httpd_accel_port 80
-
-#  TAG: httpd_accel_single_host        on|off
-#      If you are running Squid as an accelerator and have a single backend
-#      server then set this to on. This causes Squid to forward the request
-#      to this server irregardles of what any redirectors or Host headers
-#      says.
-#
-#      Leave this at off if you have multiple backend servers, and use a
-#      redirector (or host table or private DNS) to map the requests to the
-#      appropriate backend servers. Note that the mapping needs to be a
-#      1-1 mapping between requested and backend (from redirector) domain
-#      names or caching will fail, as cacing is performed using the
-#      URL returned from the redirector.
-#
-#      See also redirect_rewrites_host_header.
-#
-#Default:
-# httpd_accel_single_host off
-
-#  TAG: httpd_accel_with_proxy on|off
-#      If you want to use Squid as both a local httpd accelerator
-#      and as a proxy, change this to 'on'. Note however that your
-#      proxy users may have trouble to reach the accelerated domains
-#      unless their browsers are configured not to use this proxy for
-#      those domains (for example via the no_proxy browser configuration
-#      setting)
-#
-#Default:
-# httpd_accel_with_proxy off
-
-#  TAG: httpd_accel_uses_host_header   on|off
-#      HTTP/1.1 requests include a Host: header which is basically the
-#      hostname from the URL.  The Host: header is used for domain based
-#      virutal hosts. If your accelerator needs to provide domain based
-#      virtual hosts on the same IP address then you will need to turn this
-#      on.
-#
-#      Note that Squid does NOT check the value of the Host header matches
-#      any of your accelerated server, so it may open a big security hole
-#      unless you take care to set up access controls proper.  We recommend
-#      that this option remain disabled unless you are sure of what you
-#      are doing.
-#
-#      However, you will need to enable this option if you run Squid
-#      as a transparent proxy.  Otherwise, virtual servers which
-#      require the Host: header will not be properly cached.
-#
-#Default:
-# httpd_accel_uses_host_header off
-
-
-# MISCELLANEOUS
-# -----------------------------------------------------------------------------
-
-#  TAG: dns_testnames
-#      The DNS tests exit as soon as the first site is successfully looked up
-#
-#      This test can be disabled with the -D command line option.
-#
-#Default:
-# dns_testnames netscape.com internic.net nlanr.net microsoft.com
-
-#  TAG: logfile_rotate
-#      Specifies the number of logfile rotations to make when you
-#      type 'squid -k rotate'.  The default is 10, which will rotate
-#      with extensions 0 through 9.  Setting logfile_rotate to 0 will
-#      disable the rotation, but the logfiles are still closed and
-#      re-opened.  This will enable you to rename the logfiles
-#      yourself just before sending the rotate signal.
-#
-#      Note, the 'squid -k rotate' command normally sends a USR1
-#      signal to the running squid process.  In certain situations
-#      (e.g. on Linux with Async I/O), USR1 is used for other
-#      purposes, so -k rotate uses another signal.  It is best to get
-#      in the habit of using 'squid -k rotate' instead of 'kill -USR1
-#      <pid>'.
-#
-#Default:
-# logfile_rotate 0
-
-#  TAG: append_domain
-#      Appends local domain name to hostnames without any dots in
-#      them.  append_domain must begin with a period.
-#
-#      Be warned that there today is Internet names with no dots in
-#      them using only top-domain names, so setting this may
-#      cause some Internet sites to become unavailable.
-#
-#Example:
-# append_domain .yourdomain.com
-#
-#Default:
-# none
-
-#  TAG: tcp_recv_bufsize       (bytes)
-#      Size of receive buffer to set for TCP sockets.  Probably just
-#      as easy to change your kernel's default.  Set to zero to use
-#      the default buffer size.
-#
-#Default:
-# tcp_recv_bufsize 0 bytes
-
-#  TAG: err_html_text
-#      HTML text to include in error messages.  Make this a "mailto"
-#      URL to your admin address, or maybe just a link to your
-#      organizations Web page.
-#
-#      To include this in your error messages, you must rewrite
-#      the error template files (found in the "errors" directory).
-#      Wherever you want the 'err_html_text' line to appear,
-#      insert a %L tag in the error template file.
-#
-#Default:
-# none
-
-#  TAG: deny_info
-#      Usage:   deny_info err_page_name acl
-#      or       deny_info http://... acl
-#      Example: deny_info ERR_CUSTOM_ACCESS_DENIED bad_guys
-#
-#      This can be used to return a ERR_ page for requests which
-#      do not pass the 'http_access' rules.  A single ACL will cause
-#      the http_access check to fail.  If a 'deny_info' line exists
-#      for that ACL then Squid returns a corresponding error page.
-#
-#      You may use ERR_ pages that come with Squid or create your own pages
-#      and put them into the configured errors/ directory.
-#
-#      Alternatively you can specify an error URL. The browsers will then
-#      get redirected (302) to the specified URL. %s in the redirection
-#      URL will be replaced by the requested URL.
-#
-#      Alternatively you can tell Squid to reset the TCP connection
-#      by specifying TCP_RESET.
-#
-#Default:
-# none
-
-#  TAG: memory_pools   on|off
-#      If set, Squid will keep pools of allocated (but unused) memory
-#      available for future use.  If memory is a premium on your
-#      system and you believe your malloc library outperforms Squid
-#      routines, disable this.
-#
-#Default:
-# memory_pools on
-
-#  TAG: memory_pools_limit     (bytes)
-#      Used only with memory_pools on:
-#      memory_pools_limit 50 MB
-#
-#      If set to a non-zero value, Squid will keep at most the specified
-#      limit of allocated (but unused) memory in memory pools. All free()
-#      requests that exceed this limit will be handled by your malloc
-#      library. Squid does not pre-allocate any memory, just safe-keeps
-#      objects that otherwise would be free()d. Thus, it is safe to set
-#      memory_pools_limit to a reasonably high value even if your
-#      configuration will use less memory.
-#
-#      If not set (default) or set to zero, Squid will keep all memory it
-#      can. That is, there will be no limit on the total amount of memory
-#      used for safe-keeping.
-#
-#      To disable memory allocation optimization, do not set
-#      memory_pools_limit to 0. Set memory_pools to "off" instead.
-#
-#      An overhead for maintaining memory pools is not taken into account
-#      when the limit is checked. This overhead is close to four bytes per
-#      object kept. However, pools may actually _save_ memory because of
-#      reduced memory thrashing in your malloc library.
-#
-#Default:
-# none
-
-#  TAG: forwarded_for  on|off
-#      If set, Squid will include your system's IP address or name
-#      in the HTTP requests it forwards.  By default it looks like
-#      this:
-#
-#              X-Forwarded-For: 192.1.2.3
-#
-#      If you disable this, it will appear as
-#
-#              X-Forwarded-For: unknown
-#
-#Default:
-# forwarded_for on
-
-#  TAG: log_icp_queries        on|off
-#      If set, ICP queries are logged to access.log. You may wish
-#      do disable this if your ICP load is VERY high to speed things
-#      up or to simplify log analysis.
-#
-#Default:
-# log_icp_queries on
-
-#  TAG: icp_hit_stale  on|off
-#      If you want to return ICP_HIT for stale cache objects, set this
-#      option to 'on'.  If you have sibling relationships with caches
-#      in other administrative domains, this should be 'off'.  If you only
-#      have sibling relationships with caches under your control, then
-#      it is probably okay to set this to 'on'.
-#      If set to 'on', then your siblings should use the option "allow-miss"
-#      on their cache_peer lines for connecting to you.
-#
-#Default:
-# icp_hit_stale off
-
-#  TAG: minimum_direct_hops
-#      If using the ICMP pinging stuff, do direct fetches for sites
-#      which are no more than this many hops away.
-#
-#Default:
-# minimum_direct_hops 4
-
-#  TAG: minimum_direct_rtt
-#      If using the ICMP pinging stuff, do direct fetches for sites
-#      which are no more than this many rtt milliseconds away.
-#
-#Default:
-# minimum_direct_rtt 400
-
-#  TAG: cachemgr_passwd
-#      Specify passwords for cachemgr operations.
-#
-#      Usage: cachemgr_passwd password action action ...
-#
-#      Some valid actions are (see cache manager menu for a full list):
-#              5min
-#              60min
-#              asndb
-#              authenticator
-#              cbdata
-#              client_list
-#              comm_incoming
-#              config *
-#              counters
-#              delay
-#              digest_stats
-#              dns
-#              events
-#              filedescriptors
-#              fqdncache
-#              histograms
-#              http_headers
-#              info
-#              io
-#              ipcache
-#              mem
-#              menu
-#              netdb
-#              non_peers
-#              objects
-#              offline_toggle *
-#              pconn
-#              peer_select
-#              redirector
-#              refresh
-#              server_list
-#              shutdown *
-#              store_digest
-#              storedir
-#              utilization
-#              via_headers
-#              vm_objects
-#
-#      * Indicates actions which will not be performed without a
-#        valid password, others can be performed if not listed here.
-#
-#      To disable an action, set the password to "disable".
-#      To allow performing an action without a password, set the
-#      password to "none".
-#
-#      Use the keyword "all" to set the same password for all actions.
-#
-#Example:
-# cachemgr_passwd secret shutdown
-# cachemgr_passwd lesssssssecret info stats/objects
-# cachemgr_passwd disable all
-#
-#Default:
-# none
-
-#  TAG: store_avg_object_size  (kbytes)
-#      Average object size, used to estimate number of objects your
-#      cache can hold.  See doc/Release-Notes-1.1.txt.  The default is
-#      13 KB.
-#
-#Default:
-# store_avg_object_size 13 KB
-
-#  TAG: store_objects_per_bucket
-#      Target number of objects per bucket in the store hash table.
-#      Lowering this value increases the total number of buckets and
-#      also the storage maintenance rate.  The default is 50.
-#
-#Default:
-# store_objects_per_bucket 20
-
-#  TAG: client_db      on|off
-#      If you want to disable collecting per-client statistics, then
-#      turn off client_db here.
-#
-#Default:
-# client_db on
-
-#  TAG: netdb_low
-#  TAG: netdb_high
-#      The low and high water marks for the ICMP measurement
-#      database.  These are counts, not percents.  The defaults are
-#      900 and 1000.  When the high water mark is reached, database
-#      entries will be deleted until the low mark is reached.
-#
-#Default:
-# netdb_low 900
-# netdb_high 1000
-
-#  TAG: netdb_ping_period
-#      The minimum period for measuring a site.  There will be at
-#      least this much delay between successive pings to the same
-#      network.  The default is five minutes.
-#
-#Default:
-# netdb_ping_period 5 minutes
-
-#  TAG: query_icmp     on|off
-#      If you want to ask your peers to include ICMP data in their ICP
-#      replies, enable this option.
-#
-#      If your peer has configured Squid (during compilation) with
-#      '--enable-icmp' then that peer will send ICMP pings to origin server
-#      sites of the URLs it receives.  If you enable this option then the
-#      ICP replies from that peer will include the ICMP data (if available).
-#      Then, when choosing a parent cache, Squid will choose the parent with
-#      the minimal RTT to the origin server.  When this happens, the
-#      hierarchy field of the access.log will be
-#      "CLOSEST_PARENT_MISS".  This option is off by default.
-#
-#Default:
-# query_icmp off
-
-#  TAG: test_reachability      on|off
-#      When this is 'on', ICP MISS replies will be ICP_MISS_NOFETCH
-#      instead of ICP_MISS if the target host is NOT in the ICMP
-#      database, or has a zero RTT.
-#
-#Default:
-# test_reachability off
-
-#  TAG: buffered_logs  on|off
-#      cache.log log file is written with stdio functions, and as such
-#      it can be buffered or unbuffered. By default it will be unbuffered.
-#      Buffering it can speed up the writing slightly (though you are
-#      unlikely to need to worry unless you run with tons of debugging
-#      enabled in which case performance will suffer badly anyway..).
-#
-#Default:
-# buffered_logs off
-
-#  TAG: reload_into_ims        on|off
-#      When you enable this option, client no-cache or ``reload''
-#      requests will be changed to If-Modified-Since requests.
-#      Doing this VIOLATES the HTTP standard.  Enabling this
-#      feature could make you liable for problems which it
-#      causes.
-#      
-#      see also refresh_pattern for a more selective approach.
-#
-#Default:
-# reload_into_ims off
-
-#  TAG: always_direct
-#      Usage: always_direct allow|deny [!]aclname ...
-#
-#      Here you can use ACL elements to specify requests which should
-#      ALWAYS be forwarded directly to origin servers.  For example,
-#      to always directly forward requests for local servers use
-#      something like:
-#
-#              acl local-servers dstdomain my.domain.net
-#              always_direct allow local-servers
-#
-#      To always forward FTP requests directly, use
-#
-#              acl FTP proto FTP
-#              always_direct allow FTP
-#
-#      NOTE: There is a similar, but opposite option named
-#      'never_direct'.  You need to be aware that "always_direct deny
-#      foo" is NOT the same thing as "never_direct allow foo".  You
-#      may need to use a deny rule to exclude a more-specific case of
-#      some other rule.  Example:
-#
-#              acl local-external dstdomain external.foo.net
-#              acl local-servers dstdomain  .foo.net
-#              always_direct deny local-external
-#              always_direct allow local-servers
-#
-#      This option replaces some v1.1 options such as local_domain
-#      and local_ip.
-#
-#Default:
-# none
-
-#  TAG: never_direct
-#      Usage: never_direct allow|deny [!]aclname ...
-#
-#      never_direct is the opposite of always_direct.  Please read
-#      the description for always_direct if you have not already.
-#
-#      With 'never_direct' you can use ACL elements to specify
-#      requests which should NEVER be forwarded directly to origin
-#      servers.  For example, to force the use of a proxy for all
-#      requests, except those in your local domain use something like:
-#
-#              acl local-servers dstdomain .foo.net
-#              acl all src 0.0.0.0/0.0.0.0
-#              never_direct deny local-servers
-#              never_direct allow all
-#      
-#      or if squid is inside a firewall and there is local intranet
-#      servers inside the firewall then use something like:
-#
-#              acl local-intranet dstdomain .foo.net
-#              acl local-external dstdomain external.foo.net
-#              always_direct deny local-external
-#              always_direct allow local-intranet
-#              never_direct allow all
-#      
-#      This option replaces some v1.1 options such as inside_firewall
-#      and firewall_ip.
-#
-#Default:
-# none
-
-#  TAG: header_access
-#      Usage: header_access header_name allow|deny [!]aclname ...
-#
-#      WARNING: Doing this VIOLATES the HTTP standard.  Enabling
-#      this feature could make you liable for problems which it
-#      causes.
-#
-#      This option replaces the old 'anonymize_headers' and the
-#      older 'http_anonymizer' option with something that is much
-#      more configurable. This new method creates a list of ACLs
-#      for each header, allowing you very fine-tuned header
-#      mangling.
-#
-#      You can only specify known headers for the header name.
-#      Other headers are reclassified as 'Other'. You can also
-#      refer to all the headers with 'All'.
-#
-#      For example, to achieve the same behaviour as the old
-#      'http_anonymizer standard' option, you should use:
-#
-#              header_access From deny all
-#              header_access Referer deny all
-#              header_access Server deny all
-#              header_access User-Agent deny all
-#              header_access WWW-Authenticate deny all
-#              header_access Link deny all
-#
-#      Or, to reproduce the old 'http_anonymizer paranoid' feature
-#      you should use:
-#
-#              header_access Allow allow all
-#              header_access Authorization allow all
-#              header_access WWW-Authenticate allow all
-#              header_access Cache-Control allow all
-#              header_access Content-Encoding allow all
-#              header_access Content-Length allow all
-#              header_access Content-Type allow all
-#              header_access Date allow all
-#              header_access Expires allow all
-#              header_access Host allow all
-#              header_access If-Modified-Since allow all
-#              header_access Last-Modified allow all
-#              header_access Location allow all
-#              header_access Pragma allow all
-#              header_access Accept allow all
-#              header_access Accept-Charset allow all
-#              header_access Accept-Encoding allow all
-#              header_access Accept-Language allow all
-#              header_access Content-Language allow all
-#              header_access Mime-Version allow all
-#              header_access Retry-After allow all
-#              header_access Title allow all
-#              header_access Connection allow all
-#              header_access Proxy-Connection allow all
-#              header_access All deny all
-#
-#      By default, all headers are allowed (no anonymizing is
-#      performed).
-#
-#Default:
-# none
-
-#  TAG: header_replace
-#      Usage:   header_replace header_name message
-#      Example: header_replace User-Agent Nutscrape/1.0 (CP/M; 8-bit)
-#
-#      This option allows you to change the contents of headers
-#      denied with header_access above, by replacing them with
-#      some fixed string. This replaces the old fake_user_agent
-#      option.
-#
-#      By default, headers are removed if denied.
-#
-#Default:
-# none
-
-#  TAG: icon_directory
-#      Where the icons are stored. These are normally kept in
-#      /usr/share/squid/icons
-#
-#Default:
-# icon_directory /usr/share/squid/icons
-
-#  TAG: short_icon_urls
-#      If this is enabled then Squid will use short URLs for icons.
-#
-#      If off then the URLs for icons will always be absolute URLs
-#      including the proxy name and port.
-#
-#Default:
-# short_icon_urls off
-
-#  TAG: error_directory
-#      If you wish to create your own versions of the default
-#      (English) error files, either to customize them to suit your
-#      language or company copy the template English files to another
-#      directory and point this tag at them.
-#
-#Default:
-# error_directory /usr/share/squid/errors/English
-
-#  TAG: maximum_single_addr_tries
-#      This sets the maximum number of connection attempts for a
-#      host that only has one address (for multiple-address hosts,
-#      each address is tried once).
-#
-#      The default value is one attempt, the (not recommended)
-#      maximum is 255 tries.  A warning message will be generated
-#      if it is set to a value greater than ten.
-#
-#      Note: This is in addition to the request reforwarding which
-#      takes place if Squid fails to get a satisfying response.
-#
-#Default:
-# maximum_single_addr_tries 1
-
-#  TAG: snmp_port
-#      Squid can now serve statistics and status information via SNMP.
-#      By default it listens to port 3401 on the machine. If you don't
-#      wish to use SNMP, set this to "0".
-#
-#Default:
-# snmp_port 3401
-
-#  TAG: snmp_access
-#      Allowing or denying access to the SNMP port.
-#
-#      All access to the agent is denied by default.
-#      usage:
-#
-#      snmp_access allow|deny [!]aclname ...
-#
-#Example:
-# snmp_access allow snmppublic localhost
-# snmp_access deny all
-#
-#Default:
-# snmp_access deny all
-
-#  TAG: snmp_incoming_address
-#  TAG: snmp_outgoing_address
-#      Just like 'udp_incoming_address' above, but for the SNMP port.
-#
-#      snmp_incoming_address   is used for the SNMP socket receiving
-#                              messages from SNMP agents.
-#      snmp_outgoing_address   is used for SNMP packets returned to SNMP
-#                              agents.
-#
-#      The default snmp_incoming_address (0.0.0.0) is to listen on all
-#      available network interfaces.
-#
-#      If snmp_outgoing_address is set to 255.255.255.255 (the default)
-#      then it will use the same socket as snmp_incoming_address. Only
-#      change this if you want to have SNMP replies sent using another
-#      address than where this Squid listens for SNMP queries.
-#
-#      NOTE, snmp_incoming_address and snmp_outgoing_address can not have
-#      the same value since they both use port 3401.
-#
-#Default:
-# snmp_incoming_address 0.0.0.0
-# snmp_outgoing_address 255.255.255.255
-
-#  TAG: as_whois_server
-#      WHOIS server to query for AS numbers.  NOTE: AS numbers are
-#      queried only when Squid starts up, not for every request.
-#
-#Default:
-# as_whois_server whois.ra.net
-# as_whois_server whois.ra.net
-
-#  TAG: wccp_router
-#      Use this option to define your WCCP ``home'' router for
-#      Squid.   Setting the 'wccp_router' to 0.0.0.0 (the default)
-#      disables WCCP.
-#
-#Default:
-# wccp_router 0.0.0.0
-
-#  TAG: wccp_version
-#      According to some users, Cisco IOS 11.2 only supports WCCP
-#      version 3.  If you're using that version of IOS, change
-#      this value to 3.
-#
-#Default:
-# wccp_version 4
-
-#  TAG: wccp_incoming_address
-#  TAG: wccp_outgoing_address
-#        wccp_incoming_address   Use this option if you require WCCP
-#                              messages to be received on only one
-#                              interface.  Do NOT use this option if
-#                              you're unsure how many interfaces you
-#                              have, or if you know you have only one
-#                              interface.
-#
-#      wccp_outgoing_address   Use this option if you require WCCP
-#                              messages to be sent out on only one
-#                              interface.  Do NOT use this option if
-#                              you're unsure how many interfaces you
-#                              have, or if you know you have only one
-#                              interface.
-#
-#        The default behavior is to not bind to any specific address.
-#
-#        NOTE, wccp_incoming_address and wccp_outgoing_address can not have
-#        the same value since they both use port 2048.
-#
-#Default:
-# wccp_incoming_address 0.0.0.0
-# wccp_outgoing_address 255.255.255.255
-
-
-# DELAY POOL PARAMETERS (all require DELAY_POOLS compilation option)
-# -----------------------------------------------------------------------------
-
-#  TAG: delay_pools
-#      This represents the number of delay pools to be used.  For example,
-#      if you have one class 2 delay pool and one class 3 delays pool, you
-#      have a total of 2 delay pools.
-#
-#Default:
-# delay_pools 0
-
-#  TAG: delay_class
-#      This defines the class of each delay pool.  There must be exactly one
-#      delay_class line for each delay pool.  For example, to define two
-#      delay pools, one of class 2 and one of class 3, the settings above
-#      and here would be:
-#
-#Example:
-# delay_pools 2      # 2 delay pools
-# delay_class 1 2    # pool 1 is a class 2 pool
-# delay_class 2 3    # pool 2 is a class 3 pool
-#
-#      The delay pool classes are:
-#
-#              class 1         Everything is limited by a single aggregate
-#                              bucket.
-#
-#              class 2         Everything is limited by a single aggregate
-#                              bucket as well as an "individual" bucket chosen
-#                              from bits 25 through 32 of the IP address.
-#
-#              class 3         Everything is limited by a single aggregate
-#                              bucket as well as a "network" bucket chosen
-#                              from bits 17 through 24 of the IP address and a
-#                              "individual" bucket chosen from bits 17 through
-#                              32 of the IP address.
-#
-#      NOTE: If an IP address is a.b.c.d
-#              -> bits 25 through 32 are "d"
-#              -> bits 17 through 24 are "c"
-#              -> bits 17 through 32 are "c * 256 + d"
-#
-#Default:
-# none
-
-#  TAG: delay_access
-#      This is used to determine which delay pool a request falls into.
-#      The first matched delay pool is always used, i.e., if a request falls
-#      into delay pool number one, no more delay are checked, otherwise the
-#      rest are checked in order of their delay pool number until they have
-#      all been checked.  For example, if you want some_big_clients in delay
-#      pool 1 and lotsa_little_clients in delay pool 2:
-#
-#Example:
-# delay_access 1 allow some_big_clients
-# delay_access 1 deny all
-# delay_access 2 allow lotsa_little_clients
-# delay_access 2 deny all
-#
-#Default:
-# none
-
-#  TAG: delay_parameters
-#      This defines the parameters for a delay pool.  Each delay pool has
-#      a number of "buckets" associated with it, as explained in the
-#      description of delay_class.  For a class 1 delay pool, the syntax is:
-#
-#delay_parameters pool aggregate
-#
-#      For a class 2 delay pool:
-#
-#delay_parameters pool aggregate individual
-#
-#      For a class 3 delay pool:
-#
-#delay_parameters pool aggregate network individual
-#
-#      The variables here are:
-#
-#              pool            a pool number - ie, a number between 1 and the
-#                              number specified in delay_pools as used in
-#                              delay_class lines.
-#
-#              aggregate       the "delay parameters" for the aggregate bucket
-#                              (class 1, 2, 3).
-#
-#              individual      the "delay parameters" for the individual
-#                              buckets (class 2, 3).
-#
-#              network         the "delay parameters" for the network buckets
-#                              (class 3).
-#
-#      A pair of delay parameters is written restore/maximum, where restore is
-#      the number of bytes (not bits - modem and network speeds are usually
-#      quoted in bits) per second placed into the bucket, and maximum is the
-#      maximum number of bytes which can be in the bucket at any time.
-#
-#      For example, if delay pool number 1 is a class 2 delay pool as in the
-#      above example, and is being used to strictly limit each host to 64kbps
-#      (plus overheads), with no overall limit, the line is:
-#
-#delay_parameters 1 -1/-1 8000/8000
-#
-#      Note that the figure -1 is used to represent "unlimited".
-#
-#      And, if delay pool number 2 is a class 3 delay pool as in the above
-#      example, and you want to limit it to a total of 256kbps (strict limit)
-#      with each 8-bit network permitted 64kbps (strict limit) and each
-#      individual host permitted 4800bps with a bucket maximum size of 64kb
-#      to permit a decent web page to be downloaded at a decent speed
-#      (if the network is not being limited due to overuse) but slow down
-#      large downloads more significantly:
-#
-#delay_parameters 2 32000/32000 8000/8000 600/8000
-#
-#      There must be one delay_parameters line for each delay pool.
-#
-#Default:
-# none
-
-#  TAG: delay_initial_bucket_level     (percent, 0-100)
-#      The initial bucket percentage is used to determine how much is put
-#      in each bucket when squid starts, is reconfigured, or first notices
-#      a host accessing it (in class 2 and class 3, individual hosts and
-#      networks only have buckets associated with them once they have been
-#      "seen" by squid).
-#
-#Default:
-# delay_initial_bucket_level 50
-
-#  TAG: incoming_icp_average
-#  TAG: incoming_http_average
-#  TAG: incoming_dns_average
-#  TAG: min_icp_poll_cnt
-#  TAG: min_dns_poll_cnt
-#  TAG: min_http_poll_cnt
-#      Heavy voodoo here.  I can't even believe you are reading this.
-#      Are you crazy?  Don't even think about adjusting these unless
-#      you understand the algorithms in comm_select.c first!
-#
-#Default:
-# incoming_icp_average 6
-# incoming_http_average 4
-# incoming_dns_average 4
-# min_icp_poll_cnt 8
-# min_dns_poll_cnt 8
-# min_http_poll_cnt 8
-
-#  TAG: max_open_disk_fds
-#      To avoid having disk as the I/O bottleneck Squid can optionally
-#      bypass the on-disk cache if more than this amount of disk file
-#      descriptors are open.
-#
-#      A value of 0 indicates no limit.
-#
-#Default:
-# max_open_disk_fds 0
-
-#  TAG: offline_mode
-#      Enable this option and Squid will never try to validate cached
-#      objects.
-#
-#Default:
-# offline_mode off
-
-#  TAG: uri_whitespace
-#      What to do with requests that have whitespace characters in the
-#      URI.  Options:
-#
-#      strip:  The whitespace characters are stripped out of the URL.
-#              This is the behavior recommended by RFC2396.
-#      deny:   The request is denied.  The user receives an "Invalid
-#              Request" message.
-#      allow:  The request is allowed and the URI is not changed.  The
-#              whitespace characters remain in the URI.  Note the
-#              whitespace is passed to redirector processes if they
-#              are in use.
-#      encode: The request is allowed and the whitespace characters are
-#              encoded according to RFC1738.  This could be considered
-#              a violation of the HTTP/1.1
-#              RFC because proxies are not allowed to rewrite URI's.
-#      chop:   The request is allowed and the URI is chopped at the
-#              first whitespace.  This might also be considered a
-#              violation.
-#
-#Default:
-# uri_whitespace strip
-
-#  TAG: broken_posts
-#      A list of ACL elements which, if matched, causes Squid to send
-#      an extra CRLF pair after the body of a PUT/POST request.
-#
-#      Some HTTP servers has broken implementations of PUT/POST,
-#      and rely on an extra CRLF pair sent by some WWW clients.
-#
-#      Quote from RFC 2068 section 4.1 on this matter:
-#
-#        Note: certain buggy HTTP/1.0 client implementations generate an
-#        extra CRLF's after a POST request. To restate what is explicitly
-#        forbidden by the BNF, an HTTP/1.1 client must not preface or follow
-#        a request with an extra CRLF.
-#
-#Example:
-# acl buggy_server url_regex ^http://....
-# broken_posts allow buggy_server
-#
-#Default:
-# none
-
-#  TAG: mcast_miss_addr
-# Note: This option is only available if Squid is rebuilt with the
-#       -DMULTICAST_MISS_STREAM option
-#
-#      If you enable this option, every "cache miss" URL will
-#      be sent out on the specified multicast address.
-#
-#      Do not enable this option unless you are are absolutely
-#      certain you understand what you are doing.
-#
-#Default:
-# mcast_miss_addr 255.255.255.255
-
-#  TAG: mcast_miss_ttl
-# Note: This option is only available if Squid is rebuilt with the
-#       -DMULTICAST_MISS_TTL option
-#
-#      This is the time-to-live value for packets multicasted
-#      when multicasting off cache miss URLs is enabled.  By
-#      default this is set to 'site scope', i.e. 16.
-#
-#Default:
-# mcast_miss_ttl 16
-
-#  TAG: mcast_miss_port
-# Note: This option is only available if Squid is rebuilt with the
-#       -DMULTICAST_MISS_STREAM option
-#
-#      This is the port number to be used in conjunction with
-#      'mcast_miss_addr'.
-#
-#Default:
-# mcast_miss_port 3135
-
-#  TAG: mcast_miss_encode_key
-# Note: This option is only available if Squid is rebuilt with the
-#       -DMULTICAST_MISS_STREAM option
-#
-#      The URLs that are sent in the multicast miss stream are
-#      encrypted.  This is the encryption key.
-#
-#Default:
-# mcast_miss_encode_key XXXXXXXXXXXXXXXX
-
-#  TAG: nonhierarchical_direct
-#      By default, Squid will send any non-hierarchical requests
-#      (matching hierarchy_stoplist or not cachable request type) direct
-#      to origin servers.
-#
-#      If you set this to off, then Squid will prefer to send these
-#      requests to parents.
-#
-#      Note that in most configurations, by turning this off you will only
-#      add latency to these request without any improvement in global hit
-#      ratio.
-#
-#      If you are inside an firewall then see never_direct instead of
-#      this directive.
-#
-#Default:
-# nonhierarchical_direct on
-
-#  TAG: prefer_direct
-#      Normally Squid tries to use parents for most requests. If you by some
-#      reason like it to first try going direct and only use a parent if
-#      going direct fails then set this to on.
-#
-#      By combining nonhierarchical_direct off and prefer_direct on you
-#      can set up Squid to use a parent as a backup path if going direct
-#      fails.
-#
-#      Note: If you want Squid to use parents for all requests then see
-#      the never_direct directive. prefer_direct only modifies how Squid
-#      acts on cachable requests.
-#
-#Default:
-# prefer_direct off
-
-#  TAG: strip_query_terms
-#      By default, Squid strips query terms from requested URLs before
-#      logging.  This protects your user's privacy.
-#
-#Default:
-# strip_query_terms on
-
-#  TAG: coredump_dir
-#      By default Squid leaves core files in the directory from where
-#      it was started. If you set 'coredump_dir' to a directory
-#      that exists, Squid will chdir() to that directory at startup
-#      and coredump files will be left there.
-#
-#Default:
-# coredump_dir none
-#
-# Leave coredumps in the first cache dir
-coredump_dir /var/spool/squid
-
-#  TAG: redirector_bypass
-#      When this is 'on', a request will not go through the
-#      redirector if all redirectors are busy.  If this is 'off'
-#      and the redirector queue grows too large, Squid will exit
-#      with a FATAL error and ask you to increase the number of
-#      redirectors.  You should only enable this if the redirectors
-#      are not critical to your caching system.  If you use
-#      redirectors for access control, and you enable this option,
-#      then users may have access to pages that they should not
-#      be allowed to request.
-#
-#Default:
-# redirector_bypass off
-
-#  TAG: ignore_unknown_nameservers
-#      By default Squid checks that DNS responses are received
-#      from the same IP addresses that they are sent to.  If they
-#      don't match, Squid ignores the response and writes a warning
-#      message to cache.log.  You can allow responses from unknown
-#      nameservers by setting this option to 'off'.
-#
-#Default:
-# ignore_unknown_nameservers on
-
-#  TAG: digest_generation
-#      This controls whether the server will generate a Cache Digest
-#      of its contents.  By default, Cache Digest generation is
-#      enabled if Squid is compiled with USE_CACHE_DIGESTS defined.
-#
-#Default:
-# digest_generation on
-
-#  TAG: digest_bits_per_entry
-#      This is the number of bits of the server's Cache Digest which
-#      will be associated with the Digest entry for a given HTTP
-#      Method and URL (public key) combination.  The default is 5.
-#
-#Default:
-# digest_bits_per_entry 5
-
-#  TAG: digest_rebuild_period  (seconds)
-#      This is the number of seconds between Cache Digest rebuilds.
-#
-#Default:
-# digest_rebuild_period 1 hour
-
-#  TAG: digest_rewrite_period  (seconds)
-#      This is the number of seconds between Cache Digest writes to
-#      disk.
-#
-#Default:
-# digest_rewrite_period 1 hour
-
-#  TAG: digest_swapout_chunk_size      (bytes)
-#      This is the number of bytes of the Cache Digest to write to
-#      disk at a time.  It defaults to 4096 bytes (4KB), the Squid
-#      default swap page.
-#
-#Default:
-# digest_swapout_chunk_size 4096 bytes
-
-#  TAG: digest_rebuild_chunk_percentage        (percent, 0-100)
-#      This is the percentage of the Cache Digest to be scanned at a
-#      time.  By default it is set to 10% of the Cache Digest.
-#
-#Default:
-# digest_rebuild_chunk_percentage 10
-
-#  TAG: chroot
-#      Use this to have Squid do a chroot() while initializing.  This
-#      also causes Squid to fully drop root privileges after
-#      initializing.  This means, for example, that if you use a HTTP
-#      port less than 1024 and try to reconfigure, you will get an
-#      error.
-#
-#Default:
-# none
-
-#  TAG: client_persistent_connections
-#  TAG: server_persistent_connections
-#      Persistent connection support for clients and servers.  By
-#      default, Squid uses persistent connections (when allowed)
-#      with its clients and servers.  You can use these options to
-#      disable persistent connections with clients and/or servers.
-#
-#Default:
-# client_persistent_connections on
-# server_persistent_connections on
-
-#  TAG: detect_broken_pconn
-#      Some servers have been found to incorrectly signal the use
-#      of HTTP/1.0 persistent connections even on replies not
-#      compatible, causing significant delays. This server problem
-#      has mostly been seen on redirects.
-#
-#      By enabling this directive Squid attempts to detect such
-#      broken replies and automatically assume the reply is finished
-#      after 10 seconds timeout.
-#
-#Default:
-# detect_broken_pconn off
-
-#  TAG: pipeline_prefetch
-#      To boost the performance of pipelined requests to closer
-#      match that of a non-proxied environment Squid can try to fetch
-#      up to two requests in parallell from a pipeline.
-#
-#      Defaults to off for bandwidth management and access logging
-#      reasons.
-#
-#Default:
-# pipeline_prefetch off
-
-#  TAG: extension_methods
-#      Squid only knows about standardized HTTP request methods.
-#      You can add up to 20 additional "extension" methods here.
-#
-#Default:
-# none
-
-#  TAG: request_entities
-#      Squid defaults to deny GET and HEAD requests with request entities,
-#      as the meaning of such requests are undefined in the HTTP standard
-#      even if not explicitly forbidden.
-#
-#      Set this directive to on if you have clients which insists
-#      on sending request entities in GET or HEAD requests.
-#
-#Default:
-# request_entities off
-
-#  TAG: high_response_time_warning     (msec)
-#      If the one-minute median response time exceeds this value,
-#      Squid prints a WARNING with debug level 0 to get the
-#      administrators attention.  The value is in milliseconds.
-#
-#Default:
-# high_response_time_warning 0
-
-#  TAG: high_page_fault_warning
-#      If the one-minute average page fault rate exceeds this
-#      value, Squid prints a WARNING with debug level 0 to get
-#      the administrators attention.  The value is in page faults
-#      per second.
-#
-#Default:
-# high_page_fault_warning 0
-
-#  TAG: high_memory_warning
-#      If the memory usage (as determined by mallinfo) exceeds
-#      value, Squid prints a WARNING with debug level 0 to get
-#      the administrators attention.
-#
-#Default:
-# high_memory_warning 0
-
-#  TAG: store_dir_select_algorithm
-#      Set this to 'round-robin' as an alternative.
-#
-#Default:
-# store_dir_select_algorithm least-load
-
-#  TAG: forward_log
-# Note: This option is only available if Squid is rebuilt with the
-#       -DWIP_FWD_LOG option
-#
-#      Logs the server-side requests.
-#
-#      This is currently work in progress.
-#
-#Default:
-# none
-
-#  TAG: ie_refresh     on|off
-#      Microsoft Internet Explorer up until version 5.5 Service
-#      Pack 1 has an issue with transparent proxies, wherein it
-#      is impossible to force a refresh.  Turning this on provides
-#      a partial fix to the problem, by causing all IMS-REFRESH
-#      requests from older IE versions to check the origin server
-#      for fresh content.  This reduces hit ratio by some amount
-#      (~10% in my experience), but allows users to actually get
-#      fresh content when they want it.  Note that because Squid
-#      cannot tell if the user is using 5.5 or 5.5SP1, the behavior
-#      of 5.5 is unchanged from old versions of Squid (i.e. a
-#      forced refresh is impossible).  Newer versions of IE will,
-#      hopefully, continue to have the new behavior and will be
-#      handled based on that assumption.  This option defaults to
-#      the old Squid behavior, which is better for hit ratios but
-#      worse for clients using IE, if they need to be able to
-#      force fresh content.
-#
-#Default:
-# ie_refresh off
-
-#  TAG: vary_ignore_expire     on|off
-#      Many HTTP servers supporting Vary gives such objects
-#      immediate expiry time with no cache-control header
-#      when requested by a HTTP/1.0 client. This option
-#      enables Squid to ignore such expiry times until
-#      HTTP/1.1 is fully implemented.
-#      WARNING: This may eventually cause some varying
-#      objects not intended for caching to get cached.
-#
-#Default:
-# vary_ignore_expire off
-
-#  TAG: sleep_after_fork       (microseconds)
-#      When this is set to a non-zero value, the main Squid process
-#      sleeps the specified number of microseconds after a fork()
-#      system call. This sleep may help the situation where your
-#      system reports fork() failures due to lack of (virtual)
-#      memory. Note, however, that if you have a lot of child
-#      processes, then these sleep delays will add up and your
-#      Squid will not service requests for some amount of time
-#      until all the child processes have been started.
-#
-#Default:
-# sleep_after_fork 0
-
diff --git a/contrib/altlinux/init.ldif b/contrib/altlinux/init.ldif
deleted file mode 100644 (file)
index 9545ecf..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-dn: dc=example,dc=com
-objectClass: top
-objectClass: dcObject
-objectClass: organization
-objectClass: gosaDepartment
-dc: example
-o: Example Inc.
-ou: example
-description: Main building
-
-dn: ou=Apps,dc=example,dc=com
-objectClass: organizationalUnit
-ou: Apps
-
-dn: cn=gosa,ou=Apps,dc=example,dc=com
-objectClass: top
-objectClass: applicationProcess
-objectClass: simpleSecurityObject
-userPassword: gosa
-cn: gosa
-
-dn: cn=smbpasswd,ou=Apps,dc=example,dc=com
-objectClass: top
-objectClass: applicationProcess
-objectClass: simpleSecurityObject
-cn: smbpasswd
-userPassword: smbpasswd
-
-dn: cn=cyrus,ou=Apps,dc=example,dc=com
-objectClass: top
-objectClass: applicationProcess
-objectClass: simpleSecurityObject
-cn: cyrus
-userPassword: cyrus
-
-dn: cn=saslauthd,ou=Apps,dc=example,dc=com
-objectClass: top
-objectClass: applicationProcess
-objectClass: simpleSecurityObject
-cn: saslauthd
-userPassword: saslauthd
-
-dn: ou=Admins,dc=example,dc=com
-objectClass: organizationalUnit
-ou: Admins
-description: Directory administrators
-
-dn: cn=admin,ou=Admins,dc=example,dc=com
-objectClass: person
-cn: admin
-sn: admin
-userPassword: secret
-
-dn: ou=People,dc=example,dc=com
-objectClass: organizationalUnit
-ou: People
-
-dn: uid=administrator,ou=People,dc=example,dc=com
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-objectClass: gosaAccount
-userPassword: secret
-sn: System
-cn: administrator
-givenName: Administrator
-uid: administrator
-
-dn: ou=Groups,dc=example,dc=com
-objectClass: organizationalUnit
-ou: Groups
-
-dn: cn=administrator,ou=Groups,dc=example,dc=com
-objectClass: top
-objectClass: gosaObject
-objectClass: posixGroup
-gosaSubtreeACL:: OmFsbA==
-cn: administrator
-gidNumber: 999
-memberUid: administrator
-
-dn: ou=Computers,dc=example,dc=com
-objectClass: organizationalUnit
-ou: Computers
-
-dn: uid=pdc$,ou=Computers,dc=example,dc=com
-objectClass: top
-objectClass: account
-objectClass: goImapServer
-uid: pdc$
-cn: localhost
-goImapName: mail.example.lan
-goImapConnect: {localhost:143}
-goImapAdmin: cyrus
-goImapSieveServer: localhost
-goImapSievePort: 2000
-goImapPassword: cyrus
-
-dn: dc=branch,dc=example,dc=com
-objectClass: top
-objectClass: dcObject
-objectClass: organizationalUnit
-objectClass: gosaDepartment
-dc: branch
-ou: branch
-description: Remote branch
-
-dn: ou=Addressbook,dc=example,dc=com
-objectClass: organizationalUnit
-ou: Addressbook
-
-dn: ou=Systems,dc=example,dc=com
-objectClass: organizationalUnit
-ou: Systems
-
-dn: ou=configs,ou=systems,dc=example,dc=com
-objectClass: organizationalUnit
-ou: configs
-
-dn: ou=gosa,ou=configs,ou=systems,dc=example,dc=com
-objectClass: organizationalUnit
-ou: gosa
-
diff --git a/contrib/daemon/arp-handler-d b/contrib/daemon/arp-handler-d
deleted file mode 100755 (executable)
index b8698bc..0000000
+++ /dev/null
@@ -1,563 +0,0 @@
-#!/usr/bin/perl 
-#===============================================================================
-#
-#         FILE:  gosa-support-daemon.pl
-#
-#        USAGE:  ./.gosa-support-daemon.pl
-#
-#  DESCRIPTION:  
-#
-#      OPTIONS:  ---
-# REQUIREMENTS:  ---
-#         BUGS:  ---
-#        NOTES:  ---
-#       AUTHOR:   Andreas Rettenberger, <rettenberger@gonicus.de>
-#      COMPANY:  Gonicus GmbH, Arnsberg
-#      VERSION:  1.0
-#      CREATED:  21.08.2007 15:13:51 CEST
-#     REVISION:  ---
-#===============================================================================
-
-use strict;
-use warnings;
-use Getopt::Long;
-use Config::IniFiles;
-use POSIX;
-use Fcntl;
-use Net::LDAP;
-use Net::LDAP::LDIF;
-use Net::LDAP::Entry;
-use Switch;
-
-
-my ($verbose, $cfg_file, $log_file, $pid_file, $foreground); 
-my ($timeout, $mailto, $mailfrom, $user, $group);
-my ($procid, $pid, $loglevel);
-my ($fifo_path, $max_process_timeout, $max_process );
-my %daemon_children;
-my ($ldap, $bind_phrase, $password, $ldap_base) ;
-
-$procid = -1 ;
-$foreground = 0 ;
-$verbose = 0 ;
-$max_process = 2 ;
-$max_process_timeout = 1 ;
-$ldap_base = "dc=gonicus,dc=de" ;
-#$ldap_path = "/var/run/gosa-support-daemon.socket";
-#$log_path = "/var/log/gosa-support-daemon.log";
-#$pid_path = "/var/run/gosa-support-daemon/gosa-support-daemon.pid";
-
-#---------------------------------------------------------------------------
-#  parse commandline options
-#---------------------------------------------------------------------------
-Getopt::Long::Configure( "bundling" );
-GetOptions( "v|verbose+" => \$verbose,
-        "c|config=s" => \$cfg_file,
-        "h|help" => \&usage,
-        "l|logfile=s" => \$log_file,
-        "p|pid=s" => \$pid_file,
-        "f|foreground" => \$foreground);
-
-#---------------------------------------------------------------------------
-#  read and set config parameters
-#---------------------------------------------------------------------------
-my %cfg_defaults =
-("Allgemein" =>
- {"timeout"  => [ \$timeout, 1000 ],
- "mailto"   => [ \$mailto, 'root@localhost' ],
- "mailfrom" => [ \$mailfrom, 'sps-daemon@localhost' ],
- "user"     => [ \$user, "nobody" ],
- "group"    => [ \$group, "nogroup" ],
- "fifo_path" => [ \$fifo_path, "/home/rettenbe/gonicus/gosa-support/tmp/fifo" ],
- "log_file"  => [ \$log_file, "/home/rettenbe/gonicus/gosa-support/tmp/gosa-support.log" ],
- "pid_file"  => [ \$pid_file, "/home/rettenbe/gonicus/gosa-support/tmp/gosa-support.pid" ],
- "loglevel"     => [ \$loglevel, 1]
- },
-"LDAP"  =>
-    {"bind" => [ \$bind_phrase, "cn=ldapadmin,dc=gonicus,dc=de" ],
-     "password" => [ \$password, "tester" ],
-    }
- );
-&read_configfile;
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  check_cmdline_param
-#      PURPOSE:  checks all commandline parameters to validity
-#   PARAMETERS:  none
-#      RETURNS:  none
-#  DESCRIPTION:  ????
-#       THROWS:  no exceptions
-#     COMMENTS:  none
-#     SEE ALSO:  n/a
-#===============================================================================
-sub check_cmdline_param () {
-    my $err_config;
-    my $err_log;
-    my $err_pid;
-    my $err_counter = 0;
-    if( not defined( $cfg_file)) {
-        $err_config = "please specify a config file";
-        $err_counter += 1;
-    }
-    if( not defined( $log_file)) {
-        $err_log = "please specify a log file";
-        $err_counter += 1;
-    }
-    if( not defined( $pid_file)) {
-        $err_pid = "please specify a pid file";
-        $err_counter += 1;
-    }
-    if( $err_counter > 0 ) {
-        &usage( "", 1 );
-        if( defined( $err_config)) { print STDERR "$err_config\n"}
-        if( defined( $err_log)) { print STDERR "$err_log\n" }
-        if( defined( $err_pid)) { print STDERR "$err_pid\n"}
-        print STDERR "\n";
-        exit( -1 );
-    }
-}
-
-#===  FUNCTION  ================================================================
-#         NAME:  check_pid
-#      PURPOSE:  
-#   PARAMETERS:  none
-#      RETURNS:  none
-#  DESCRIPTION:  ????
-#       THROWS:  no exceptions
-#     COMMENTS:  none
-#     SEE ALSO:  n/a
-#===============================================================================
-sub check_pid { 
-    if( open( LOCK_FILE, "<$pid_file") ) {
-        $procid = <LOCK_FILE>;
-        if( defined $procid ) {
-            chomp( $procid );
-            if( -f "/proc/$procid/stat" ) {
-                my($stat) = `cat /proc/$procid/stat` =~ m/$procid \((.+)\).*/;
-                print "\t".$stat."\n";
-                if( "sps-daemon.pl" eq $stat ) {
-                    close( LOCK_FILE );
-                    exit -1;
-                }
-            }
-        }
-        close( LOCK_FILE );
-        unlink( $pid_file );
-    }
-
-    # Try to open PID file
-    if (!sysopen(LOCK_FILE, $pid_file, O_WRONLY|O_CREAT|O_EXCL, 0644)) {
-        my($msg) = "Couldn't obtain lockfile '$pid_file' ";
-        if (open(LOCK_FILE, "<", $pid_file) && ($pid = <LOCK_FILE>)) {
-            chomp($pid);
-            $msg .= "(PID $pid)\n";
-        } else {
-            $msg .= "(unable to read PID)\n";
-        }
-        if ( ! $foreground ) {
-            daemon_log( $msg."\n");
-        } else {
-            print( STDERR " $msg " );
-        }
-        exit( -1 );
-    }
-}
-
-#===  FUNCTION  ================================================================
-#         NAME:  read_configfile
-#      PURPOSE:  read the configuration file and provide the programm with 
-#                parameters
-#   PARAMETERS:  none
-#      RETURNS:  none
-#  DESCRIPTION:  ????
-#       THROWS:  no exceptions
-#     COMMENTS:  none
-#     SEE ALSO:  n/a
-#===============================================================================
-sub read_configfile {
-    my $log_time = localtime(time);
-    my $cfg;
-    if( defined( $cfg_file) && ( length($cfg_file) > 0 )) {
-        if( -r $cfg_file ) { 
-            $cfg = Config::IniFiles->new( -file => $cfg_file ); 
-        } else { 
-            usage( "Couldn't read config file: $cfg_file \n" ); 
-        }
-    } else { 
-        $cfg = Config::IniFiles->new() ; 
-    }
-
-    foreach my $section (keys %cfg_defaults) {      # "Parse" config into values
-        foreach my $param (keys %{$cfg_defaults{ $section }}) {
-            my $pinfo = $cfg_defaults{ $section }{ $param };
-            ${@$pinfo[ 0 ]} = $cfg->val( $section, $param, @$pinfo[ 1 ] );
-        }
-    }
-
-    if(-e $log_file ) { unlink $log_file }
-    daemon_log("$log_time: config file read\n");
-}
-
-#===  FUNCTION  ================================================================
-#         NAME:  daemon_log
-#      PURPOSE:  log messages to specified logfile
-#   PARAMETERS:  $msg, $level
-#      RETURNS:  ????
-#  DESCRIPTION:  Takes a message ($msg) and append it to the logfile. The 
-#                standard log-level ($level) is 1. Messages whith higher level
-#                than the verbosity-level (defined by commandline) are printed 
-#                out to commandline. Messages with log-level lower than 2 are 
-#                not logged to logfile!
-#       THROWS:  no exceptions
-#     COMMENTS:  none
-#     SEE ALSO:  n/a
-#===============================================================================
-sub daemon_log {
-    my( $msg, $level ) = @_;
-    if(not defined $msg) { return } 
-    if(not defined $level) { $level = 1 }
-    open(LOG_HANDLE, ">>$log_file");
-    if(not defined open( LOG_HANDLE, ">>$log_file" ) ) { return }
-    chomp($msg);
-    #if( $verbose >= $level ) { print "$msg"."\n" }
-    if( $level <= 1 ) { print LOG_HANDLE $msg."\n"  }
-    if( $foreground ) { print $msg."\n" }
-    close( LOG_HANDLE );
-    }
-
-#===  FUNCTION  ================================================================
-#         NAME:  signal handler
-#      PURPOSE:  catches signals from the programm and do diffrent things 
-#                than default
-#   PARAMETERS:  none
-#      RETURNS:  none
-#  DESCRIPTION:  sighandler
-#       THROWS:  no exceptions
-#     COMMENTS:  none
-#     SEE ALSO:  n/a
-#===============================================================================
-sub sigINT {
-    my $log_time = localtime(time);
-    print "INT\n";
-    if( -p $fifo_path ) {
-        close FIFO  ;
-        unlink($fifo_path) ;
-        daemon_log( "$log_time: FIFO closed after signal INT!\n") ;
-        }
-    if(defined($ldap)) {
-        $ldap->unbind;
-    }
-    $SIG{INT} = "DEFAULT" ;
-    kill INT => $$ ;
-}
-$SIG{INT} = \&sigINT ;
-
-#===  FUNCTION  ================================================================
-#         NAME:  usage
-#      PURPOSE:  
-#   PARAMETERS:  none
-#      RETURNS:  none
-#  DESCRIPTION:  print out the usage of the program
-#       THROWS:  no exceptions
-#     COMMENTS:  none
-#     SEE ALSO:  n/a
-#===============================================================================
-sub usage {
-        my( $text, $help ) = @_;
-        $text = undef if( "h" eq $text );
-        (defined $text) && print STDERR "\n$text\n";
-        if( (defined $help && $help) || (!defined $help && !defined $text) ) {
-                print STDERR << "EOF" ;
-usage: $0 [-hvf] [-c config, -l logfile, -p pidfile]
-
-    -h        : this (help) message
-    -c <file> : config file
-    -l <file> : log file (example: /var/log/sps/sps.log)
-    -p <file> : pid file (example: /var/run/sps/sps.pid)
-    -f        : foreground (don"t fork)
-    -v        : be verbose (multiple to increase verbosity)
-EOF
-        }
-        print "\n" ;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  open_fifo
-#      PURPOSE:  
-#   PARAMETERS:  $fifo_path
-#      RETURNS:  0: FIFO couldn"t be setup, 1: FIFO setup correctly
-#  DESCRIPTION:  creates a FIFO at $fifo_path
-#       THROWS:  no exceptions
-#     COMMENTS:  none
-#     SEE ALSO:  n/a
-#===============================================================================
-sub open_fifo {
-    my ($fifo_path) = @_ ;
-    my $log_time = localtime( time );
-    if( -p $fifo_path ) {
-        daemon_log("$log_time: FIFO at $fifo_path already exists\n");
-        return 0;
-        } 
-    POSIX::mkfifo($fifo_path, 0666) or die "can't mkfifo $fifo_path: $!";
-    daemon_log( "$log_time: FIFO started at $fifo_path\n" ) ;
-    return 1;
-    }
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  add_ldap_entry
-#      PURPOSE:  adds an element to ldap-tree
-#   PARAMETERS:  
-#      RETURNS:  none
-#  DESCRIPTION:  ????
-#       THROWS:  no exceptions
-#     COMMENTS:  none
-#     SEE ALSO:  n/a
-#===============================================================================
-sub add_ldap_entry {
-    my ($ldap_tree, $ldap_base, $mac, $gotoSysStatus, $ip, $interface, $desc) = @_;
-    my $dn = "cn=$mac,ou=incoming,$ldap_base";
-    my $s_res = &search_ldap_entry($ldap_tree, $ldap_base, "(|(macAddress=$mac)(dhcpHWAddress=ethernet $mac))");
-    my $c_res = $s_res->count;
-    if($c_res == 1) {
-        daemon_log("WARNING: macAddress $mac already in LDAP", 1);
-        return;
-    } elsif($c_res > 0) {
-        daemon_log("ERROR: macAddress $mac exists $c_res times in LDAP", 1);
-        return;
-    }
-
-    # create LDAP entry 
-    my $entry = Net::LDAP::Entry->new( $dn );
-    $entry->dn($dn);
-    $entry->add("objectClass" => "goHard");
-    $entry->add("cn" => $mac);
-    $entry->add("macAddress" => $mac);
-    if(defined $gotoSysStatus) {$entry->add("gotoSysStatus" => $gotoSysStatus)}
-    if(defined $ip) {$entry->add("ipHostNumber" => $ip) }
-    #if(defined $interface) { }
-    if(defined $desc) {$entry->add("description" => $desc) }
-    
-    # submit entry to LDAP
-    my $result = $entry->update ($ldap_tree); 
-        
-    # for $result->code constants please look at Net::LDAP::Constant
-    my $log_time = localtime( time );
-    if($result->code == 68) {   # entry already exists 
-        daemon_log("WARNING: $log_time: $dn ".$result->error, 3);
-    } elsif($result->code == 0) {   # everything went fine
-        daemon_log("$log_time: add entry $dn to ldap", 1);
-    } else {  # if any other error occur
-        daemon_log("ERROR: $log_time: $dn, ".$result->code.", ".$result->error, 1);
-    }
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  change_ldap_entry
-#      PURPOSE:  ????
-#   PARAMETERS:  ????
-#      RETURNS:  ????
-#  DESCRIPTION:  ????
-#       THROWS:  no exceptions
-#     COMMENTS:  none
-#     SEE ALSO:  n/a
-#===============================================================================
-sub change_ldap_entry {
-    my ($ldap_tree, $ldap_base, $mac, $gotoSysStatus ) = @_;
-    
-    # check if ldap_entry exists or not
-    my $s_res = &search_ldap_entry($ldap_tree, $ldap_base, "(|(macAddress=$mac)(dhcpHWAddress=ethernet $mac))");
-    my $c_res = $s_res->count;
-    if($c_res == 0) {
-        daemon_log("WARNING: macAddress $mac not in LDAP", 1);
-        return;
-    } elsif($c_res > 1) {
-        daemon_log("ERROR: macAddress $mac exists $c_res times in LDAP", 1);
-        return;
-    }
-
-    my $s_res_entry = $s_res->pop_entry();
-    my $dn = $s_res_entry->dn();
-    my $result = $ldap->modify( $dn, replace => {'gotoSysStatus' => $gotoSysStatus } );
-
-    # for $result->code constants please look at Net::LDAP::Constant
-    my $log_time = localtime( time );
-    if($result->code == 32) {   # entry doesnt exists 
-        &add_ldap_entry($mac, $gotoSysStatus);
-    } elsif($result->code == 0) {   # everything went fine
-        daemon_log("$log_time: entry $dn changed successful", 1);
-    } else {  # if any other error occur
-        daemon_log("ERROR: $log_time: $dn, ".$result->code.", ".$result->error, 1);
-    }
-
-    return;
-}
-
-#===  FUNCTION  ================================================================
-#         NAME:  search_ldap_entry
-#      PURPOSE:  ????
-#   PARAMETERS:  [Net::LDAP] $ldap_tree - object of an ldap-tree
-#                string $sub_tree - dn of the subtree the search is performed
-#                string $search_string - either a string or a Net::LDAP::Filter object
-#      RETURNS:  [Net::LDAP::Search] $msg - result object of the performed search
-#  DESCRIPTION:  ????
-#       THROWS:  no exceptions
-#     COMMENTS:  none
-#     SEE ALSO:  n/a
-#===============================================================================
-sub search_ldap_entry {
-    my ($ldap_tree, $sub_tree, $search_string) = @_;
-    my $msg = $ldap_tree->search( # perform a search
-                        base   => $sub_tree,
-                        filter => $search_string,
-                      ) or daemon_log("cannot perform search at ldap: $@", 1);
-#    if(defined $msg) {
-#        print $sub_tree."\t".$search_string."\t";
-#        print $msg->count."\n";
-#        foreach my $entry ($msg->entries) { $entry->dump; };
-#    }
-
-    return $msg;
-}
-
-
-
-#========= MAIN = main ========================================================
-daemon_log( "####### START DAEMON ######\n", 1 );
-&check_cmdline_param ;
-&check_pid;
-&open_fifo($fifo_path);
-
-# Just fork, if we"re not in foreground mode
-if( ! $foreground ) { $pid = fork(); }
-else { $pid = $$; }
-
-# Do something useful - put our PID into the pid_file
-if( 0 != $pid ) {
-    open( LOCK_FILE, ">$pid_file" );
-    print LOCK_FILE "$pid\n";
-    close( LOCK_FILE );
-    if( !$foreground ) { exit( 0 ) };
-}
-
-
-if( not -p $fifo_path ) { die "fifo file disappeared\n" }
-sysopen(FIFO, $fifo_path, O_RDONLY) or die "can't read from $fifo_path: $!" ;
-
-while( 1 ) {
-    # checke alle prozesse im hash daemon_children ob sie noch aktiv sind, wenn
-    # nicht, dann entferne prozess aus hash
-    while( (my $key, my $val) = each( %daemon_children) ) {
-        my $status = waitpid( $key, &WNOHANG) ;
-        if( $status == -1 ) { 
-            delete $daemon_children{$key} ; 
-            daemon_log("childprocess finished: $key", 3) ;
-        }
-    }
-
-    # ist die max_process anzahl von prozesskindern erreicht, dann warte und 
-    # prüfe erneut, ob in der zwischenzeit prozesse fertig geworden sind
-    if( keys( %daemon_children ) >= $max_process ) { 
-        sleep($max_process_timeout) ;
-        next ;
-    }
-
-    my $msg = <FIFO>;
-    if( not defined( $msg )) { next ; }
-    
-    chomp( $msg );
-    if( length( $msg ) == 0 ) { next ; }
-
-    my $forked_pid = fork();
-#=== PARENT = parent ==========================================================
-    if ( $forked_pid != 0 ) { 
-        daemon_log("childprocess forked: $forked_pid", 3) ;
-        $daemon_children{$forked_pid} = 0 ;
-    }
-#=== CHILD = child ============================================================
-    else {
-        # parse the incoming message from arp, split the message and return 
-        # the values in an array. not defined values are set to "none" 
-        #my ($mac, $ip, $interface, $arp_sig, $desc) = &parse_input( $msg ) ;
-        daemon_log( "childprocess read from arp: $fifo_path\nline: $msg", 3);
-        my ($mac, $ip, $interface, $arp_sig, $desc) = split('\s', $msg, 5);
-
-        # create connection to LDAP
-        $ldap = Net::LDAP->new( "localhost" ) or die "$@";
-        $ldap->bind($bind_phrase,
-                    password => $password,
-                    ) ;
-        
-        switch($arp_sig) {
-            case 0 {&change_ldap_entry($ldap, $ldap_base, 
-                                      $mac, "ip-changed",
-                                      )} 
-            case 1 {&change_ldap_entry($ldap, $ldap_base, 
-                                      $mac, "mac-not-whitelisted",
-                                      )}
-            case 2 {&change_ldap_entry($ldap, $ldap_base, 
-                                      $mac, "mac-in-blacklist",
-                                      )}
-            case 3 {&add_ldap_entry($ldap, $ldap_base, 
-                                   $mac, "new-mac-address", $ip, 
-                                   $interface, $desc, 
-                                   )}
-            case 4 {&change_ldap_entry($ldap, $ldap_base, 
-                                      $mac, "unauthorized-arp-request",
-                                      )}
-            case 5 {&change_ldap_entry($ldap, $ldap_base, 
-                                      $mac, "abusive-number-of-arp-requests",
-                                      )}
-            case 6 {&change_ldap_entry($ldap, $ldap_base, 
-                                      $mac, "ether-and-arp-mac-differs",
-                                      )}
-            case 7 {&change_ldap_entry($ldap, $ldap_base, 
-                                      $mac, "flood-detected",
-                                      )}
-            case 8 {&add_ldap_entry($ldap, $ldap_base, 
-                                   $mac, $ip, "new-system",
-                                   )}
-            case 9 {&change_ldap_entry($ldap, $ldap_base, 
-                                      $mac, "mac-changed",
-                                      )}
-        }
-
-
-        # ldap search
-#        my $base_phrase = "dc=gonicus,dc=de";
-#        my $filter_phrase = "cn=keinesorge";
-#        my $attrs_phrase = "cn macAdress";
-#        my $msg_search = $ldap->search( base   => $base_phrase,
-#                                        filter => $filter_phrase,
-#                                        attrs => $attrs_phrase,
-#                                        );
-#        $msg_search->code && die $msg_search->error;
-#        
-#        my @entries = $msg_search->entries;
-#        my $max = $msg_search->count;
-#        print "anzahl der entries: $max\n";
-#        my $i;
-#        for ( $i = 0 ; $i < $max ; $i++ ) {
-#            my $entry = $msg_search->entry ( $i );
-#            foreach my $attr ( $entry->attributes ) {
-#                if( not $attr eq "cn") {
-#                    next;
-#                }
-#                print join( "\n ", $attr, $entry->get_value( $attr ) ), "\n\n";
-#            }
-#        }
-
-        # ldap add
-       
-        
-        $ldap->unbind;
-        exit;
-    }
-
-}
-
-
diff --git a/contrib/daemon/arp-handler-d.cfg b/contrib/daemon/arp-handler-d.cfg
deleted file mode 100644 (file)
index 36c24a3..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-[Allgemein]
-timeout   = 1000 
-mailto    = root@localhost
-mailfrom  = gosa-sd@localhost
-user      = rettenbe
-group     = usr
-fifo_path = /home/rettenbe/gonicus/projekte/gosa-trunk/contrib/daemon/fifo
-log_file  = /home/rettenbe/gonicus/projekte/gosa-trunk/contrib/daemon/gosa-sd.log
-pid_file  = /home/rettenbe/gonicus/projekte/gosa-trunk/contrib/daemon/gosa-sd.pid
-loglevel  = 1
-
-[LDAP]
-bind     = cn=ldapadmin,dc=gonicus,dc=de 
-password = tester
diff --git a/contrib/daemon/debian/README.debian b/contrib/daemon/debian/README.debian
deleted file mode 100644 (file)
index 100bd2d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-README.Debian for GOto 3.0
---------------------------
-
-* Configuring GOto 3.0
-
-You need a proper LDAP/FAI/GOsa setup to make this run. More
-text will follow later. Sorry.
-
-----
-Cajus Pollmeier <cajus@debian.org>  Fri 02 Jun 2006 16:23:50 +0200
-
diff --git a/contrib/daemon/debian/changelog b/contrib/daemon/debian/changelog
deleted file mode 100644 (file)
index 3367299..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-gosa-sd (1.0-1) unstable; urgency=low
-
-  * Initial release
-
- -- Cajus Pollmeier <cajus@debian.org>  Fri,  7 Dec 2007 11:37:45 +0100
-
diff --git a/contrib/daemon/debian/compat b/contrib/daemon/debian/compat
deleted file mode 100644 (file)
index 7ed6ff8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-5
diff --git a/contrib/daemon/debian/control b/contrib/daemon/debian/control
deleted file mode 100644 (file)
index b7b873d..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-Source: gosa-si
-Section: utils
-Priority: optional
-Maintainer: Cajus Pollmeier <cajus@debian.org>
-Standards-Version: 3.7.2.2
-Build-Depends: debhelper(>= 4.2.32), dpatch
-
-Package: gosa-si-common
-Architecture: any
-Depends: libconfig-inifiles-perl, libcrypt-rijndael-perl, libxml-simple-perl, libipc-shareable-perl, libdata-dumper-simple-perl, libmime-perl
-Suggests: gosa-si-daemon, gosa-si-client
-Description: GOsa support infrastructure
- This package provides common library functionality used by the
- infrastructure server and client packages.
- .
- GOsa is a combination of system-administrator and end-user web
- interface, designed to handle LDAP based setups.
-
-Package: gosa-si-daemon
-Architecture: any
-Depends: gosa-si-common
-Suggests: gosa
-Description: GOsa support infrastructure daemon
- This package provides everything you need in order to deploy a simple
- or distributed GOsa support infrastructure. It can be used to trigger
- certain actions or retrieve information from clients.
- .
- GOsa is a combination of system-administrator and end-user web
- interface, designed to handle LDAP based setups.
-
-Package: gosa-si-client
-Architecture: any
-Depends: gosa-si-common
-Suggests: gosa
-Description: GOsa support infrastructure client
- This package lets you join to a GOsa support infrastructure as a
- client in order to provide information or to act on events.
- .
- GOsa is a combination of system-administrator and end-user web
- interface, designed to handle LDAP based setups.
diff --git a/contrib/daemon/debian/copyright b/contrib/daemon/debian/copyright
deleted file mode 100644 (file)
index d7463ef..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-This package was debianized by Cajus Pollmeier
-<cajus@debian.org> on Mon, 25 Jun 2007 12:57:35 +0100.
-
-Copyright: GPL2
-
-This code is released under the terms of the GPLv2 license.
-
-See /usr/share/common-licenses/GPL-2 for the full license.
diff --git a/contrib/daemon/debian/default b/contrib/daemon/debian/default
deleted file mode 100644 (file)
index 10df929..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# /etc/default/gosa-si - configure the init script
-START_BUS=0
diff --git a/contrib/daemon/debian/gosa-si-client.dirs b/contrib/daemon/debian/gosa-si-client.dirs
deleted file mode 100644 (file)
index 763e43a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-usr/share/ltsp/plugins/ltsp-build-client/common
-usr/share/ltsp/scripts
-usr/sbin
-etc/default
diff --git a/contrib/daemon/debian/gosa-si-client.install b/contrib/daemon/debian/gosa-si-client.install
deleted file mode 100644 (file)
index 8155a9c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-debian/goto                     etc/default
-build-goto-client               usr/sbin
-plugins/001-ltsp-addon-packages usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/020-ssh-pubkey-login    usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/001-goto-ldap-packages  usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/001-sane-packages       usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/020-nx-client           usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/010-goto-ldap-files     usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/999-goto-ldap-final     usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/001-snmp-packages       usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/030-late-packages-goto  usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/000-goto-ldap-vars      usr/share/ltsp/plugins/ltsp-build-client/common
diff --git a/contrib/daemon/debian/gosa-si-common.dirs b/contrib/daemon/debian/gosa-si-common.dirs
deleted file mode 100644 (file)
index 763e43a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-usr/share/ltsp/plugins/ltsp-build-client/common
-usr/share/ltsp/scripts
-usr/sbin
-etc/default
diff --git a/contrib/daemon/debian/gosa-si-common.install b/contrib/daemon/debian/gosa-si-common.install
deleted file mode 100644 (file)
index 8155a9c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-debian/goto                     etc/default
-build-goto-client               usr/sbin
-plugins/001-ltsp-addon-packages usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/020-ssh-pubkey-login    usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/001-goto-ldap-packages  usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/001-sane-packages       usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/020-nx-client           usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/010-goto-ldap-files     usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/999-goto-ldap-final     usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/001-snmp-packages       usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/030-late-packages-goto  usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/000-goto-ldap-vars      usr/share/ltsp/plugins/ltsp-build-client/common
diff --git a/contrib/daemon/debian/gosa-si-server.dirs b/contrib/daemon/debian/gosa-si-server.dirs
deleted file mode 100644 (file)
index 763e43a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-usr/share/ltsp/plugins/ltsp-build-client/common
-usr/share/ltsp/scripts
-usr/sbin
-etc/default
diff --git a/contrib/daemon/debian/gosa-si-server.init b/contrib/daemon/debian/gosa-si-server.init
deleted file mode 100755 (executable)
index 26fb1cb..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/bin/sh
-# Start/stop the GOsa support daemon infrastructure.
-#
-### BEGIN INIT INFO
-# Provides:          gosa-si
-# Required-Start:    $syslog $time
-# Required-Stop:     $syslog $time
-# Default-Start:     2 3 4 5
-# Default-Stop:      0 1 6
-# Short-Description: GOsa message bus and server component
-# Description:       gosa-si establishes the communication between a couple of
-#                    GOsa hosting servers and optionally clients to do event
-#                    signaling for all communication partners.
-### END INIT INFO
-
-# Sanity checks
-test -f /usr/sbin/gosa-si-server || exit 0
-test -f /usr/sbin/gosa-si-bus || exit 0
-
-# Load defaults
-START_BUS=0
-[ -r /etc/default/gosa-si ] && . /etc/default/gosa-si
-
-# Load LSB support functions
-. /lib/lsb/init-functions
-
-
-start_bus() {
-       start-stop-daemon --start --quiet --pidfile /var/run/gosa-si-bus.pid --name gosa-si-bus --startas /usr/sbin/gosa-si-bus
-}
-
-
-start_server() {
-       start-stop-daemon --start --quiet --pidfile /var/run/gosa-si-server.pid --name gosa-si-server --startas /usr/sbin/gosa-si-server -- $1
-}
-
-
-stop_bus() {
-       start-stop-daemon --stop --retry 5 --quiet --pidfile /var/run/gosa-si-bus.pid --name gosa-si-bus
-}
-
-
-stop_server() {
-       start-stop-daemon --stop --retry 5 --quiet --pidfile /var/run/gosa-si-server.pid --name gosa-si-server
-}
-
-
-case "$1" in
-start)  log_daemon_msg "Starting GOsa support infrastructure"
-       if [ "$START_BUS" == "1" ]; then
-               log_progress_msg "bus"
-               start_bus
-               log_progress_msg "daemon"
-               start_server
-       else
-               log_progress_msg "daemon"
-               start_server --no-bus
-       fi
-        log_end_msg $?
-       ;;
-stop)   log_daemon_msg "Stopping GOsa support infrastructure"
-       if [ "$START_BUS" == "1" ]; then
-               log_progress_msg "daemon"
-               stop_server
-               log_progress_msg "bus"
-               stop_bus
-       else
-               log_progress_msg "daemon"
-               stop_server
-       fi
-        log_end_msg $?
-        ;;
-reload|force-reload|restart) log_daemon_msg "Restarting GOsa support infrastructure" 
-       if [ "$START_BUS" == "1" ]; then
-               stop_server
-               stop_bus
-               start_bus
-               start_server --no-bus
-               log_progress_msg "done"
-       else
-               stop_server
-               start_server --no-bus
-               log_progress_msg "done"
-       fi
-        log_end_msg $?
-        ;;
-*)     log_action_msg "Usage: /etc/init.d/gosa-si {start|stop|restart|reload|force-reload}"
-        exit 2
-        ;;
-esac
-exit 0
diff --git a/contrib/daemon/debian/gosa-si-server.install b/contrib/daemon/debian/gosa-si-server.install
deleted file mode 100644 (file)
index 8155a9c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-debian/goto                     etc/default
-build-goto-client               usr/sbin
-plugins/001-ltsp-addon-packages usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/020-ssh-pubkey-login    usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/001-goto-ldap-packages  usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/001-sane-packages       usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/020-nx-client           usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/010-goto-ldap-files     usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/999-goto-ldap-final     usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/001-snmp-packages       usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/030-late-packages-goto  usr/share/ltsp/plugins/ltsp-build-client/common
-plugins/000-goto-ldap-vars      usr/share/ltsp/plugins/ltsp-build-client/common
diff --git a/contrib/daemon/debian/rules b/contrib/daemon/debian/rules
deleted file mode 100755 (executable)
index 78cd0aa..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/make -f
-# Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess.
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-build: patch 
-       #********************************************************
-       #*  Building ltsp-goto into a Debian/GNU Linux Package  *
-       #*                    please stand by                   *
-       #********************************************************
-
-clean: clean-patched unpatch
-clean-patched:
-       dh_testdir
-       rm -f install-stamp 
-       -rm -f debian/files
-       -rm -rf debian/tmp
-       -rm -f debian/substvars
-       dh_clean
-
-unpatch:
-       dpatch deapply-all
-       rm -rf patch-stamp debian/patched
-
-install: install-stamp
-install-stamp: 
-       dh_testdir
-       dh_testroot
-       dh_clean -k
-       dh_installdirs
-
-       # Create a copy, remove svn stuff
-       -mkdir debian/tmp
-       -for i in `ls | grep -v debian`; do \
-               cp -R $$i debian/tmp ; \
-       done
-       -find debian/tmp -name '*.svn' -type d -exec rm -rf {} \; 2> /dev/null
-
-       touch install-stamp
-
-patch: patch-stamp
-patch-stamp:
-       dpatch apply-all
-       dpatch cat-all >patch-stamp
-
-binary-indep: install
-       dh_testdir
-       dh_testroot
-       
-       dh_install
-       dh_installdocs 
-       dh_installcron
-       dh_installexamples
-       dh_installchangelogs
-       #dh_installdebconf
-       #dh_installcron -p goto-agents-printmanager
-       dh_link
-       dh_strip
-       dh_compress
-       dh_fixperms 
-       dh_perl
-       dh_installdeb
-       dh_shlibdeps
-       
-       dh_gencontrol
-       dh_md5sums
-       dh_builddeb
-
-source diff:                                                                  
-       @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false
-
-binary: binary-indep 
-.PHONY: build install clean binary-indep binary
-
-binary-arch:
-
diff --git a/contrib/daemon/gosa-si-bus b/contrib/daemon/gosa-si-bus
deleted file mode 100755 (executable)
index a56a38e..0000000
+++ /dev/null
@@ -1,1183 +0,0 @@
-#!/usr/bin/perl
-#===============================================================================
-#
-#         FILE:  gosa-server
-#
-#        USAGE:  ./gosa-server
-#
-#  DESCRIPTION:
-#
-#      OPTIONS:  ---
-# REQUIREMENTS:  ---
-#         BUGS:  ---
-#        NOTES: 
-#       AUTHOR:   (Andreas Rettenberger), <rettenberger@gonicus.de>
-#      COMPANY:
-#      VERSION:  1.0
-#      CREATED:  12.09.2007 08:54:41 CEST
-#     REVISION:  ---
-#===============================================================================
-
-use strict;
-use warnings;
-use Getopt::Long;
-use Config::IniFiles;
-use POSIX;
-use Time::HiRes qw( gettimeofday );
-
-use IO::Socket::INET;
-use Crypt::Rijndael;
-use MIME::Base64;
-use Digest::MD5  qw(md5 md5_hex md5_base64);
-use XML::Simple;
-use Data::Dumper;
-use Sys::Syslog qw( :DEFAULT setlogsock);
-use Cwd;
-use File::Spec;
-use IPC::Shareable qw( :lock);
-IPC::Shareable->clean_up_all;
-
-my ($cfg_file, $default_cfg_file, %cfg_defaults, $foreground, $verbose);
-my ($bus_activ, $bus_passwd, $bus_ip, $bus_port, $bus_address, $bus, $bus_mac_address);
-my ($pid_file, $procid, $pid, $log_file, $my_own_address);
-my (%free_child, %busy_child, $child_max, $child_min, %child_alive_time, $child_timeout);
-my ($xml, $bus_cipher, $known_daemons, $shmkh);
-
-$foreground = 0 ;
-$known_daemons = {};
-$shmkh = tie($known_daemons, 'IPC::Shareable', undef, {create => 1, 
-                                                            exclusive => 1, 
-                                                            mode => 0666, 
-                                                            destroy => 1,
-                                                            });
-%cfg_defaults =
-("general" =>
-    {"log_file" => [\$log_file, "/var/run/".$0.".log"],
-    "pid_file" => [\$pid_file, "/var/run/".$0.".pid"],
-    "child_max" => [\$child_max, 10],
-    "child_min" => [\$child_min, 3],
-    "child_timeout" => [\$child_timeout, 180],
-
-    },
-"bus" =>
-    {"bus_activ" => [\$bus_activ, "on"],
-    "bus_passwd" => [\$bus_passwd, ""],
-    "bus_port" => [\$bus_port, "20080"],
-    }
-    );
-
-#===  FUNCTION  ================================================================
-#         NAME:  read_configfile
-#   PARAMETERS:  cfg_file - string - 
-#      RETURNS:  nothing 
-#  DESCRIPTION:  read cfg_file and set variables
-#===============================================================================
-sub read_configfile {
-    my $cfg;
-    if( defined( $cfg_file) && ( length($cfg_file) > 0 )) {
-        if( -r $cfg_file ) {
-            $cfg = Config::IniFiles->new( -file => $cfg_file );
-        } else {
-            print STDERR "Couldn't read config file!";
-        }
-    } else {
-        $cfg = Config::IniFiles->new() ;
-    }
-    foreach my $section (keys %cfg_defaults) {
-        foreach my $param (keys %{$cfg_defaults{ $section }}) {
-            my $pinfo = $cfg_defaults{ $section }{ $param };
-            ${@$pinfo[ 0 ]} = $cfg->val( $section, $param, @$pinfo[ 1 ] );
-        }
-    }
-}
-
-#===  FUNCTION  ================================================================
-#         NAME:  logging
-#   PARAMETERS:  level - string - default 'info' 
-#                msg - string - 
-#                facility - string - default 'LOG_DAEMON' 
-#      RETURNS:  nothing
-#  DESCRIPTION:  function for logging
-#===============================================================================
-sub daemon_log {
-    my( $msg, $level ) = @_;
-    if(not defined $msg) { return }
-    if(not defined $level) { $level = 1 }
-    if(defined $log_file){
-        open(LOG_HANDLE, ">>$log_file");
-        if(not defined open( LOG_HANDLE, ">>$log_file" )) { 
-            print STDERR "cannot open $log_file: $!";
-            return }
-        chomp($msg);
-        if($level <= $verbose){
-            print LOG_HANDLE $msg."\n";
-            if(defined $foreground) { print $msg."\n" }
-        }
-    }
-    close( LOG_HANDLE );
-#    my ($msg, $level, $facility) = @_;
-#    if(not defined $msg) {return}
-#    if(not defined $level) {$level = "info"}
-#    if(not defined $facility) {$facility = "LOG_DAEMON"}
-#    openlog($0, "pid,cons,", $facility);
-#    syslog($level, $msg);
-#    closelog;
-#    return;
-}
-
-#===  FUNCTION  ================================================================
-#         NAME:  check_cmdline_param
-#   PARAMETERS:  nothing
-#      RETURNS:  nothing
-#  DESCRIPTION:  validates commandline parameter 
-#===============================================================================
-sub check_cmdline_param () {
-    my $err_config;
-    my $err_counter = 0;
-    if( not defined( $cfg_file)) {
-        my $cwd = getcwd;
-        my $name = "/etc/gosa/gosa-si-bus.conf";
-        $cfg_file = File::Spec->catfile( $cwd, $name );
-        print STDERR "no conf file specified\n   try to use default: $cfg_file\n";
-    }
-    if( $err_counter > 0 ) {
-        &usage( "", 1 );
-        if( defined( $err_config)) { print STDERR "$err_config\n"}
-        print STDERR "\n";
-        exit( -1 );
-    }
-}
-
-#===  FUNCTION  ================================================================
-#         NAME:  check_pid
-#   PARAMETERS:  nothing
-#      RETURNS:  nothing
-#  DESCRIPTION:  handels pid processing
-#===============================================================================
-sub check_pid {
-    $pid = -1;
-    # Check, if we are already running
-    if( open(LOCK_FILE, "<$pid_file") ) {
-        $pid = <LOCK_FILE>;
-        if( defined $pid ) {
-            chomp( $pid );
-            if( -f "/proc/$pid/stat" ) {
-                my($stat) = `cat /proc/$pid/stat` =~ m/$pid \((.+)\).*/;
-                if( $0 eq $stat ) {
-                    close( LOCK_FILE );
-                    exit -1;
-                }
-            }
-        }
-        close( LOCK_FILE );
-        unlink( $pid_file );
-    }
-
-    # create a syslog msg if it is not to possible to open PID file
-    if (not sysopen(LOCK_FILE, $pid_file, O_WRONLY|O_CREAT|O_EXCL, 0644)) {
-        my($msg) = "Couldn't obtain lockfile '$pid_file' ";
-        if (open(LOCK_FILE, '<', $pid_file)
-                && ($pid = <LOCK_FILE>))
-        {
-            chomp($pid);
-            $msg .= "(PID $pid)\n";
-        } else {
-            $msg .= "(unable to read PID)\n";
-        }
-        if( ! ($foreground) ) {
-            openlog( $0, "cons,pid", "daemon" );
-            syslog( "warning", $msg );
-            closelog();
-        }
-        else {
-            print( STDERR " $msg " );
-        }
-        exit( -1 );
-    }
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  usage
-#   PARAMETERS:  nothing
-#      RETURNS:  nothing
-#  DESCRIPTION:  print out usage text to STDERR
-#===============================================================================
-sub usage {
-    print STDERR << "EOF" ;
-usage: $0 [-hvf] [-c config]
-
-    -h        : this (help) message
-    -c <file> : config file
-    -f        : foreground, process will not be forked to background
-    -v        : be verbose (multiple to increase verbosity)
-EOF
-    print "\n" ;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  sig_int_handler
-#   PARAMETERS:  signal - string - signal arose from system
-#      RETURNS:  noting
-#  DESCRIPTION:  handels tasks to be done befor signal becomes active
-#===============================================================================
-sub sig_int_handler {
-    my ($signal) = @_;
-    if($bus){
-        close($bus);
-        print "$bus closed\n";
-    }
-    print "$signal\n";
-    IPC::Shareable->clean_up;
-    exit(1);
-}
-$SIG{INT} = \&sig_int_handler;
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  get_ip_and_mac 
-#   PARAMETERS:  nothing
-#      RETURNS:  (ip, mac) 
-#  DESCRIPTION:  executes /sbin/ifconfig and parses the output, the first occurence 
-#                of a inet address is returned as well as the mac address in the line
-#                above the inet address
-#===============================================================================
-sub get_ip_and_mac {
-    my $ip = "0.0.0.0.0"; # Defualt-IP
-    my $mac_address = "00:00:00:00:00:00";  # Default-MAC
-    my @ifconfig = qx(/sbin/ifconfig);
-    foreach(@ifconfig) {
-        if (/Hardware Adresse (\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2})/) {
-            $mac_address = "$1:$2:$3:$4:$5:$6";
-            next;
-        }
-        if (/inet Adresse:(\d+).(\d+).(\d+).(\d+)/) {
-            $ip = "$1.$2.$3.$4";
-            last;
-        }
-    }
-    return ($ip, $mac_address);
-}
-
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  activating_child
-#   PARAMETERS:  msg - string - incoming message
-#                host - string - host from which the incomming message comes
-#      RETURNS:  nothing
-#  DESCRIPTION:  handels the distribution of incoming messages to working childs
-#===============================================================================
-sub activating_child {
-    my ($msg, $host) = @_;
-    my $child = &get_processing_child();
-    my $pipe_wr = $$child{'pipe_wr'};
-    daemon_log("activating: childpid: $$child{'pid'}", 5);
-    print $pipe_wr $msg.".".$host."\n";
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  get_processing_child
-#   PARAMETERS:  nothing
-#      RETURNS:  child - hash - holding the process id and the references to the pipe
-#                               handles pipe_wr and pipe_rd
-#  DESCRIPTION:  handels the forking, reactivating and keeping alive tasks
-#===============================================================================
-sub get_processing_child {
-    my $child;
-    # checking %busy_child{pipe_wr} if msg is 'done', then set child from busy to free
-    while(my ($key, $val) = each(%busy_child)) {
-        # check wether process still exists
-        my $exitus_pid = waitpid($key, WNOHANG);
-        if($exitus_pid != 0) {
-            delete $busy_child{$key};
-            daemon_log( "prozess:$key wurde aus busy_child entfernt\n", 5);
-            next;
-        }
-
-        # check wether process sitll works
-        my $fh = $$val{'pipe_rd'};
-        $fh->blocking(0); 
-        my $child_answer;
-        if(not $child_answer = <$fh>) { next }
-        chomp($child_answer);
-        if($child_answer eq "done") {
-            delete $busy_child{$key};
-            $free_child{$key} = $val;
-        }
-    }
-
-    while(my ($key, $val) = each(%free_child)) {
-        my $exitus_pid = waitpid($key, WNOHANG);
-        if($exitus_pid != 0) {
-            delete $free_child{$key};
-            daemon_log( "prozess:$key wurde aus free_child entfernt\n", 5);
-        }
-        daemon_log("free child:$key\n", 5);
-    }
-    # check @free_child and @busy_child
-    my $free_len = scalar(keys(%free_child));
-    my $busy_len = scalar(keys(%busy_child));
-    daemon_log("free children $free_len, busy children $busy_len\n",5);
-    
-    # if there is a free child, let the child work 
-    if($free_len > 0){
-        my @keys = keys(%free_child);
-        $child = $free_child{$keys[0]};
-        if(defined $child) {
-            $busy_child{$$child{'pid'}} = $child ; 
-            delete $free_child{$$child{'pid'}};          
-        }
-        return $child;
-    }
-    
-    # no free child, try to fork another one 
-    if($free_len + $busy_len < $child_max) {
-                
-        daemon_log("not enough children, create a new one\n",5);
-
-        # New pipes for communication
-        my( $PARENT_wr, $PARENT_rd );
-        my( $CHILD_wr, $CHILD_rd );
-        pipe( $CHILD_rd,  $PARENT_wr );
-        pipe( $PARENT_rd, $CHILD_wr  );
-        $PARENT_wr->autoflush(1);
-        $CHILD_wr->autoflush(1);
-
-        ############
-        # fork child
-        ############
-        my $child_pid = fork();
-        
-        #CHILD
-        if($child_pid == 0) {
-            # Close unused pipes
-            close( $CHILD_rd );
-            close( $CHILD_wr );
-            while( 1 ) {
-                my $rbits = "";
-                vec( $rbits, fileno $PARENT_rd , 1 ) = 1;
-
-                # waiting child_timeout for jobs to do
-                my $nf = select($rbits, undef, undef, $child_timeout);
-                if($nf < 0 ) {
-                    # if $nf < 1, error handling
-                    die "select(): $!\n";
-                } elsif (! $nf) {
-                    # if already child_min childs are alive, then leave loop
-                    $free_len = scalar(keys(%free_child));
-                    $busy_len = scalar(keys(%busy_child));
-                    if($free_len + $busy_len >= $child_min) {
-                        last;
-                    } else {
-                        redo;
-                    }
-                } 
-
-                # a job for a child arise
-                if ( vec $rbits, fileno $PARENT_rd, 1 ) {
-                    # read everything from pipe
-                    my $msg = "";
-                    $PARENT_rd->blocking(0);
-                    while(1) {
-                        my $read = <$PARENT_rd>;
-                        if(not defined $read) { last}
-                        $msg .= $read;
-                    }
-
-                    # forward the job msg to another function
-                    &process_incoming_msg($msg);
-                    daemon_log("processing of msg finished", 5);
-
-                    # important!!! wait until child says 'done', until then child is set from busy to free
-                    print $PARENT_wr "done";
-                    redo;
-                }
-            }
-            # childs leaving the loop are allowed to die
-            exit(0);
-
-        #PARENT
-        } else {
-            # Close unused pipes
-            close( $PARENT_rd );
-            close( $PARENT_wr );
-            # add child to child alive hash
-            my %child_hash = (
-                    'pid' => $child_pid,
-                    'pipe_wr' => $CHILD_wr,
-                    'pipe_rd' => $CHILD_rd,
-                    );
-
-            $child = \%child_hash;
-            $busy_child{$$child{'pid'}} = $child;
-            return $child;
-        }
-    }
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  process_incoming_msg
-#   PARAMETERS:  crypted_msg - string - incoming crypted message
-#      RETURNS:  nothing
-#  DESCRIPTION:  handels the proceeded distribution to the appropriated functions
-#===============================================================================
-sub process_incoming_msg {
-    my ($crypted_msg) = @_;
-    if(not defined $crypted_msg) {
-        daemon_log("function 'process_incoming_msg': got no msg", 7);
-        return;
-    }
-    $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
-    $crypted_msg = $1;
-    my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
-
-    daemon_log("msg from host:\n\t$host", 1);
-    daemon_log("crypted_msg:\n\t$crypted_msg", 7);
-
-    my @valid_keys;
-    my @daemon_keys = keys %$known_daemons;
-    foreach my $daemon_key (@daemon_keys) {    
-        if($daemon_key =~ "^$daemon_key") {
-            push(@valid_keys, $daemon_key);
-        }
-    }
-
-    my $l = @valid_keys;
-    daemon_log("number of valid daemons: $l\n", 7);
-
-    my ($msg, $msg_hash);
-    my $msg_flag = 0;    
-
-    # collect addresses from possible incoming clients
-    foreach my $host_key (@valid_keys) {
-        eval{
-            daemon_log( "daemon: $host_key\n", 7);
-            my $key_passwd = $known_daemons->{$host_key}->{passwd};
-            daemon_log("daemon_passwd: $key_passwd\n", 7);
-            my $key_cipher = &create_ciphering($key_passwd);
-            $msg = &decrypt_msg($crypted_msg, $key_cipher);
-            daemon_log("daemon decrypted msg:$msg", 7);
-            $msg_hash = $xml->XMLin($msg, ForceArray=>1);
-        };
-        if($@) {
-            daemon_log("msg processing raise error", 7);
-            daemon_log("error string: $@", 7);
-            $msg_flag += 1;
-        } else {
-            last;
-        }
-    } 
-    
-    if($msg_flag >= $l)  {
-        daemon_log("\nERROR: do not understand the message:\n$msg" , 1);
-        return;
-    }
-
-    my $header = &get_content_from_xml_hash($msg_hash, "header");
-    my $target = &get_content_from_xml_hash($msg_hash, "target");
-
-    daemon_log("header from msg:\n\t$header", 1);
-    daemon_log("msg to process:\n\t$msg", 5);
-    daemon_log("msg is for: \n\t$target", 7);
-
-    if($target eq $bus_address) {
-        # msg is for bus
-        if($header eq 'here_i_am'){ &here_i_am($msg_hash)}
-        elsif($header eq 'confirm_new_passwd'){ &confirm_new_passwd($msg_hash)}
-        elsif($header eq 'got_ping') { &got_ping($msg_hash)} 
-        elsif($header eq 'ping') { &ping($msg_hash)}
-        elsif($header eq 'who_has') { &who_has($msg_hash)}
-        elsif($header eq 'new_client') { &new_client($msg_hash)}
-        elsif($header eq 'delete_client') { &delete_client($msg_hash)}
-    } else {
-        # msg is for any other server
-        my @targets = @{$msg_hash->{target}};
-        my $len_targets = @targets;
-    
-        if ($len_targets == 0){
-            # no targets specified
-
-            daemon_log("ERROR: no target specified for msg $header", 1);
-
-        } elsif ($targets[0] eq "*"){
-            # all deamons in known_daemons are targets
-
-            my $target = $targets[0];
-            my $source = @{$msg_hash->{source}}[0];
-            my @target_addresses = keys(%$known_daemons);
-            foreach my $target_address (@target_addresses) {
-                if ($target_address eq $source) { next; }
-                if ($target_address eq $bus_address) { next ; }
-                $msg_hash->{target} = [$target_address];
-                &send_msg_hash2address($msg_hash, $target_address);
-            }
-
-        } else {
-            # a list of targets is specified            
-            
-            my $target_address;
-            foreach $target_address (@targets) {
-                if (exists $known_daemons->{$target_address}) {
-                    &send_msg_hash2address($msg_hash, $target_address);
-                } else { 
-                    my @daemon_addresses = keys %$known_daemons;
-                    my $daemon_address;
-                    foreach $daemon_address (@daemon_addresses) {
-                        if (exists $known_daemons->{$daemon_address}->{clients}->{$target_address}) {
-                            my $header = &get_content_from_xml_hash($msg_hash, "header");
-                            &send_msg_hash2address($msg_hash, $daemon_address);
-                            daemon_log("bus forwards msg $header for client $target_address to server $daemon_address", 3);
-                            last;
-                        }
-                    }
-
-                }
-            }
-        }
-    }
-
-    &print_known_daemons_hash();
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  get_content_of_known_daemons
-#   PARAMETERS:
-#      RETURNS:
-#  DESCRIPTION:
-#===============================================================================
-#sub get_content_of_known_daemons {
-#    my ($host, $content) = @_;
-#    return;
-#}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_passwd
-#   PARAMETERS:  nothing
-#      RETURNS:  new_passwd - string 
-#  DESCRIPTION:  creates a 32 bit long random passwd out of "a".."z","A".."Z",0..9
-#===============================================================================
-sub create_passwd {
-    my $new_passwd = "";
-    for(my $i=0; $i<31; $i++) {
-        $new_passwd .= ("a".."z","A".."Z",0..9)[int(rand(62))]
-    }
-    return $new_passwd;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_ciphering
-#   PARAMETERS:  passwd - string - used to create ciphering
-#      RETURNS:  cipher - object 
-#  DESCRIPTION:  creates a Crypt::Rijndael::MODE_CBC object with passwd as key
-#===============================================================================
-sub create_ciphering {
-    my ($passwd) = @_;
-    $passwd = substr(md5_hex("$passwd") x 32, 0, 32);
-    my $iv = substr(md5_hex('GONICUS GmbH'),0, 16);
-
-    #daemon_log("iv: $iv", 7);
-    #daemon_log("key: $passwd", 7);
-    my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC());
-    $my_cipher->set_iv($iv);
-    return $my_cipher;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  encrypt_msg
-#   PARAMETERS:  msg - string - message to encrypt
-#                my_cipher - ref - reference to a Crypt::Rijndael object
-#      RETURNS:  crypted_msg - string - crypted message
-#  DESCRIPTION:  crypts the incoming message with the Crypt::Rijndael module
-#===============================================================================
-sub encrypt_msg {
-    my ($msg, $my_cipher) = @_;
-    if(not defined $my_cipher) { print "no cipher object\n"; }
-    $msg = "\0"x(16-length($msg)%16).$msg;
-    my $crypted_msg = $my_cipher->encrypt($msg);
-    chomp($crypted_msg = &encode_base64($crypted_msg));
-    return $crypted_msg;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  decrypt_msg
-#   PARAMETERS:  crypted_msg - string - message to decrypt
-#                my_cipher - ref - reference to a Crypt::Rijndael object
-#      RETURNS:  msg - string - decrypted message
-#  DESCRIPTION:  decrypts the incoming message with the Crypt::Rijndael module
-#===============================================================================
-sub decrypt_msg {
-    my ($crypted_msg, $my_cipher) = @_ ;
-    $crypted_msg = &decode_base64($crypted_msg);
-    my $msg = $my_cipher->decrypt($crypted_msg); 
-    $msg =~ s/^\0*//g;
-    return $msg;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_xml_hash
-#   PARAMETERS:  header - string - message header (required)
-#                source - string - where the message come from (required)
-#                target - string - where the message should go to (required)
-#                [header_value] - string - something usefull (optional)
-#      RETURNS:  hash - hash - nomen est omen
-#  DESCRIPTION:  creates a key-value hash, all values are stored in a array
-#===============================================================================
-sub create_xml_hash {
-    my ($header, $source, $target, $header_value) = @_ ;
-    
-    if (not defined $header || not defined $source || not defined $target) {
-        daemon_log("ERROR: create_xml_hash function is invoked with uncompleted parameters", 7);
-    }
-
-    my $hash = {
-            header => [$header],
-            source => [$source],
-            target => [$target],
-            $header => [$header_value],
-    };
-    #daemon_log("create_xml_hash:", 7),
-    #chomp(my $tmp = Dumper $hash);
-    #daemon_log("\t$tmp\n", 7);
-    return $hash
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_xml_string
-#   PARAMETERS:  xml_hash - hash - hash from function create_xml_hash
-#      RETURNS:  xml_string - string - xml string representation of the hash
-#  DESCRIPTION:  transform the hash to a string using XML::Simple module
-#===============================================================================
-sub create_xml_string {
-    my ($xml_hash) = @_ ;
-    my $xml_string = $xml->XMLout($xml_hash, RootName => 'xml');
-    $xml_string =~ s/[\n]+//g;
-    return $xml_string;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  add_content2xml_hash
-#   PARAMETERS:  xml_ref - ref - reference to a hash from function create_xml_hash
-#                element - string - key for the hash
-#                content - string - value for the hash
-#      RETURNS:  nothing 
-#  DESCRIPTION:  add key-value pair to xml_ref, if key alread exists, then append value to list
-#===============================================================================
-sub add_content2xml_hash {
-    my ($xml_ref, $element, $content) = @_;
-    if(not exists $$xml_ref{$element} ) {
-        $$xml_ref{$element} = [];
-    }
-    my $tmp = $$xml_ref{$element};
-    push(@$tmp, $content);
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  get_content_from_xml_hash
-#   PARAMETERS:  xml_ref - ref - reference of the xml hash
-#                element - string - key of the value you want
-#      RETURNS:  value - string - if key is either header, target or source
-#                value - list - for all other keys in xml hash
-#  DESCRIPTION:  
-#===============================================================================
-sub get_content_from_xml_hash {
-    my ($xml_ref, $element) = @_;
-    my $result = $xml_ref->{$element};
-    if( $element eq "header" || $element eq "target" || $element eq "source") {
-        return @$result[0];
-    }
-    return @$result;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  open_socket
-#   PARAMETERS:  PeerAddr - string - something like 192.168.1.1 or 192.168.1.1:10000
-#                [PeerPort] - string - necessary if port not appended by PeerAddr
-#      RETURNS:  socket - IO::Socket::INET
-#  DESCRIPTION:  open a socket to PeerAddr 
-#===============================================================================
-sub open_socket {
-    my ($PeerAddr, $PeerPort) = @_ ;
-    if(defined($PeerPort)){
-        $PeerAddr = $PeerAddr.":".$PeerPort;
-    }
-    my $socket;
-    $socket = new IO::Socket::INET(PeerAddr => $PeerAddr ,
-            Porto => "tcp" ,
-            Type => SOCK_STREAM,
-            Reuse => 1,
-            Timeout => 5,
-            );
-    if(not defined $socket) {
-        return;
-    }
-    return $socket;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  read_from_socket
-#   PARAMETERS:  socket - fh - filehandel to read from  
-#      RETURNS:  result - string - readed characters from socket
-#  DESCRIPTION:  reads data from socket in 16 byte steps
-#===============================================================================
-sub read_from_socket {
-    my ($socket) = @_;
-
-    $socket->blocking(1);
-    my $result = <$socket>;
-    $socket->blocking(0);
-    my $part_msg;
-    while ($part_msg = <$socket>) {
-        if (not defined $part_msg) { last; }
-        $result .= $part_msg;
-    }
-    
-    #my $result = "";
-    #my $len = 16;
-    #while($len == 16){
-    #    my $char;
-    #    $len = sysread($socket, $char, 16);
-    #    if($len != 16) { last }
-    #    if($len != 16) { last }
-    #    $result .= $char;
-    #}
-    return $result;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  send_msg_hash2address
-#   PARAMETERS:  msg_hash - hash - xml_hash created with function create_xml_hash
-#                PeerAddr string - socket address to send msg
-#                PeerPort string - socket port, if not included in socket address
-#      RETURNS:  nothing
-#  DESCRIPTION:  ????
-#===============================================================================
-sub send_msg_hash2address {
-    my ($msg_hash, $address) = @_ ;
-
-    # fetch header for logging
-    my $header = &get_content_from_xml_hash($msg_hash, "header");
-
-    # generate xml string
-    my $msg_xml = &create_xml_string($msg_hash);
-
-    # fetch the appropriated passwd from hash
-    my $passwd = $known_daemons->{$address}->{passwd};
-
-    # create a ciphering object
-    my $act_cipher = &create_ciphering($passwd);
-
-    # encrypt xml msg
-    my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher);
-
-    # open socket
-    my $socket = &open_socket($address);
-    if(not defined $socket){
-        daemon_log("ERROR: cannot send '$header'-msg to $address , server not reachable", 1);
-        return;
-    }
-
-    # send xml msg
-    print $socket $crypted_msg."\n";
-
-    close $socket;
-    daemon_log("send '$header'-msg to $address", 5);
-    daemon_log("crypted_msg:\n\t$crypted_msg", 7);
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  send_msg_hash2all
-#   PARAMETERS:  msg_hash - hash - xml_hash created with function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  send msg_hash to all registered daemons
-#===============================================================================
-sub send_msg_hash2all {
-    my ($msg_hash) = @_;
-
-    # fetch header for logging
-    my $header = &get_content_from_xml_hash($msg_hash, "header");
-
-    # generate xml string
-    my $msg_xml = &create_xml_string($msg_hash);
-
-    # fetch a list of all target addresses 
-    my @targets = keys(%$known_daemons);
-
-    # itterates through the list an send each the msg
-    foreach my $target (@targets) {
-        if($target eq $bus_address) {next};   # do not send msg to bus
-
-        # fetch the appropriated passwd
-        my $passwd = $known_daemons->{$target}->{passwd};
-
-        # create ciphering object
-        my $act_cipher = &create_ciphering($passwd);
-
-        # encrypt xml msg
-        my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher);
-
-        # open socket
-        my $socket = &open_socket($target);
-        if(not defined $socket){
-            daemon_log("ERROR: cannot open socket to $target , server not reachable", 1);
-            &update_known_daemons_entry(hostname=>$target, status=>"down");
-            next;
-        }
-
-        # send xml msg
-        print $socket $crypted_msg."\n";
-
-        close $socket;
-        daemon_log("send '$header'-msg to $target", 5);
-        daemon_log("crypted_msg:\n\t$crypted_msg", 7);
-    }
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  here_i_am
-#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  process the incoming msg 'here_i_am'
-#===============================================================================
-sub here_i_am {
-    my ($msg_hash) = @_ ;
-    my $source = &get_content_from_xml_hash($msg_hash, "source");
-
-    my $new_passwd = &create_passwd();
-
-    # create known_daemons entry
-    &create_known_daemons_entry($source);
-    &update_known_daemons_entry(hostname=>$source, status=>"registered", passwd=>$bus_passwd);
-
-    # create outgoing msg
-    my $out_hash = &create_xml_hash("new_passwd", "$bus_ip:$bus_port", $source, $new_passwd);
-    &send_msg_hash2address($out_hash, $source);
-
-    # change passwd, reason
-    # &send_msg_hash2address takes $known_daemons->{"$source"}->{passwd} to cipher msg
-    &update_known_daemons_entry(hostname=>$source, status=>"new_passwd", passwd=>$new_passwd);
-
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  confirm_new_passwd
-#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  process this incoming message
-#===============================================================================
-sub confirm_new_passwd {
-    my ($msg_hash) = @_ ;
-    my $source = &get_content_from_xml_hash($msg_hash, "source");
-    &update_known_daemons_entry(hostname=>$source, status=>"confirmed_new_passwd");
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  ping
-#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  process this incoming message
-#===============================================================================
-sub ping {
-    my ($msg_hash) = @_ ;
-    my $source = &get_content_from_xml_hash($msg_hash, "source");   
-    &update_known_daemons_entry(hostname=>$source, status=>"ping");
-    my $out_hash = &create_xml_hash("got_ping", $bus_address, $source);
-    &send_msg_hash2address($out_hash, $source);
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  make ping
-#   PARAMETERS:  address - string - address which should be pinged
-#      RETURNS:  nothing
-#  DESCRIPTION:  send ping message to address
-#===============================================================================
-sub make_ping {
-    my ($address) = @_;
-    daemon_log("ping:$address\n", 1);
-    my $out_hash = &create_xml_hash("ping", "$bus_ip:$bus_port", $address);
-    &send_msg_hash2address($out_hash, $address);
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  got_ping
-#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  process this incoming message
-#===============================================================================
-sub got_ping {
-    my ($msg_hash) = @_;
-    my $source = &get_content_from_xml_hash($msg_hash, "source");
-    &update_known_daemons_entry(hostname=>$source, status=>"got_ping");
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  new_client
-#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  process this incoming message
-#===============================================================================
-sub new_client {
-    my ($msg_hash) = @_ ;
-    my $source = &get_content_from_xml_hash($msg_hash, "source");
-    my $header = &get_content_from_xml_hash($msg_hash, "header");
-    my $new_client = (&get_content_from_xml_hash($msg_hash, $header))[0];
-    
-    &update_known_daemons_entry(hostname=>$source, client=>$new_client);
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  delete_client
-#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  process this incoming message
-#===============================================================================
-sub delete_client {
-    my ($msg_hash) = @_ ;
-    my $source = &get_content_from_xml_hash($msg_hash, "source");
-    my $header = &get_content_from_xml_hash($msg_hash, "header");
-    my $del_client = (&get_content_from_xml_hash($msg_hash, $header))[0];
-   
-    if (not exists $known_daemons->{$source}->{$del_client}) {
-        daemon_log
-    }
-    delete $known_daemons->{$source}->{$del_client};
-    
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  print_known_daemons_hash
-#   PARAMETERS:  nothing
-#      RETURNS:  nothing
-#  DESCRIPTION:  nome est omen
-#===============================================================================
-sub print_known_daemons_hash {
-    my ($tmp) = @_;
-    print "####################################\n";
-    print "# status of known_daemons\n";
-    my $hosts;
-    my $host_hash;
-    $shmkh->shlock(LOCK_EX);
-    my @hosts = keys %$known_daemons;
-    foreach my $host (@hosts) {
-        my $status = $known_daemons->{$host}->{status} ;
-        my $passwd = $known_daemons->{$host}->{passwd};
-        my $timestamp = $known_daemons->{$host}->{timestamp};
-        my @clients = keys %{$known_daemons->{$host}->{clients}};
-        my $client_string = join(", ", @clients);
-        print "$host\n";
-        print "\tstatus:    $status\n";
-        print "\tpasswd:    $passwd\n";
-        print "\ttimestamp: $timestamp\n";
-        print "\tclients:   $client_string\n";
-        
-    }
-    $shmkh->shunlock(LOCK_EX);
-    print "####################################\n\n";
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_known_daemons_entry
-#   PARAMETERS:  hostname - string - ip address and port of host
-#      RETURNS:  nothing
-#  DESCRIPTION:  nome est omen
-#===============================================================================
-sub create_known_daemons_entry {
-    my ($hostname) = @_;
-    $shmkh->shlock(LOCK_EX);
-    $known_daemons->{$hostname} = {};
-    $known_daemons->{$hostname}->{status} = "none";
-    $known_daemons->{$hostname}->{passwd} = "none";
-    $known_daemons->{$hostname}->{timestamp} = "none";
-    $known_daemons->{$hostname}->{clients} = {};
-    $shmkh->shunlock(LOCK_EX); 
-    return;  
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  update_known_daemons_entry
-#   PARAMETERS:  hostname - string - ip address and port of host (required)
-#                status - string - (optional)
-#                passwd - string - (optional)
-#                client - string - ip address and port of client (optional)
-#      RETURNS:  nothing
-#  DESCRIPTION:  nome est omen and updates each time the timestamp of hostname
-#===============================================================================
-sub update_known_daemons_entry {
-    my $arg = {
-        hostname => undef, status => undef, passwd => undef,
-        client => undef,
-        @_ };
-    my $hostname = $arg->{hostname};
-    my $status = $arg->{status};
-    my $passwd = $arg->{passwd};
-    my $client = $arg->{client};
-
-    if (not defined $hostname) {
-        daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1);
-        return;
-    }
-
-    my ($seconds, $minutes, $hours, $monthday, $month,
-    $year, $weekday, $yearday, $sommertime) = localtime(time);
-    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
-    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
-    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
-    $month+=1;
-    $month = $month < 10 ? $month = "0".$month : $month;
-    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
-    $year+=1900;
-    my $t = "$year$month$monthday$hours$minutes$seconds";
-
-    $shmkh->shlock(LOCK_EX);
-    if (defined $status) {
-        $known_daemons->{$hostname}->{status} = $status;
-    }
-    if (defined $passwd) {
-        $known_daemons->{$hostname}->{passwd} = $passwd;
-    }
-    if (defined $client) {
-        $known_daemons->{$hostname}->{clients}->{$client} = "";
-    }
-    $known_daemons->{$hostname}->{timestamp} = $t;
-    $shmkh->shunlock(LOCK_EX);
-    return;
-}
-
-
-#==== MAIN = main ==============================================================
-
-#  parse commandline options
-Getopt::Long::Configure( "bundling" );
-GetOptions("h|help" => \&usage,
-           "c|config=s" => \$cfg_file,
-           "f|foreground" => \$foreground,
-           "v|verbose+" => \$verbose,
-           );
-
-#  read and set config parameters
-&check_cmdline_param ;
-&read_configfile;
-&check_pid;
-
-$SIG{CHLD} = 'IGNORE';
-
-# restart daemon log file
-if(-e $log_file ) { unlink $log_file }
-daemon_log("$0 started!");
-
-# Just fork, if we"re not in foreground mode
-if( ! $foreground ) { $pid = fork(); }
-else { $pid = $$; }
-
-# Do something useful - put our PID into the pid_file
-if( 0 != $pid ) {
-    open( LOCK_FILE, ">$pid_file" );
-    print LOCK_FILE "$pid\n";
-    close( LOCK_FILE );
-    if( !$foreground ) { exit( 0 ) };
-}
-
-# detect own ip and mac address
-($bus_ip, $bus_mac_address) = &get_ip_and_mac(); 
-if (not defined $bus_ip) {
-    die "EXIT: ip address of $0 could not be detected";
-}
-daemon_log("bus ip address detected: $bus_ip", 1);
-daemon_log("bus mac address detected: $bus_mac_address", 1);
-
-
-# setup xml parser
-$xml = new XML::Simple();
-
-# create cipher object
-$bus_cipher = &create_ciphering($bus_passwd);
-$bus_address = "$bus_ip:$bus_port";
-
-# create reading and writing vectors
-my $rbits = my $wbits = my $ebits = "";
-
-# open the bus socket
-if($bus_activ eq "on") {
-    $bus = IO::Socket::INET->new(LocalPort => $bus_port,
-            Type => SOCK_STREAM,
-            Reuse => 1,
-            Listen => 20,
-            ) or die "kann kein TCP-Server an Port $bus_port sein: $@\n";
-    vec($rbits, fileno $bus, 1) = 1;
-    vec($wbits, fileno $bus, 1) = 1;
-    print "start bus at $bus_ip:$bus_port\n";        
-}
-
-# add bus to known_daemons 
-&create_known_daemons_entry($bus_address);
-&update_known_daemons_entry(hostname=>$bus_address, status=>"bus", passwd=>$bus_passwd);
-
-
-while(1) {
-    my $nf = select($rbits, $wbits, undef, undef);
-    # error handling
-    if($nf < 0 ) { 
-    }
-
-    # something is coming in 
-    if(vec $rbits, fileno $bus, 1 ) {
-        my $client = $bus->accept();
-        my $other_end = getpeername($client);
-        if(not defined $other_end) {
-            daemon_log("Gegenstelle konnte nicht identifiziert werden: $!\n");
-        } else {
-            my ($port, $iaddr) = unpack_sockaddr_in($other_end);
-            my $actual_ip = inet_ntoa($iaddr);
-            daemon_log("\naccept client from $actual_ip\n", 5);
-            my $in_msg = &read_from_socket($client);
-            if(defined $in_msg){
-                &activating_child($in_msg, $actual_ip);
-            } else {
-                daemon_log("cannot read from $actual_ip\n",1);
-            }
-        }
-        close($client);        
-    }
-
-}
-
-
diff --git a/contrib/daemon/gosa-si-bus.conf-template b/contrib/daemon/gosa-si-bus.conf-template
deleted file mode 100644 (file)
index 7ca56e9..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-[general]
-log_file = /var/log/gosa-si-bus.log
-pid_file = /var/run/gosa-si-bus.pid
-child_max = 10
-child_min = 2
-child_timeout = 10
-
-[bus]
-bus_activ = on
-bus_passwd = secret-bus-password
-bus_ip = 127.0.0.1
-bus_port = 20080
-
diff --git a/contrib/daemon/gosa-si-client b/contrib/daemon/gosa-si-client
deleted file mode 100755 (executable)
index 3825940..0000000
+++ /dev/null
@@ -1,1109 +0,0 @@
-#!/usr/bin/perl
-#===============================================================================
-#
-#         FILE:  gosa-server
-#
-#        USAGE:  ./gosasc
-#
-#  DESCRIPTION:
-#
-#      OPTIONS:  ---
-# REQUIREMENTS:  ---
-#         BUGS:  ---
-#        NOTES:
-#       AUTHOR:   (Andreas Rettenberger), <rettenberger@gonicus.de>
-#      COMPANY:
-#      VERSION:  1.0
-#      CREATED:  12.09.2007 08:54:41 CEST
-#     REVISION:  ---
-#===============================================================================
-
-use strict;
-use warnings;
-use Getopt::Long;
-use Config::IniFiles;
-use POSIX;
-use Time::HiRes qw( gettimeofday );
-
-use Fcntl;
-use IO::Socket::INET;
-use Crypt::Rijndael;
-use MIME::Base64;
-use Digest::MD5  qw(md5 md5_hex md5_base64);
-use XML::Simple;
-use Data::Dumper;
-use Sys::Syslog qw( :DEFAULT setlogsock);
-use File::Spec;
-use Cwd;
-use GosaSupportDaemon;
-
-
-my ($cfg_file, %cfg_defaults, $foreground, $verbose, $pid_file, $procid, $pid, $log_file);
-my ($server_address, $server_ip, $server_port, $server_domain, $server_passwd, $server_cipher, $server_timeout);
-my ($client_address, $client_ip, $client_port, $client_mac_address);
-my ($input_socket, $rbits, $wbits, $ebits, $xml, $known_hosts);
-my (@events);
-
-# default variables
-my $event_dir = "/etc/gosac/events";
-$known_hosts = {};
-$foreground = 0 ;
-%cfg_defaults =
-("general" =>
-    {"log_file" => [\$log_file, "/var/run/".$0.".log"],
-    "pid_file" => [\$pid_file, "/var/run/".$0.".pid"],
-    },
-"client" => 
-    {"client_port" => [\$client_port, "20083"],
-    },
-"server" =>
-    {"server_ip" => [\$server_ip, ""],
-    "server_port" => [\$server_port, "20081"],
-    "server_passwd" => [\$server_passwd, ""],
-    "server_timeout" => [\$server_timeout, 10],
-    "server_domain" => [\$server_domain, ""],
-    },
-    );
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  read_configfile
-#   PARAMETERS:  cfg_file - string - 
-#      RETURNS:  
-#  DESCRIPTION: 
-#===============================================================================
-sub read_configfile {
-    my $cfg;
-    if( defined( $cfg_file) && ( length($cfg_file) > 0 )) {
-        if( -r $cfg_file ) {
-            $cfg = Config::IniFiles->new( -file => $cfg_file );
-        } else {
-            print STDERR "Couldn't read config file!";
-        }
-    } else {
-        $cfg = Config::IniFiles->new() ;
-    }
-    foreach my $section (keys %cfg_defaults) {
-        foreach my $param (keys %{$cfg_defaults{ $section }}) {
-            my $pinfo = $cfg_defaults{ $section }{ $param };
-            ${@$pinfo[ 0 ]} = $cfg->val( $section, $param, @$pinfo[ 1 ] );
-        }
-    }
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  logging
-#   PARAMETERS:  level - string - default 'info' 
-#                msg - string - 
-#                facility - string - default 'LOG_DAEMON' 
-#      RETURNS:  
-#  DESCRIPTION: 
-#===============================================================================
-sub daemon_log {
-    my( $msg, $level ) = @_;
-    if(not defined $msg) { return }
-    if(not defined $level) { $level = 1 }
-    if(defined $log_file){
-        open(LOG_HANDLE, ">>$log_file");
-        if(not defined open( LOG_HANDLE, ">>$log_file" )) { 
-            print STDERR "cannot open $log_file: $!";
-            return }
-        chomp($msg);
-        if($level <= $verbose){
-            print LOG_HANDLE $msg."\n";
-            if(defined $foreground) { print $msg."\n" }
-        }
-    }
-    close( LOG_HANDLE );
-#    my ($msg, $level, $facility) = @_;
-#    if(not defined $msg) {return}
-#    if(not defined $level) {$level = "info"}
-#    if(not defined $facility) {$facility = "LOG_DAEMON"}
-#    openlog($0, "pid,cons,", $facility);
-#    syslog($level, $msg);
-#    closelog;
-#    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME: check_cmdline_param
-#   PARAMETERS: 
-#      RETURNS:  
-#  DESCRIPTION: 
-#===============================================================================
-sub check_cmdline_param () {
-    my $err_config;
-    my $err_counter = 0;
-    if( not defined( $cfg_file)) {
-        #$err_config = "please specify a config file";
-        #$err_counter += 1;
-        my $cwd = getcwd;
-        my $name = "/etc/gosa/gosa-si-client.conf";
-        $cfg_file = File::Spec->catfile( $cwd, $name );
-        print STDERR "no conf file specified\n   try to use default: $cfg_file\n";        
-    }
-    if( $err_counter > 0 ) {
-        &usage( "", 1 );
-        if( defined( $err_config)) { print STDERR "$err_config\n"}
-        print STDERR "\n";
-        exit( -1 );
-    }
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME: check_pid
-#   PARAMETERS:
-#      RETURNS:
-#  DESCRIPTION:
-#===============================================================================
-sub check_pid {
-    $pid = -1;
-    # Check, if we are already running
-    if( open(LOCK_FILE, "<$pid_file") ) {
-        $pid = <LOCK_FILE>;
-        if( defined $pid ) {
-            chomp( $pid );
-            if( -f "/proc/$pid/stat" ) {
-                my($stat) = `cat /proc/$pid/stat` =~ m/$pid \((.+)\).*/;
-                if( $0 eq $stat ) {
-                    close( LOCK_FILE );
-                    exit -1;
-                }
-            }
-        }
-        close( LOCK_FILE );
-        unlink( $pid_file );
-    }
-
-    # create a syslog msg if it is not to possible to open PID file
-    if (not sysopen(LOCK_FILE, $pid_file, O_WRONLY|O_CREAT|O_EXCL, 0644)) {
-        my($msg) = "Couldn't obtain lockfile '$pid_file' ";
-        if (open(LOCK_FILE, '<', $pid_file)
-                && ($pid = <LOCK_FILE>))
-        {
-            chomp($pid);
-            $msg .= "(PID $pid)\n";
-        } else {
-            $msg .= "(unable to read PID)\n";
-        }
-        if( ! ($foreground) ) {
-            openlog( $0, "cons,pid", "daemon" );
-            syslog( "warning", $msg );
-            closelog();
-        }
-        else {
-            print( STDERR " $msg " );
-        }
-        exit( -1 );
-    }
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  get_ip_and_mac 
-#   PARAMETERS:  nothing
-#      RETURNS:  (ip, mac) 
-#  DESCRIPTION:  executes /sbin/ifconfig and parses the output, the first occurence 
-#                of a inet address is returned as well as the mac address in the line
-#                above the inet address
-#===============================================================================
-sub get_ip_and_mac {
-    my $ip = "0.0.0.0.0"; # Defualt-IP
-    my $mac = "00:00:00:00:00:00";  # Default-MAC
-    my @ifconfig = qx(/sbin/ifconfig);
-    foreach(@ifconfig) {
-        if (/Hardware Adresse (\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2})/) {
-            $mac = "$1:$2:$3:$4:$5:$6";
-            next;
-        }
-        if (/inet Adresse:(\d+).(\d+).(\d+).(\d+)/) {
-            $ip = "$1.$2.$3.$4";
-            last;
-        }
-    }
-    return ($ip, $mac);
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  usage
-#   PARAMETERS: 
-#      RETURNS:  
-#  DESCRIPTION: 
-#===============================================================================
-sub usage {
-        my( $text, $help ) = @_;
-        $text = undef if( "h" eq $text );
-        (defined $text) && print STDERR "\n$text\n";
-        if( (defined $help && $help) || (!defined $help && !defined $text) ) {
-                print STDERR << "EOF" ;
-usage: $0 [-hvf] [-c config]
-
-    -h        : this (help) message
-    -c <file> : config file
-    -f        : foreground, process will not be forked to background
-    -v        : be verbose (multiple to increase verbosity)
-EOF
-        }
-        print "\n" ;
-}
-
-#===  FUNCTION  ================================================================
-#         NAME:  get_server_addresses
-#   PARAMETERS:  
-#      RETURNS:  
-#  DESCRIPTION:  
-#===============================================================================
-sub get_server_addresses {
-    my $domain= shift;
-    my @result;
-    my $dig_cmd= 'dig +nocomments srv _gosad._tcp.'.$domain;
-
-    my $output= `$dig_cmd 2>&1`;
-    open (PIPE, "$dig_cmd 2>&1 |");
-    while(<PIPE>) {
-        chomp $_;
-        # If it's not a comment
-        if($_ =~ m/^[^;]/) {
-            my @matches= split /\s+/;
-
-            # Push hostname with port
-            if($matches[3] eq 'SRV') {
-                push @result, $matches[7].':'.$matches[6];
-            } elsif ($matches[3] eq 'A') {
-                my $i=0;
-
-                # Substitute the hostname with the ip address of the matching A record
-                foreach my $host (@result) {
-                    if ((split /\:/, $host)[0] eq $matches[0]) {
-                        $result[$i]= $matches[4].':'.(split /\:/, $host)[1];
-                    }
-                    $i++;
-                }
-            }
-        }
-    }
-    close(PIPE);
-    return @result;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  register_at_server
-#   PARAMETERS:  
-#      RETURNS:  
-#  DESCRIPTION:  
-#===============================================================================
-sub register_at_server {
-    my ($tmp) = @_;
-
-    # create new passwd and ciphering object for client-server communication
-    my $new_server_passwd = &create_passwd();
-    my $new_server_cipher;
-
-    # detect all client accepted events
-    opendir(DIR, $event_dir) 
-        or daemon_log("cannot find directory $event_dir!\ngosac starts without any accepting events!", 1);
-    my $file_name;
-    @events = ();
-    while(defined($file_name = readdir(DIR))){
-        if ($file_name eq "." || $file_name eq "..") {
-            next;
-        }
-        push(@events, $file_name);
-    }
-    my $events = join(",", @events);
-    daemon_log("found events: $events", 1);
-
-    # fill in all possible servers
-    my @servers;
-    if (defined $server_domain) {
-        my @tmp_servers = &get_server_addresses($server_domain);
-        foreach my $server (@tmp_servers) { unshift(@servers, $server); }
-    }
-    # add server address from config file at first position of server list
-    if (defined $server_address) {
-        unshift(@servers, $server_address);
-    }
-    daemon_log("found servers in configuration file and via DNS:", 5);
-    foreach my $server (@servers) {
-        daemon_log("\t$server", 5);
-    }
-
-    my ($rout, $wout, $reg_server);
-    foreach my $server (@servers) {
-        # create msg hash
-        my $register_hash = &create_xml_hash("here_i_am", $client_address, $server);
-        &add_content2xml_hash($register_hash, "new_passwd", $new_server_passwd);
-        &add_content2xml_hash($register_hash, "client_mac_address", $client_mac_address);
-        &add_content2xml_hash($register_hash, "events", $events);
-
-        # send xml hash to server with general server passwd
-        my $answer = &send_msg_hash2address($register_hash, $server, $server_passwd);
-        
-        # sending fails, no sens to wait for response
-        if ($answer ne "done") { next; }
-    
-        # waiting for response
-        daemon_log("waiting for response...\n", 5);
-        my $nf = select($rout=$rbits, $wout=$wbits, undef, $server_timeout);
-
-        # something is coming in
-        if(vec $rout, fileno $input_socket, 1) {
-            my $crypted_msg;
-            my $client = $input_socket->accept();
-            my $other_end = getpeername($client);
-            if(not defined $other_end) {
-                daemon_log("client cannot be identified: $!\n");
-            } else {
-                my ($port, $iaddr) = unpack_sockaddr_in($other_end);
-                my $actual_ip = inet_ntoa($iaddr);
-                daemon_log("\naccept client from $actual_ip\n", 5);
-                my $in_msg = &read_from_socket($client);
-                if(defined $in_msg){
-                    chomp($in_msg);
-                    $crypted_msg = $in_msg;
-                } else {
-                    daemon_log("cannot read from $actual_ip\n", 5);
-                }
-            }
-            close($client);
-            
-            # validate acknowledge msg from server
-            $new_server_cipher = &create_ciphering($new_server_passwd);
-            my $msg_hash;
-            eval {
-                my $decrypted_msg = &decrypt_msg($crypted_msg, $new_server_cipher);
-                daemon_log("decrypted register msg: $decrypted_msg", 5);
-                $msg_hash = $xml->XMLin($decrypted_msg, ForceArray=>1);
-            };
-            if($@) {
-                daemon_log("ERROR: do not understand the incoming message:" , 5);  
-                daemon_log("$@", 7); 
-            } else {
-                my $header = &get_content_from_xml_hash($msg_hash, "header");
-                if($header eq "registered") {
-                    $reg_server = $server;
-                    last;
-                } elsif($header eq "denied") {
-                    my $reason = (&get_content_from_xml_hash($msg_hash, "denied"))[0];
-                    daemon_log("registration at $server denied: $reason", 1);
-                } else {
-                    daemon_log("cannot register at $server", 1);
-                }
-            }
-        }
-        # kommt antwort nicht, dann probiere es mit dem nächsten in der liste
-
-    }
-    
-    if(defined $reg_server) {
-        daemon_log("registered at $reg_server", 1);
-    } else {
-        daemon_log("cannot register at any server", 1);
-        daemon_log("exiting!!!", 1);
-        exit(1);
-    }
-
-    # update the global available variables
-    $server_address = $reg_server;
-    $server_passwd = $new_server_passwd;
-    $server_cipher = $new_server_cipher;
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_xml_hash
-#   PARAMETERS:  
-#      RETURNS:
-#  DESCRIPTION:
-#===============================================================================
-sub create_xml_hash {
-    my ($header, $source, $target, $header_value) = @_;
-    my $hash = {
-            header => [$header],
-            source => [$source],
-            target => [$target],
-            $header => [$header_value],
-    };
-    daemon_log("create_xml_hash:", 7),
-    chomp(my $tmp = Dumper $hash);
-    daemon_log("\t$tmp\n", 7);
-    return $hash
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_xml_string
-#   PARAMETERS:  
-#      RETURNS:
-#  DESCRIPTION:
-#===============================================================================
-sub create_xml_string {
-    my ($xml_hash) = @_ ;
-    my $xml_string = $xml->XMLout($xml_hash, RootName => 'xml');
-    $xml_string =~ s/[\n]+//g;
-    daemon_log("create_xml_string:\n\t$xml_string\n", 7);
-    return $xml_string;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  add_content2xml_hash
-#   PARAMETERS:  
-#      RETURNS:
-#  DESCRIPTION:
-#===============================================================================
-sub add_content2xml_hash {
-    my ($xml_ref, $element, $content) = @_;
-    if(not exists $$xml_ref{$element} ) {
-        $$xml_ref{$element} = [];
-    }
-    my $tmp = $$xml_ref{$element};
-    push(@$tmp, $content);
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  get_content_from_xml_hash
-#   PARAMETERS:  ref : reference to the xml hash
-#                string: key of the value you want
-#      RETURNS:  STRING AND ARRAY
-#  DESCRIPTION:  if key of the hash is either 'header', 'target' or 'source' the 
-#                function returns a string cause it is expected that these keys
-#                do just have one value, all other keys returns an array!!!
-#===============================================================================
-sub get_content_from_xml_hash {
-    my ($xml_ref, $element) = @_;
-    my $result = $xml_ref->{$element};
-    if( $element eq "header" || $element eq "target" || $element eq "source") {
-        return @$result[0];
-    }
-    return @$result;
-}
-
-#    my ($xml_ref, $element) = @_;
-#    if (exists $xml_ref->{$element}) {
-#        my $result = $xml_ref->{$element};
-#        if( $element eq "header" || $element eq "target" || $element eq "source") {
-#            return @$result[0];
-#        } else {
-#            return @$result;
-#        }
-#        
-#    } else {
-#        my $result = ();
-#        return @$result;
-#    }
-#}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  encrypt_msg
-#   PARAMETERS:
-#      RETURNS:
-#  DESCRIPTION:
-#===============================================================================
-sub encrypt_msg {
-    my ($msg, $my_cipher) = @_;
-    if(not defined $my_cipher) { print "no cipher object\n"; }
-    $msg = "\0"x(16-length($msg)%16).$msg;
-    my $crypted_msg = $my_cipher->encrypt($msg);
-    chomp($crypted_msg = &encode_base64($crypted_msg));
-    return $crypted_msg;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  decrypt_msg
-#   PARAMETERS:
-#      RETURNS:
-#  DESCRIPTION:
-#===============================================================================
-sub decrypt_msg {
-    my ($crypted_msg, $my_cipher) = @_ ;
-    $crypted_msg = &decode_base64($crypted_msg);
-    my $msg = $my_cipher->decrypt($crypted_msg); 
-    $msg =~ s/\0*//g;
-    return $msg;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_ciphering
-#   PARAMETERS:  
-#      RETURNS:  cipher object
-#  DESCRIPTION:  
-#===============================================================================
-sub create_ciphering {
-    my ($passwd) = @_;
-    $passwd = substr(md5_hex("$passwd") x 32, 0, 32);
-    my $iv = substr(md5_hex('GONICUS GmbH'),0, 16);
-
-    #daemon_log("iv: $iv", 7);
-    #daemon_log("key: $passwd", 7);
-    my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC());
-    $my_cipher->set_iv($iv);
-    return $my_cipher;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_passwd
-#   PARAMETERS:
-#      RETURNS:  cipher object
-#  DESCRIPTION:
-#===============================================================================
-sub create_passwd {
-    my $new_passwd = "";
-    for(my $i=0; $i<31; $i++) {
-        $new_passwd .= ("a".."z","A".."Z",0..9)[int(rand(62))]
-    }
-
-    return $new_passwd;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  send_msg_hash2address
-#   PARAMETERS:  msg string - xml message
-#                PeerAddr string - socket address to send msg
-#                PeerPort string - socket port, if not included in socket address
-#      RETURNS:  nothing
-#  DESCRIPTION:  ????
-#===============================================================================
-sub send_msg_hash2address {
-    my ($msg_hash, $address, $passwd) = @_ ;
-
-    # fetch header for logging
-    my $header = @{$msg_hash->{header}}[0];
-
-    # generiere xml string
-    my $msg_xml = &create_xml_string($msg_hash);
-
-    # hole das entsprechende passwd aus dem hash
-    if(not defined $passwd) {
-        if(exists $known_hosts->{$address}) {
-            $passwd = $known_hosts->{$address}->{passwd};
-        } elsif ($address eq $server_address) {
-            $passwd = $server_passwd;
-        } else {
-            daemon_log("$address not known, neither as server nor as client", 1);
-            return "failed";
-        }
-    }
-
-    # erzeuge ein ciphering object
-    my $act_cipher = &create_ciphering($passwd);
-
-    # encrypt xml msg
-    my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher);
-
-    # Ã¶ffne socket
-    my $socket = &open_socket($address);
-    if(not defined $socket){
-        daemon_log("cannot open socket to $address, server not reachable", 1);
-        daemon_log("cannot send '$header'-msg", 1);
-        return "failed";
-    }
-
-    # versende xml msg
-    print $socket $crypted_msg."\n";
-
-    # schließe socket
-    close $socket;
-
-    daemon_log("send '$header'-msg to $address", 5);
-    daemon_log("crypted_msg:\n\t$crypted_msg", 7);
-
-    return "done";
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  open_socket
-#   PARAMETERS:  PeerAddr string something like 192.168.1.1 or 192.168.1.1:10000
-#                [PeerPort] string necessary if port not appended by PeerAddr
-#      RETURNS:  socket IO::Socket::INET
-#  DESCRIPTION:
-#===============================================================================
-sub open_socket {
-    my ($PeerAddr, $PeerPort) = @_ ;
-    if(defined($PeerPort)){
-        $PeerAddr = $PeerAddr.":".$PeerPort;
-    }
-    my $socket;
-    $socket = new IO::Socket::INET(PeerAddr => $PeerAddr ,
-            Porto => "tcp" ,
-            Type => SOCK_STREAM,
-            Timeout => 5,
-            );
-    if(not defined $socket) {
-        #daemon_log("cannot connect to socket at $PeerAddr, $@\n");
-        return;
-    }
-    daemon_log("open_socket:\n\t$PeerAddr", 7);
-    return $socket;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  read_from_socket
-#   PARAMETERS:  socket fh - 
-#      RETURNS:  result string - readed characters from socket
-#  DESCRIPTION:  reads data from socket in 16 byte steps
-#===============================================================================
-sub read_from_socket {
-    my ($socket) = @_;
-    my $result = "";
-
-    $socket->blocking(1);
-    $result = <$socket>;
-
-    $socket->blocking(0);
-    while ( my $char = <$socket> ) {
-        if (not defined $char) { last }
-        $result .= $char;
-    }
-    return $result;
-
-
-
-#    my ($socket) = @_;
-#    my $result = "";
-#    my $len = 16;
-#    while($len == 16){
-#        my $char;
-#        $len = sysread($socket, $char, 16);
-#        if($len != 16) { last }
-#        if($len != 16) { last }
-#        $result .= $char;
-#    }
-#    return $result;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  print_known_hosts_hash
-#   PARAMETERS:
-#      RETURNS: 
-#  DESCRIPTION: 
-#===============================================================================
-sub print_known_hosts_hash {
-    my ($tmp) = @_;
-    print "####################################\n";
-    print "# status of known_hosts\n";
-    my $hosts;
-    my $host_hash;
-    my @hosts = keys %$known_hosts;
-    foreach my $host (@hosts) {
-        #my @elements = keys %$known_hosts->{$host};
-        my $status = $known_hosts->{$host}->{status} ;
-        my $passwd = $known_hosts->{$host}->{passwd};
-        my $timestamp = $known_hosts->{$host}->{timestamp};
-        print "$host\n";
-        print "\t$status\n";
-        print "\t$passwd\n";
-        print "\t$timestamp\n";
-    }
-    print "####################################\n";
-    return;
-}
-
-#===  FUNCTION  ================================================================
-#         NAME:  
-#   PARAMETERS:
-#      RETURNS: 
-#  DESCRIPTION: 
-#===============================================================================
-sub create_known_hosts_entry {
-    my ($hostname) = @_;
-    $known_hosts->{$hostname} = {};
-    $known_hosts->{$hostname}->{status} = "none";
-    $known_hosts->{$hostname}->{passwd} = "none";
-    $known_hosts->{$hostname}->{timestamp} = "none";
-    return;  
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  
-#   PARAMETERS:
-#      RETURNS: 
-#  DESCRIPTION: 
-#===============================================================================
-sub update_known_hosts_entry {
-    my ($hostname, $status, $passwd, $timestamp) = @_;
-    my ($seconds, $minutes, $hours, $monthday, $month,
-    $year, $weekday, $yearday, $sommertime) = localtime(time);
-    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
-    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
-    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
-    $month+=1;
-    $month = $month < 10 ? $month = "0".$month : $month;
-    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
-    $year+=1900;
-    my $t = "$year$month$monthday$hours$minutes$seconds";
-
-    if($status) {
-        $known_hosts->{$hostname}->{status} = $status;
-    }
-    if($passwd) {
-        $known_hosts->{$hostname}->{passwd} = $passwd;
-    }
-    if($timestamp) {
-        $t = $timestamp;
-    }
-    $known_hosts->{$hostname}->{timestamp} = $t;
-    return;  
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  
-#   PARAMETERS:
-#      RETURNS: 
-#  DESCRIPTION: 
-#===============================================================================
-sub add_content2known_hosts {
-    my ($hostname, $element, $content) = @_;
-    my ($seconds, $minutes, $hours, $monthday, $month,
-    $year, $weekday, $yearday, $sommertime) = localtime(time);
-    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
-    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
-    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
-    $month+=1;
-    $month = $month < 10 ? $month = "0".$month : $month;
-    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
-    $year+=1900;
-    my $t = "$year$month$monthday$hours$minutes$seconds";
-    
-    $known_hosts->{$hostname}->{$element} = $content;
-    $known_hosts->{$hostname}->{timestamp} = $t;
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  
-#   PARAMETERS:
-#      RETURNS: 
-#  DESCRIPTION: 
-#===============================================================================
-sub process_incoming_msg {
-    my ($crypted_msg) = @_;
-    if(not defined $crypted_msg) {
-        daemon_log("function 'process_incoming_msg': got no msg", 7);
-    }
-    $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
-    $crypted_msg = $1;
-    my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
-    daemon_log("msg from host:", 1);
-    daemon_log("\t$host", 1);
-    daemon_log("crypted msg:", 7);
-    daemon_log("\t$crypted_msg", 7);
-
-    my $act_cipher = &create_ciphering($server_passwd);
-
-    # try to decrypt incoming msg
-    my ($msg, $msg_hash);
-    eval{
-        $msg = &decrypt_msg($crypted_msg, $act_cipher);
-        $msg_hash = $xml->XMLin($msg, ForceArray=>1);
-    };
-    if($@) {
-        daemon_log("ERROR: incoming msg cannot be decrypted with server passwd", 1);
-        return;
-    } 
-
-    my $header = &get_content_from_xml_hash($msg_hash, "header");
-    
-    daemon_log("header from msg:", 1);
-    daemon_log("\t$header", 1);
-    daemon_log("msg to process:", 7);
-    daemon_log("\t$msg", 7);
-
-    #check whether msg to process is a event 
-    opendir(DIR, $event_dir) 
-        or daemon_log("cannot find directory $event_dir, no events specified", 5);
-    my $file_name;
-    while(defined($file_name = readdir(DIR))){
-        if ($file_name eq "." || $file_name eq "..") {
-            next;
-        }
-        if ($file_name eq $header) {
-            my $cmd = "$event_dir/$file_name '$msg'";
-            my $result_xml = "";
-            open(PIPE, "$cmd 2>&1 |");
-            while(<PIPE>) {
-                $result_xml.=$_;
-                last;
-            }
-            close(PIPE);
-            my $res_hash = &transform_msg2hash($result_xml);
-            my $res_target = @{$res_hash->{target}}[0];
-            &send_msg_hash2address($res_hash, $server_address);
-            
-            return;
-        }
-    }
-    close(DIR);
-    daemon_log("could not assign the msg $header to an event", 5);
-    
-
-
-    if ($header eq 'new_ldap_config') { &new_ldap_config($msg_hash)}
-    elsif ($header eq 'ping') { &got_ping($msg_hash) }
-    elsif ($header eq 'wake_up') { &execute_event($msg_hash)}
-    elsif ($header eq 'new_passwd') { &new_passwd()}
-    else { daemon_log("ERROR: no function assigned to msg $header", 5) }
-
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  
-#   PARAMETERS:
-#      RETURNS: 
-#  DESCRIPTION: 
-#===============================================================================
-sub update_status { 
-    my ($new_status) = @_ ;
-    my $out_hash = &create_xml_hash("update_status", $client_address, $server_address);      
-    &add_content2xml_hash($out_hash, "update_status", $new_status);
-    &send_msg_hash2address($out_hash, $server_address);
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  
-#   PARAMETERS:
-#      RETURNS: 
-#  DESCRIPTION: 
-#===============================================================================
-sub server_leaving {
-    my ($msg_hash) = @_ ;
-    my $source = &get_content_from_xml_hash("source");
-    my $header = &get_content_from_xml_hash("header");
-    
-    daemon_log("gosa daemon $source is going down, cause registration procedure", 1);
-    my $server_address = "none";
-    my $server_passwd = "none";
-    my $server_cipher = "none";
-
-    # reinitialization of default values in config file
-    &read_configfile;
-    
-    # registrated at new daemon
-    &register_at_server();
-       
-    return;   
-}
-
-
-sub got_ping {
-    my ($msg_hash) = @_ ;
-
-    my $source = &get_content_from_xml_hash($msg_hash, 'source');
-    my $target = &get_content_from_xml_hash($msg_hash, 'target');
-    my $header = &get_content_from_xml_hash($msg_hash, 'header');    
-    
-    &add_content2known_hosts(hostname=>$target, status=>$header);
-    
-    my $out_hash = &create_xml_hash("got_ping", $target, $source);
-    &send_msg_hash2address($out_hash, $source, $server_passwd);
-
-    return;
-}
-
-
-sub new_ldap_config {
-    my ($msg_hash) = @_ ;
-
-    my @gotoLdapServer = &get_content_from_xml_hash($msg_hash, "new_ldap_config");
-    print Dumper @gotoLdapServer;
-
-
-    return;
-
-}
-
-
-sub execute_event {
-    my ($msg_hash)= @_;
-    my $configdir= '/etc/gosac/events/';
-    my $result;
-
-    my $header = &get_content_from_xml_hash($msg_hash, 'header');
-    my $source = &get_content_from_xml_hash($msg_hash, 'source');
-    my $target = &get_content_from_xml_hash($msg_hash, 'target');
-
-
-    if((not defined $source)
-            && (not defined $target)
-            && (not defined $header)) {
-        daemon_log("ERROR: Entries missing in XML msg for gosa events under /etc/gosac/events");
-    } else {
-        my $parameters="";
-        my @params = &get_content_from_xml_hash($msg_hash, $header);
-        my $params = join(", ", @params);
-        daemon_log("execute_event: got parameters: $params", 5);
-
-        if (@params) {
-            foreach my $param (@params) {
-                my $param_value = (&get_content_from_xml_hash($msg_hash, $param))[0];
-                daemon_log("execute_event: parameter -> value: $param -> $param_value", 7);
-                $parameters.= " ".$param_value;
-            }
-        }
-
-        my $cmd= $configdir.$header."$parameters";
-        daemon_log("execute_event: executing cmd: $cmd", 7);
-        $result= "";
-        open(PIPE, "$cmd 2>&1 |");
-        while(<PIPE>) {
-            $result.=$_;
-        }
-        close(PIPE);
-    }
-
-    # process the event result
-
-
-    return;
-}
-
-
-sub new_passwd {
-    # my ($msg_hash) = @_ ;
-    my $new_server_passwd = &create_passwd();
-    my $new_server_cipher = &create_ciphering($new_server_passwd);
-
-    my $out_hash = &create_xml_hash("new_passwd", $client_address, $server_address, $new_server_passwd);
-    
-    &send_msg_hash2address($out_hash, $server_address, $server_passwd);
-
-    $server_passwd = $new_server_passwd;
-    $server_cipher = $new_server_cipher;
-    return; 
-}
-
-
-
-
-#==== MAIN = main ==============================================================
-
-#  parse commandline options
-Getopt::Long::Configure( "bundling" );
-GetOptions("h|help" => \&usage,
-           "c|config=s" => \$cfg_file,
-           "f|foreground" => \$foreground,
-           "v|verbose+" => \$verbose,
-           );
-
-#  read and set config parameters
-&check_cmdline_param ;
-&read_configfile;
-&check_pid;
-
-# restart daemon log file
-if(-e $log_file ) { unlink $log_file }
-daemon_log("started!");
-
-# Just fork, if we"re not in foreground mode
-if( ! $foreground ) { $pid = fork(); }
-else { $pid = $$; }
-
-# Do something useful - put our PID into the pid_file
-if( 0 != $pid ) {
-    open( LOCK_FILE, ">$pid_file" );
-    print LOCK_FILE "$pid\n";
-    close( LOCK_FILE );
-    if( !$foreground ) { exit( 0 ) };
-}
-
-# detect own ip and mac address
-($client_ip, $client_mac_address) = &get_ip_and_mac(); 
-if (not defined $client_ip) {
-    die "EXIT: ip address of $0 could not be detected";
-}
-daemon_log("client ip address detected: $client_ip", 1);
-daemon_log("client mac address detected: $client_mac_address", 1);
-
-# prepare variables
-if (defined $server_ip && defined $server_port) {
-    $server_address = $server_ip.":".$server_port;
-}
-$client_address = $client_ip.":".$client_port;
-
-# setup xml parser
-$xml = new XML::Simple();
-
-# create input socket
-$rbits = $wbits = $ebits = "";
-$input_socket = IO::Socket::INET->new(LocalPort => $client_port,
-        Type => SOCK_STREAM,
-        Reuse => 1,
-        Listen => 20,
-        ); 
-if(not defined $input_socket){
-    daemon_log("cannot be a tcp server at $client_port : $@\n");
-} else {
-    daemon_log("start server:\n\t$server_ip:$client_port",1) ;
-    vec($rbits, fileno $input_socket, 1) = 1;
-    vec($wbits, fileno $input_socket, 1) = 1;
-}
-
-# register at server
-&register_at_server();
-
-
-##############
-# Debugging
-#############
-#sleep(2);
-#&update_status("ich_bin_ein_neuer_status");
-
-###################################
-#everything ready, okay, lets start
-###################################
-while(1) {
-    my ($rout, $wout);
-    my $nf = select($rout=$rbits, $wout=$wbits, undef, undef);
-
-    # error handling
-    if($nf < 0 ) {
-    }
-
-    # something is coming in
-    if(vec $rout, fileno $input_socket, 1) {
-        my $client = $input_socket->accept();
-        my $other_end = getpeername($client);
-        
-        if(not defined $other_end) {
-            daemon_log("client cannot be identified: $!");
-        } else {
-            my ($port, $iaddr) = unpack_sockaddr_in($other_end);
-            my $actual_ip = inet_ntoa($iaddr);
-            daemon_log("accept client from $actual_ip", 5);
-            my $in_msg = &read_from_socket($client);
-            if(defined $in_msg){
-                chomp($in_msg);
-                $in_msg = $in_msg.".".$actual_ip;
-                &process_incoming_msg($in_msg);
-
-            }
-        }
-    }
-}
-
-
-
diff --git a/contrib/daemon/gosa-si-client.conf-template b/contrib/daemon/gosa-si-client.conf-template
deleted file mode 100644 (file)
index 0c65e2c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-[general]
-log_file = /var/log/gosa-si-client.log
-pid_file = /var/run/gosa-si-client.pid
-
-[client]
-client_port = 20083
-
-[server]
-server_ip = 127.0.0.1
-server_port = 20081
-server_passwd = secret-server-password
-server_timeout = 5
-server_domain = intranet.gonicus.de
diff --git a/contrib/daemon/gosa-si-server b/contrib/daemon/gosa-si-server
deleted file mode 100755 (executable)
index 0966374..0000000
+++ /dev/null
@@ -1,2025 +0,0 @@
-#!/usr/bin/perl
-#===============================================================================
-#
-#         FILE:  gosa-sd
-#
-#        USAGE:  ./gosa-sd
-#
-#  DESCRIPTION:
-#
-#      OPTIONS:  ---
-# REQUIREMENTS:  libconfig-inifiles-perl libcrypt-rijndael-perl libxml-simple-perl libipc-shareable-perl libdata-dumper-simple-perl
-#         BUGS:  ---
-#        NOTES:
-#       AUTHOR:   (Andreas Rettenberger), <rettenberger@gonicus.de>
-#      COMPANY:
-#      VERSION:  1.0
-#      CREATED:  12.09.2007 08:54:41 CEST
-#     REVISION:  ---
-#===============================================================================
-
-
-use strict;
-use warnings;
-use Getopt::Long;
-use Config::IniFiles;
-use POSIX;
-use Time::HiRes qw( gettimeofday );
-
-use Fcntl;
-use IO::Socket::INET;
-use Crypt::Rijndael;
-use MIME::Base64;
-use Digest::MD5  qw(md5 md5_hex md5_base64);
-use XML::Simple;
-use Data::Dumper;
-use Sys::Syslog qw( :DEFAULT setlogsock);
-use Cwd;
-use File::Spec;
-use IPC::Shareable qw( :lock);
-IPC::Shareable->clean_up_all;
-
-use lib "/etc/gosad/modules";
-my $modules_path = "/etc/gosad/modules";
-
-my ($cfg_file, %cfg_defaults, $foreground, $verbose, $ping_timeout, $no_bus);
-my ($bus, $msg_to_bus, $bus_cipher);
-my ($server, $server_mac_address, $server_events);
-my ($gosa_server);
-my ($known_daemons, $shmda, $known_clients, $shmcl, $known_modules);
-my ($max_clients);
-my ($pid_file, $procid, $pid, $log_file);
-my (%free_child, %busy_child, $child_max, $child_min, %child_alive_time, $child_timeout);
-my ($arp_activ, $arp_fifo, $arp_fifo_path, $no_arp);
-
-# variables declared in config file are always set to 'our'
-our (%cfg_defaults, $log_file, $pid_file, 
-    $bus_activ, $bus_passwd, $bus_ip, $bus_port,
-    $server_activ, $server_ip, $server_port, $server_passwd, $max_clients,
-    $arp_activ, $arp_fifo_path,
-    $gosa_activ, $gosa_passwd, $gosa_ip, $gosa_port, $gosa_timeout,
-);
-
-# additional variable which should be globaly accessable
-our $xml;
-our $server_address;
-our $bus_address;
-our $gosa_address;
-
-# specifies the verbosity of the daemon_log
-$verbose = 0 ;
-
-# if foreground is not null, script will be not forked to background
-$foreground = 0 ;
-
-# specifies the timeout seconds while checking the online status of a registrating client
-$ping_timeout = 5;
-
-$no_bus = 0;
-
-$no_arp = 0;
-
-# holds all other gosa-sd as well as the gosa-sd-bus
-our $known_daemons = {};
-our $shmda = tie($known_daemons, 'IPC::Shareable', undef, {create => 1, 
-                                                            exclusive => 1, 
-                                                            mode => 0666, 
-                                                            destroy => 1,
-                                                            });
-# holds all registrated clients
-our $known_clients = {};
-our $shmcl = tie($known_clients, 'IPC::Shareable', undef, {create => 1, 
-                                                            exclusive => 1, 
-                                                            mode => 0666, 
-                                                            destroy => 1,
-                                                            });
-
-
-%cfg_defaults =
-("general" =>
-    {"log_file" => [\$log_file, "/var/run/".$0.".log"],
-    "pid_file" => [\$pid_file, "/var/run/".$0.".pid"],
-    "child_max" => [\$child_max, 10],
-    "child_min" => [\$child_min, 3],
-    "child_timeout" => [\$child_timeout, 180],
-   },
-"bus" =>
-    {"bus_activ" => [\$bus_activ, "on"],
-    "bus_passwd" => [\$bus_passwd, ""],
-    "bus_ip" => [\$bus_ip, ""],
-    "bus_port" => [\$bus_port, "20080"],
-    },
-"server" =>
-    {"server_activ" => [\$server_activ, "on"],
-    "server_ip" => [\$server_ip, ""],
-    "server_port" => [\$server_port, "20081"],
-    "server_passwd" => [\$server_passwd, ""],
-    "max_clients" => [\$max_clients, 100],
-    },
-"arp" =>
-    {"arp_activ" => [\$arp_activ, "on"],
-    "arp_fifo_path" => [\$arp_fifo_path, "/var/run/gosa-si/arp-notify"],
-    },
-"gosa" =>
-    {"gosa_activ" => [\$gosa_activ, "on"],
-    "gosa_ip" => [\$gosa_ip, ""],
-    "gosa_port" => [\$gosa_port, "20082"],
-    "gosa_passwd" => [\$gosa_passwd, "none"],
-    },
-    );
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  usage
-#   PARAMETERS:  nothing
-#      RETURNS:  nothing
-#  DESCRIPTION:  print out usage text to STDERR
-#===============================================================================
-sub usage {
-    print STDERR << "EOF" ;
-usage: $0 [-hvf] [-c config]
-
-           -h        : this (help) message
-           -c <file> : config file
-           -f        : foreground, process will not be forked to background
-           -v        : be verbose (multiple to increase verbosity)
-EOF
-    print "\n" ;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  read_configfile
-#   PARAMETERS:  cfg_file - string -
-#      RETURNS:  nothing
-#  DESCRIPTION:  read cfg_file and set variables
-#===============================================================================
-sub read_configfile {
-    my $cfg;
-    if( defined( $cfg_file) && ( length($cfg_file) > 0 )) {
-        if( -r $cfg_file ) {
-            $cfg = Config::IniFiles->new( -file => $cfg_file );
-        } else {
-            print STDERR "Couldn't read config file!";
-        }
-    } else {
-        $cfg = Config::IniFiles->new() ;
-    }
-    foreach my $section (keys %cfg_defaults) {
-        foreach my $param (keys %{$cfg_defaults{ $section }}) {
-            my $pinfo = $cfg_defaults{ $section }{ $param };
-            ${@$pinfo[ 0 ]} = $cfg->val( $section, $param, @$pinfo[ 1 ] );
-        }
-    }
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  logging
-#   PARAMETERS:  level - string - default 'info'
-#                msg - string -
-#                facility - string - default 'LOG_DAEMON'
-#      RETURNS:  nothing
-#  DESCRIPTION:  function for logging
-#===============================================================================
-sub daemon_log {
-# log into log_file
-    my( $msg, $level ) = @_;
-    if(not defined $msg) { return }
-    if(not defined $level) { $level = 1 }
-    if(defined $log_file){
-        open(LOG_HANDLE, ">>$log_file");
-        if(not defined open( LOG_HANDLE, ">>$log_file" )) {
-            print STDERR "cannot open $log_file: $!";
-            return }
-            chomp($msg);
-            if($level <= $verbose){
-                print LOG_HANDLE "$level $msg\n";
-                if(defined $foreground) { print $msg."\n" }
-            }
-    }
-    close( LOG_HANDLE );
-#log into syslog
-#    my ($msg, $level, $facility) = @_;
-#    if(not defined $msg) {return}
-#    if(not defined $level) {$level = "info"}
-#    if(not defined $facility) {$facility = "LOG_DAEMON"}
-#    openlog($0, "pid,cons,", $facility);
-#    syslog($level, $msg);
-#    closelog;
-#    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  check_cmdline_param
-#   PARAMETERS:  nothing
-#      RETURNS:  nothing
-#  DESCRIPTION:  validates commandline parameter
-#===============================================================================
-sub check_cmdline_param () {
-    my $err_config;
-    my $err_counter = 0;
-    if( not defined( $cfg_file)) {
-        #$err_config = "please specify a config file";
-        #$err_counter += 1;
-        my $cwd = getcwd;
-        my $name = "/etc/gosa/gosa-si-server.conf";
-        $cfg_file = File::Spec->catfile( $cwd, $name );
-        print STDERR "no conf file specified\n   try to use default: $cfg_file\n";       
-    }
-    if( $err_counter > 0 ) {
-        &usage( "", 1 );
-        if( defined( $err_config)) { print STDERR "$err_config\n"}
-        print STDERR "\n";
-        exit( -1 );
-    }
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  check_pid
-#   PARAMETERS:  nothing
-#      RETURNS:  nothing
-#  DESCRIPTION:  handels pid processing
-#===============================================================================
-sub check_pid {
-    $pid = -1;
-    # Check, if we are already running
-    if( open(LOCK_FILE, "<$pid_file") ) {
-        $pid = <LOCK_FILE>;
-        if( defined $pid ) {
-            chomp( $pid );
-            if( -f "/proc/$pid/stat" ) {
-                my($stat) = `cat /proc/$pid/stat` =~ m/$pid \((.+)\).*/;
-                if( $0 eq $stat ) {
-                    close( LOCK_FILE );
-                    exit -1;
-                }
-            }
-        }
-        close( LOCK_FILE );
-        unlink( $pid_file );
-    }
-
-    # create a syslog msg if it is not to possible to open PID file
-    if (not sysopen(LOCK_FILE, $pid_file, O_WRONLY|O_CREAT|O_EXCL, 0644)) {
-        my($msg) = "Couldn't obtain lockfile '$pid_file' ";
-        if (open(LOCK_FILE, '<', $pid_file)
-                && ($pid = <LOCK_FILE>))
-        {
-            chomp($pid);
-            $msg .= "(PID $pid)\n";
-        } else {
-            $msg .= "(unable to read PID)\n";
-        }
-        if( ! ($foreground) ) {
-            openlog( $0, "cons,pid", "daemon" );
-            syslog( "warning", $msg );
-            closelog();
-        }
-        else {
-            print( STDERR " $msg " );
-        }
-        exit( -1 );
-    }
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  get_ip_and_mac 
-#   PARAMETERS:  nothing
-#      RETURNS:  (ip, mac) 
-#  DESCRIPTION:  executes /sbin/ifconfig and parses the output, the first occurence 
-#                of a inet address is returned as well as the mac address in the line
-#                above the inet address
-#===============================================================================
-sub get_ip_and_mac {
-    my $ip = "0.0.0.0.0"; # Defualt-IP
-    my $mac = "00:00:00:00:00:00";  # Default-MAC
-    my @ifconfig = qx(/sbin/ifconfig);
-    foreach(@ifconfig) {
-        if (/Hardware Adresse (\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2})/) {
-            $mac = "$1:$2:$3:$4:$5:$6";
-            next;
-        }
-        if (/inet Adresse:(\d+).(\d+).(\d+).(\d+)/) {
-            $ip = "$1.$2.$3.$4";
-            last;
-        }
-    }
-    return ($ip, $mac);
-}
-
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  import_modules
-#   PARAMETERS:  module_path - string - abs. path to the directory the modules are stored
-#      RETURNS:  nothing
-#  DESCRIPTION:  each file in module_path which ends with '.pm' is imported by "require 'file';"
-#===============================================================================
-sub import_modules {
-    daemon_log(" ", 1);
-
-    if (not -e $modules_path) {
-        daemon_log("ERROR: cannot find directory or directory is not readable: $modules_path", 1);   
-    }
-
-    opendir (DIR, $modules_path) or die "ERROR while loading modules from directory $modules_path : $!\n";
-    while (defined (my $file = readdir (DIR))) {
-        if (not $file =~ /(\S*?).pm$/) {
-            next;
-        }
-        eval { require $file; };
-        if ($@) {
-            daemon_log("ERROR: gosa-sd could not load module $file", 1);
-            daemon_log("$@", 5);
-            next;
-        }
-        my $mod_name = $1;
-        my $module_tag_hash = eval( $mod_name.'::get_module_tags()' );
-        $known_modules->{$mod_name} = $module_tag_hash;
-
-        daemon_log("load module $mod_name", 1);
-    }   
-
-    # for debugging
-    #while ( my ($module, $tag_hash) = each(%$known_modules)) {
-    #    print "\tmodule: $module"."\n";   
-    #    print "\ttags: ".join(", ", keys(%$tag_hash))."\n";
-    #}
-    close (DIR);
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  register_at_bus
-#   PARAMETERS:  nothing
-#      RETURNS:  nothing
-#  DESCRIPTION:  creates an entry in known_daemons and send a 'here_i_am' msg to bus
-#===============================================================================
-sub register_at_bus {
-
-    # create known_daemons entry
-    &create_known_daemon($bus_address);
-    &add_content2known_daemons(hostname=>$bus_address, status=>"register_at_bus", passwd=>$bus_passwd);
-    daemon_log("register at bus: $bus_address", 1);
-
-    my $msg_hash = &create_xml_hash("here_i_am", "$server_ip:$server_port", $bus_address);
-    &send_msg_hash2address($msg_hash, $bus_address);
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  sig_int_handler
-#   PARAMETERS:  signal - string - signal arose from system
-#      RETURNS:  noting
-#  DESCRIPTION:  handels tasks to be done befor signal becomes active
-#===============================================================================
-sub sig_int_handler {
-    my ($signal) = @_;
-    if($server){
-        close($server);
-        daemon_log("daemon server closed", 1);
-    }
-    if( -p $arp_fifo_path ) {
-        close $arp_fifo  ;
-        unlink($arp_fifo_path) ;
-        daemon_log("ARP_FIFO closed", 1) ;
-    }
-
-    if($gosa_server){
-        close($gosa_server);
-        daemon_log("gosa server closed", 1);
-    }
-
-    print STDERR "$signal\n";
-    
-    exit(1);
-}
-$SIG{INT} = \&sig_int_handler;
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  activating_child
-#   PARAMETERS:  msg - string - incoming message
-#                host - string - host from which the incomming message comes
-#      RETURNS:  nothing
-#  DESCRIPTION:  handels the distribution of incoming messages to working childs
-#===============================================================================
-sub activating_child {
-    my ($msg, $host, $client) = @_;
-    my $child = &get_processing_child();
-    my $pipe_wr = $$child{'pipe_wr'};
-    my $pipe_rd = $$child{'pipe_rd'};
-    $$child{client_ref} = $client;
-    daemon_log("activating: childpid:$$child{'pid'}", 5);
-
-    print $pipe_wr $msg.".".$host."\n";
-
-#    if (defined $client) {
-#        my $rbits = "";
-#        vec($rbits, fileno $client, 1) = 1;
-#        
-#        my ($rout);
-#        my $nf = select($rout=$rbits, undef, undef, $gosa_timeout);
-#        if($gosa_activ eq "on" && vec($rout, fileno $gosa_server, 1)) {
-#            
-#        }
-#    }
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  get_processing_child
-#   PARAMETERS:  nothing
-#      RETURNS:  child - hash - holding the process id and the references to the pipe
-#                               handles pipe_wr and pipe_rd
-#  DESCRIPTION:  handels the forking, reactivating and keeping alive tasks
-#===============================================================================
-sub get_processing_child {
-    my $child;
-    # checking %busy_child{pipe_wr} if msg is 'done', then set child from busy to free
-#    while(my ($key, $val) = each(%busy_child)) {
-#        # test ob prozess noch existiert
-#        my $exitus_pid = waitpid($key, WNOHANG);
-#        if($exitus_pid != 0) {
-#            delete $busy_child{$key};
-#            print "prozess:$key wurde aus busy_child entfernt\n";
-#            next;
-#        }
-#
-#        # check wether process sitll works
-#        my $fh = $$val{'pipe_rd'};
-#        $fh->blocking(0);
-#        my $child_answer;
-#        if(not $child_answer = <$fh>) { next }
-#        chomp($child_answer);
-#        if($child_answer eq "done") {
-#            delete $busy_child{$key};
-#            $free_child{$key} = $val;
-#        }
-#    }
-
-    while(my ($key, $val) = each(%free_child)) {
-        my $exitus_pid = waitpid($key, WNOHANG);
-        if($exitus_pid != 0) {
-            delete $free_child{$key};
-        }
-        daemon_log("free child:$key", 5);
-    }
-    # check @free_child and @busy_child
-    my $free_len = scalar(keys(%free_child));
-    my $busy_len = scalar(keys(%busy_child));
-    daemon_log("free children $free_len, busy children $busy_len", 5);
-
-    # if there is a free child, let the child work
-    if($free_len > 0){
-        my @keys = keys(%free_child);
-        $child = $free_child{$keys[0]};
-        if(defined $child) {
-            $busy_child{$$child{'pid'}} = $child ;
-            delete $free_child{$$child{'pid'}};
-        }
-        return $child;
-    }
-
-    # no free child, try to fork another one
-    if($free_len + $busy_len < $child_max) {
-
-        daemon_log("not enough children, create a new one", 5);
-
-        # New pipes for communication
-        my( $PARENT_wr, $PARENT_rd );
-        my( $CHILD_wr, $CHILD_rd );
-        pipe( $CHILD_rd,  $PARENT_wr );
-        pipe( $PARENT_rd, $CHILD_wr  );
-        $PARENT_wr->autoflush(1);
-        $CHILD_wr->autoflush(1);
-
-        ############
-        # fork child
-        ############
-        my $child_pid = fork();
-        
-        #CHILD
-        if($child_pid == 0) {
-            # Close unused pipes
-            close( $CHILD_rd );
-            close( $CHILD_wr );
-            while( 1 ) {
-                my $rbits = "";
-                vec( $rbits, fileno $PARENT_rd , 1 ) = 1;
-                my $nf = select($rbits, undef, undef, $child_timeout);
-                if($nf < 0 ) {
-                    die "select(): $!\n";
-                } elsif (! $nf) {
-                    # if already child_min childs are alive, then leave loop
-                    $free_len = scalar(keys(%free_child));
-                    $busy_len = scalar(keys(%busy_child));
-                    if($free_len + $busy_len >= $child_min) {
-                        last;
-                    } else {
-                        redo;
-                    }
-                }
-
-                # a job for a child arise
-                if ( vec $rbits, fileno $PARENT_rd, 1 ) {
-                    # read everything from pipe
-                    my $msg = "";
-                    $PARENT_rd->blocking(0);
-                    while(1) {
-                        my $read = <$PARENT_rd>;
-                        if(not defined $read) { last}
-                        $msg .= $read;
-                    }
-
-                    ######################################
-                    # forward msg to all imported modules 
-                    no strict "refs";
-                    my $answer;
-                    while( my ($module, $tag_hash) = each(%$known_modules)) {
-                        #if(exists $known_modules->{$module}->{server_packages}) {
-                            my $tmp = &{ $module."::process_incoming_msg" }($msg);
-                            if (defined $tmp) {
-                                $answer = $tmp;
-                            }
-                        #}
-                    }        
-
-                    &print_known_daemons();
-                    &print_known_clients();
-
-                    daemon_log("processing of msg finished", 5);
-
-                    if (defined $answer) {
-                        print $PARENT_wr $answer."\n";
-                        daemon_log("\t$answer", 5);
-                        daemon_log(" ", 5);
-                    } else {
-                        print $PARENT_wr "done"."\n";
-                        daemon_log(" ", 5);
-                    }
-                    redo;
-                }
-            }
-            # childs leaving the loop are allowed to die
-            exit(0);
-
-
-        #PARENT
-        } else {
-            # Close unused pipes
-            close( $PARENT_rd );
-            close( $PARENT_wr );
-
-            # add child to child alive hash
-            my %child_hash = (
-                    'pid' => $child_pid,
-                    'pipe_wr' => $CHILD_wr,
-                    'pipe_rd' => $CHILD_rd,
-                    'client_ref' => "",
-                    );
-
-            $child = \%child_hash;
-            $busy_child{$$child{'pid'}} = $child;
-            return $child;
-        }
-    }
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  process_incoming_msg
-#   PARAMETERS:  crypted_msg - string - incoming crypted message
-#      RETURNS:  nothing
-#  DESCRIPTION:  handels the proceeded distribution to the appropriated functions
-#===============================================================================
-sub process_incoming_msg {
-    my ($crypted_msg) = @_;
-    if(not defined $crypted_msg) {
-        daemon_log("function 'process_incoming_msg': got no msg", 7);
-    }
-    $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
-    $crypted_msg = $1;
-    my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
-    daemon_log("msg from host:", 1);
-    daemon_log("\t$host", 1);
-    #daemon_log("crypted msg:", 7);
-    #daemon_log("\t$crypted_msg", 7);
-
-    # collect addresses from possible incoming clients
-    my @valid_keys;
-    my @host_keys = keys %$known_daemons;
-    foreach my $host_key (@host_keys) {    
-        if($host_key =~ "^$host") {
-            push(@valid_keys, $host_key);
-        }
-    }
-    my @client_keys = keys %$known_clients;
-    foreach my $client_key (@client_keys) {
-        if($client_key =~ "^$host"){
-            push(@valid_keys, $client_key);
-        }
-    }
-    push(@valid_keys, $server_address);
-    
-    my $l = @valid_keys;
-    my ($msg, $msg_hash);
-    my $msg_flag = 0;    
-
-    # determine the correct passwd for deciphering of the incoming msgs
-    foreach my $host_key (@valid_keys) {
-        eval{
-            daemon_log( "key: $host_key", 7);
-            my $key_passwd;
-            if (exists $known_daemons->{$host_key}) {
-                $key_passwd = $known_daemons->{$host_key}->{passwd};
-            } elsif (exists $known_clients->{$host_key}) {
-                $key_passwd = $known_clients->{$host_key}->{passwd};
-            } elsif ($host_key eq $server_address) {
-                $key_passwd = $server_passwd;
-            } 
-            daemon_log("key_passwd: $key_passwd", 7);
-            my $key_cipher = &create_ciphering($key_passwd);
-            $msg = &decrypt_msg($crypted_msg, $key_cipher);
-            $msg_hash = $xml->XMLin($msg, ForceArray=>1);
-        };
-        if($@) {
-            daemon_log("key raise error", 7);
-            $msg_flag += 1;
-        } else {
-            last;
-        }
-    } 
-    
-    if($msg_flag >= $l)  {
-        daemon_log("ERROR: do not understand the message:", 1);
-        daemon_log("\t$msg", 1);
-        return;
-    }
-
-    # process incoming msg
-    my $header = &get_content_from_xml_hash($msg_hash, "header");
-    my $source = @{$msg_hash->{source}}[0];
-
-    daemon_log("header from msg:", 1);
-    daemon_log("\t$header", 1);
-    daemon_log("msg to process:", 5);
-    daemon_log("\t$msg", 5);
-
-    my @targets = @{$msg_hash->{target}};
-    my $len_targets = @targets;
-    if ($len_targets == 0){     
-        daemon_log("ERROR: no target specified for msg $header", 1);
-
-    } elsif ($len_targets == 1){
-        # we have only one target symbol
-
-        my $target = $targets[0];
-        daemon_log("msg is for:", 7);
-        daemon_log("\t$target", 7);
-
-        if ($target eq $server_address) {
-            # msg is for server
-            if ($header eq 'new_passwd'){ &new_passwd($msg_hash)}
-            elsif ($header eq 'here_i_am') { &here_i_am($msg_hash)}
-            elsif ($header eq 'who_has') { &who_has($msg_hash) }
-            elsif ($header eq 'who_has_i_do') { &who_has_i_do($msg_hash)}
-            elsif ($header eq 'update_status') { &update_status($msg_hash) }
-            #elsif ($header eq 'got_ping') { &got_ping($msg_hash)}
-            elsif ($header eq 'get_load') { &execute_actions($msg_hash)}
-            else { daemon_log("ERROR: no function assigned to this msg", 5) }
-
-        
-       } elsif ($target eq "*") {
-            # msg is for all clients
-
-            my @target_addresses = keys(%$known_clients);
-            foreach my $target_address (@target_addresses) {
-                if ($target_address eq $source) { next; }
-                $msg_hash->{target} = [$target_address];
-                &send_msg_hash2address($msg_hash, $target_address);
-            }           
-        } else {
-            # msg is for one client
-
-            if (exists $known_clients->{$target}) {
-                # target is known
-
-                &send_msg_hash2address($msg_hash, $target);
-            } else {
-                # target is not known
-
-                daemon_log("ERROR: target $target is not known in known_clients", 1);
-            }
-        }
-    } else {
-        # we have multiple target symbols
-
-        my $target_string = join(", ", @targets);
-        daemon_log("msg is for:", 7);
-        daemon_log("\t$target_string", 7);
-        
-        my $target_address;
-        foreach $target_address (@targets) {
-            if (exists $known_clients->{$target_address}) {
-                # target_address is known
-
-                &send_msg_hash2address($msg_hash, $target_address);
-                daemon_log("server forwards msg $header to client $target_address", 3);
-            } else {
-                # target is not known
-
-                daemon_log("ERROR: target $target_address is not known in known_clients", 1);
-            }
-        }
-
-
-    }
-
-   return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  open_socket
-#   PARAMETERS:  PeerAddr string something like 192.168.1.1 or 192.168.1.1:10000
-#                [PeerPort] string necessary if port not appended by PeerAddr
-#      RETURNS:  socket IO::Socket::INET
-#  DESCRIPTION:  open a socket to PeerAddr
-#===============================================================================
-sub open_socket {
-    my ($PeerAddr, $PeerPort) = @_ ;
-    if(defined($PeerPort)){
-        $PeerAddr = $PeerAddr.":".$PeerPort;
-    }
-    my $socket;
-    $socket = new IO::Socket::INET(PeerAddr => $PeerAddr ,
-            Porto => "tcp" ,
-            Type => SOCK_STREAM,
-            Timeout => 5,
-            );
-    if(not defined $socket) {
-        return;
-    }
-    daemon_log("open_socket:", 7);
-    daemon_log("\t$PeerAddr", 7);
-    return $socket;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  open_fifo
-#   PARAMETERS:  $fifo_path
-#      RETURNS:  0: FIFO couldn"t be setup, 1: FIFO setup correctly
-#  DESCRIPTION:  creates a FIFO at $fifo_path
-#===============================================================================
-sub open_fifo {
-    my ($fifo_path) = @_ ;
-    if( -p $fifo_path ) {
-        daemon_log("FIFO at $fifo_path already exists! Is being deleted!", 1);
-        unlink($fifo_path);
-    }
-    POSIX::mkfifo($fifo_path, 0666) or die "can't mkfifo $fifo_path: $!";
-    daemon_log( "FIFO started at $fifo_path", 1) ;
-    return 1;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  read_from_socket
-#   PARAMETERS:  socket fh - 
-#      RETURNS:  result string - readed characters from socket
-#  DESCRIPTION:  reads data from socket in 16 byte steps
-#===============================================================================
-sub read_from_socket {
-    my ($socket) = @_;
-    my $result = "";
-
-    $socket->blocking(1);
-    $result = <$socket>;
-
-    $socket->blocking(0);
-    while ( my $char = <$socket> ) {
-        if (not defined $char) { last }
-        $result .= $char;
-    }
-
-#    my $len = 16;
-#    while($len == 16){
-#        my $char;
-#        $len = sysread($socket, $char, 16);
-#        if($len != 16) { last }
-#        $result .= $char;
-#    }
-    return $result;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_xml_hash
-#   PARAMETERS:  header - string - message header (required)
-#                source - string - where the message come from (required)
-#                target - string - where the message should go to (required)
-#                [header_value] - string - something usefull (optional)
-#      RETURNS:  hash - hash - nomen est omen
-#  DESCRIPTION:  creates a key-value hash, all values are stored in a array
-#===============================================================================
-sub create_xml_hash {
-    my ($header, $source, $target, $header_value) = @_;
-    my $hash = {
-            header => [$header],
-            source => [$source],
-            target => [$target],
-            $header => [$header_value],
-    };
-    #daemon_log("create_xml_hash:", 7),
-    #chomp(my $tmp = Dumper $hash);
-    #daemon_log("\t$tmp", 7);
-    return $hash
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_xml_string
-#   PARAMETERS:  xml_hash - hash - hash from function create_xml_hash
-#      RETURNS:  xml_string - string - xml string representation of the hash
-#  DESCRIPTION:  transform the hash to a string using XML::Simple module
-#===============================================================================
-sub create_xml_string {
-    my ($xml_hash) = @_ ;
-    my $xml_string = $xml->XMLout($xml_hash, RootName => 'xml');
-    $xml_string =~ s/[\n]+//g;
-    #daemon_log("create_xml_string:",7);
-    #daemon_log("$xml_string\n", 7);
-    return $xml_string;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  add_content2xml_hash
-#   PARAMETERS:  xml_ref - ref - reference to a hash from function create_xml_hash
-#                element - string - key for the hash
-#                content - string - value for the hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  add key-value pair to xml_ref, if key alread exists, then append value to list
-#===============================================================================
-sub add_content2xml_hash {
-    my ($xml_ref, $element, $content) = @_;
-    if(not exists $$xml_ref{$element} ) {
-        $$xml_ref{$element} = [];
-    }
-    my $tmp = $$xml_ref{$element};
-    push(@$tmp, $content);
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  get_content_from_xml_hash
-#   PARAMETERS:  xml_ref - ref - reference of the xml hash
-#                element - string - key of the value you want
-#      RETURNS:  value - string - if key is either header, target or source
-#                value - list - for all other keys in xml hash
-#  DESCRIPTION:
-#===============================================================================
-sub get_content_from_xml_hash {
-    my ($xml_ref, $element) = @_ ;
-    my $result = $xml_ref->{$element};
-    if( $element eq "header" || $element eq "target" || $element eq "source") {
-        return @$result[0];
-    }
-    return @$result;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  encrypt_msg
-#   PARAMETERS:  msg - string - message to encrypt
-#                my_cipher - ref - reference to a Crypt::Rijndael object
-#      RETURNS:  crypted_msg - string - crypted message
-#  DESCRIPTION:  crypts the incoming message with the Crypt::Rijndael module
-#===============================================================================
-sub encrypt_msg {
-    my ($msg, $my_cipher) = @_;
-    if(not defined $my_cipher) { print "no cipher object\n"; }
-    $msg = "\0"x(16-length($msg)%16).$msg;
-    my $crypted_msg = $my_cipher->encrypt($msg);
-    chomp($crypted_msg = &encode_base64($crypted_msg));
-    return $crypted_msg;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  decrypt_msg
-#   PARAMETERS:  crypted_msg - string - message to decrypt
-#                my_cipher - ref - reference to a Crypt::Rijndael object
-#      RETURNS:  msg - string - decrypted message
-#  DESCRIPTION:  decrypts the incoming message with the Crypt::Rijndael module
-#===============================================================================
-sub decrypt_msg {
-    my ($crypted_msg, $my_cipher) = @_ ;
-    $crypted_msg = &decode_base64($crypted_msg);
-    my $msg = $my_cipher->decrypt($crypted_msg); 
-    $msg =~ s/\0*//g;
-    return $msg;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_ciphering
-#   PARAMETERS:  passwd - string - used to create ciphering
-#      RETURNS:  cipher - object
-#  DESCRIPTION:  creates a Crypt::Rijndael::MODE_CBC object with passwd as key
-#===============================================================================
-sub create_ciphering {
-    my ($passwd) = @_;
-    $passwd = substr(md5_hex("$passwd") x 32, 0, 32);
-    my $iv = substr(md5_hex('GONICUS GmbH'),0, 16);
-
-    #daemon_log("iv: $iv", 7);
-    #daemon_log("key: $passwd", 7);
-    my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC());
-    $my_cipher->set_iv($iv);
-    return $my_cipher;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  send_msg_hash2address
-#   PARAMETERS:  msg_hash - hash - xml_hash created with function create_xml_hash
-#                PeerAddr string - socket address to send msg
-#                PeerPort string - socket port, if not included in socket address
-#      RETURNS:  nothing
-#  DESCRIPTION:  ????
-#===============================================================================
-sub send_msg_hash2address {
-    my ($msg_hash, $address, $passwd) = @_ ;
-
-    # fetch header for logging
-    my $header = &get_content_from_xml_hash($msg_hash, "header");
-    
-    # generate xml string
-    my $msg_xml = &create_xml_string($msg_hash);
-    
-    # fetch the appropriated passwd from hash 
-    if(not defined $passwd) {
-        if(exists $known_daemons->{$address}) {
-            $passwd = $known_daemons->{$address}->{passwd};
-        } elsif(exists $known_clients->{$address}) {
-            $passwd = $known_clients->{$address}->{passwd};
-            
-        } else {
-            daemon_log("$address not known, neither as server nor as client", 1);
-            return;
-        }
-    }
-    
-    # create ciphering object
-    my $act_cipher = &create_ciphering($passwd);
-    
-    # encrypt xml msg
-    my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher);
-    
-    # opensocket
-    my $socket = &open_socket($address);
-    if(not defined $socket){
-        daemon_log( "cannot send '$header'-msg to $address , server not reachable", 5);
-
-        if (exists $known_clients->{$address}) {
-            if ($known_clients->{$address}->{status} eq "down") {
-                # if status of not reachable client is already 'down', then delete client from known_clients
-                &clean_up_known_clients($address);
-
-            } else {
-                # update status to 'down'
-                &update_known_clients(hostname=>$address, status=>"down");        
-
-            }
-        }
-        return;
-    }
-    
-    # send xml msg
-    print $socket $crypted_msg."\n";
-    
-    close $socket;
-
-    daemon_log("send '$header'-msg to $address", 1);
-
-    daemon_log("$msg_xml", 5);
-
-    #daemon_log("crypted message:",7);
-    #daemon_log("\t$crypted_msg", 7);
-
-    # update status of client in known_clients with last send msg
-    if(exists $known_daemons->{$address}) {
-        #&update_known_daemons();
-    } elsif(exists $known_clients->{$address}) {
-        &update_known_clients(hostname=>$address, status=>$header);
-    }
-
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  send_msg_hash2bus
-#   PARAMETERS:  msg_hash - hash - xml_hash created with function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  ????
-#===============================================================================
-sub send_msg_hash2bus {
-    my($msg_hash) = @_;
-
-    # fetch header for logging
-    my $header = &get_content_from_xml_hash($msg_hash, "header");    
-
-    # generate xml string
-    my $msg_xml = &create_xml_string($msg_hash);
-
-    # encrypt xml msg 
-    my $crypted_msg = &encrypt_msg($msg_xml, $bus_cipher);
-
-    # open socket
-    my $socket = &open_socket($bus_address);
-    if(not defined $socket){
-        daemon_log( "cannot send '$header'-msg to $bus_address , bus not reachable", 5);
-        return;
-    }
-    
-    # send xml msg
-    print $socket $crypted_msg."\n";
-    
-    close $socket;
-   
-
-    daemon_log("send '$header'-msg to bus", 1);
-    daemon_log("$msg_xml", 5);
-    #daemon_log("crypted msg:",7);
-    #daemon_log("\t$crypted_msg", 7);
-
-    return;
-}
-
-
-
-
-
-
-
-##===  FUNCTION  ================================================================
-##         NAME:  new_passwd
-##   PARAMETERS:  msg_hash - ref - hash from function create_xml_hash
-##      RETURNS:  nothing
-##  DESCRIPTION:  process this incoming message
-##===============================================================================
-#sub new_passwd {
-#    my ($msg_hash) = @_;
-#    
-#    my $source = &get_content_from_xml_hash($msg_hash, "source");
-#    my $passwd = (&get_content_from_xml_hash($msg_hash, "new_passwd"))[0];
-#
-#    if (exists $known_daemons->{$source}) {
-#        &add_content2known_daemons(hostname=>$source, status=>"new_passwd", passwd=>$passwd);
-#        $bus_cipher = &create_ciphering($passwd);
-#        my $hash = &create_xml_hash("confirm_new_passwd", "$server_ip:$server_port", "$source");
-#        &send_msg_hash2address($hash, $source);
-#
-#    } elsif (exists $known_clients->{$source}) {
-#        &add_content2known_clients(hostname=>$source, status=>"new_passwd", passwd=>$passwd);
-#
-#    } else {
-#        daemon_log("ERROR: $source not known, neither in known_daemons nor in known_clients", 1)   
-#    }
-#
-#    return;
-#}
-
-
-##===  FUNCTION  ================================================================
-##         NAME:  make ping
-##   PARAMETERS:  address - string - address which should be pinged
-##      RETURNS:  nothing
-##  DESCRIPTION:  send ping message to address
-##===============================================================================
-#sub make_ping {
-#    my ($msg_hash) = @_;
-#
-#    my $source = &get_content_from_xml_hash($msg_hash, "source");
-#    my $target = &get_content_from_xml_hash($msg_hash, "target");
-#    
-#    print "make_ping:$source\n";
-#    my $out_hash = &create_xml_hash("ping", $target, $source);
-#    &send_msg_hash2address($out_hash, $source);
-#    return;
-#}
-
-
-##===  FUNCTION  ================================================================
-##         NAME:  got_ping
-##   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-##      RETURNS:  nothing
-##  DESCRIPTION:  process this incoming message
-##===============================================================================
-#sub got_ping {
-#    my ($msg_hash) = @_;
-#    
-#    my $source = &get_content_from_xml_hash($msg_hash, 'source');
-#    my $target = &get_content_from_xml_hash($msg_hash, 'target');
-#    my $header = &get_content_from_xml_hash($msg_hash, 'header');    
-#    
-#    if(exists $known_daemons->{$source}) {
-#        &add_content2known_daemons(hostname=>$source, status=>$header);
-#    } else {
-#        &add_content2known_clients(hostname=>$source, status=>$header);
-#    }
-#    
-#    return;
-#}
-
-
-##===  FUNCTION  ================================================================
-##         NAME:  here_i_am
-##   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-##      RETURNS:  nothing
-##  DESCRIPTION:  process this incoming message
-##===============================================================================
-#sub here_i_am {
-#    my ($msg_hash) = @_;
-#
-#    my $source = &get_content_from_xml_hash($msg_hash, "source");
-#    my $mac_address = (&get_content_from_xml_hash($msg_hash, "mac_address"))[0]; 
-#    my $out_hash;
-#
-#    # number of known clients
-#    my $nu_clients = keys %$known_clients;
-#
-#    # check wether client address or mac address is already known
-#    if (exists $known_clients->{$source}) {
-#        daemon_log("WARNING: $source is already known as a client", 1);
-#        daemon_log("WARNING: values for $source are being overwritten", 1);   
-#        $nu_clients --;
-#    }
-#
-#    # number of actual activ clients
-#    my $act_nu_clients = $nu_clients;
-#
-#    daemon_log("number of actual activ clients: $act_nu_clients", 5);
-#    daemon_log("number of maximal allowed clients: $max_clients", 5);
-#
-#    if($max_clients <= $act_nu_clients) {
-#        my $out_hash = &create_xml_hash("denied", $server_address, $source);
-#        &add_content2xml_hash($out_hash, "denied", "I_cannot_take_any_more_clients!");
-#        my $passwd = (&get_content_from_xml_hash($msg_hash, "new_passwd"))[0];
-#        &send_msg_hash2address($out_hash, $source, $passwd);
-#        return;
-#    }
-#    
-#    # new client accepted
-#    my $new_passwd = (&get_content_from_xml_hash($msg_hash, "new_passwd"))[0];
-#
-#    # create known_daemons entry
-#    my $events = (&get_content_from_xml_hash($msg_hash, "events"))[0];
-#    &create_known_client($source);
-#    &add_content2known_clients(hostname=>$source, events=>$events, mac_address=>$mac_address, 
-#                                status=>"registered", passwd=>$new_passwd);
-#
-#    # return acknowledgement to client
-#    $out_hash = &create_xml_hash("registered", $server_address, $source);
-#    &send_msg_hash2address($out_hash, $source);
-#
-#    # notify registered client to bus
-#    $out_hash = &create_xml_hash("new_client", $server_address, $bus_address, $source);
-#    &send_msg_hash2bus($out_hash);
-#
-#    # give the new client his ldap config
-#    &new_ldap_config($source);
-#
-#    return;
-#}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  who_has
-#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-#      RETURNS:  nothing 
-#  DESCRIPTION:  process this incoming message
-#===============================================================================
-#sub who_has {
-#    my ($msg_hash) = @_ ;
-#    
-#    # what is your search pattern
-#    my $search_pattern = (&get_content_from_xml_hash($msg_hash, "who_has"))[0];
-#    my $search_element = (&get_content_from_xml_hash($msg_hash, $search_pattern))[0];
-#    daemon_log("who_has-msg looking for $search_pattern $search_element", 7);
-#
-#    # scanning known_clients for search_pattern
-#    my @host_addresses = keys %$known_clients;
-#    my $known_clients_entries = length @host_addresses;
-#    my $host_address;
-#    foreach my $host (@host_addresses) {
-#        my $client_element = $known_clients->{$host}->{$search_pattern};
-#        if ($search_element eq $client_element) {
-#            $host_address = $host;
-#            last;
-#        }
-#    }
-#        
-#    # search was successful
-#    if (defined $host_address) {
-#        my $source = @{$msg_hash->{source}}[0];
-#        my $out_msg = &create_xml_hash("who_has_i_do", $server_address, $source, "mac_address");
-#        &add_content2xml_hash($out_msg, "mac_address", $search_element);
-#        &send_msg_hash2address($out_msg, $bus_address);
-#    }
-#    return;
-#}
-
-
-#sub who_has_i_do {
-#    my ($msg_hash) = @_ ;
-#    my $header = &get_content_from_xml_hash($msg_hash, "header");
-#    my $source = &get_content_from_xml_hash($msg_hash, "source");
-#    my $search_param = (&get_content_from_xml_hash($msg_hash, $header))[0];
-#    my $search_value = (&get_content_from_xml_hash($msg_hash, $search_param))[0];
-#    print "\ngot msg $header:\nserver $source has client with $search_param $search_value\n";
-#}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  update_status
-#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  process this incoming message
-#===============================================================================
-#sub update_status {
-#    my ($msg_hash) = @_;
-#    my $header = &get_content_from_xml_hash($msg_hash, "header");
-#    my $source = &get_content_from_xml_hash($msg_hash, "source");
-#    my $new_status = (&get_content_from_xml_hash($msg_hash, "update_status"))[0];
-#    
-#    # find the source
-#    my $act_known_hash;
-#    if (exists $known_daemons->{$source}) {
-#        
-#        &add_content2known_daemons(hostname=>$source, status=>$new_status);
-#    } elsif (exists $known_clients->{$source}) {
-#        &update_known_clients(hostname=>$source, status=>$new_status);
-#        #&add_content2known_clients(hostname=>$source, status=>$new_status);
-#    } else {
-#        daemon_log("ERROR: got $header-msg, but cannot find $source in my hashes, unable to update status", 1);
-#        return;
-#    }
-#
-#   return;
-#}
-
-
-##===  FUNCTION  ================================================================
-##         NAME:  new_ldap_config
-##   PARAMETERS:  address - string - ip address and port of a host
-##      RETURNS:  nothing
-##  DESCRIPTION:  send to address the ldap configuration found for dn gotoLdapServer
-##===============================================================================
-#sub new_ldap_config {
-#    my ($address) = @_ ;
-#    
-#    if (not exists $known_clients->{$address}) {
-#        daemon_log("ERROR: $address does not exist in known_clients, cannot send him his ldap config", 1);
-#        return;
-#    }
-#    
-#    my $mac_address = $known_clients->{$address}->{"mac_address"};
-#    if (not defined $mac_address) {
-#        daemon_log("ERROR: no mac address found for client $address", 1);
-#        return;
-#    }
-#
-#    # fetch dn
-#    my $goHard_cmd = "ldapsearch -x '(&(objectClass=goHard)(macAddress=00:11:22:33:44:57))' dn gotoLdapServer";
-#    my $dn;
-#    my @gotoLdapServer;
-#    open (PIPE, "$goHard_cmd 2>&1 |");
-#    while(<PIPE>) {
-#        chomp $_;
-#        # If it's a comment, goto next
-#        if ($_ =~ m/^[#]/) { next;}
-#        if ($_ =~ m/^dn: ([\S]+?)$/) {
-#            $dn = $1;
-#        } elsif ($_ =~ m/^gotoLdapServer: ([\S]+?)$/) {
-#            push(@gotoLdapServer, $1);
-#        }
-#    }
-#    close(PIPE);
-#    
-#    # no dn found
-#    if (not defined $dn) {
-#        daemon_log("ERROR: no dn arose from command: $goHard_cmd", 1);
-#        return;
-#    }
-#    
-#    # no gotoLdapServer found
-#    my $gosaGroupOfNames_cmd = "ldapsearch -x '(&(objectClass=gosaGroupOfNames)(member=$dn))' gotoLdapServer";
-#    if (@gotoLdapServer == 0) {
-#        open (PIPE, "$gosaGroupOfNames_cmd 2>&1 |");
-#        while(<PIPE>) {
-#            chomp $_;
-#            if ($_ =~ m/^[#]/) { next; }
-#            if ($_ =~ m/^gotoLdapServer: ([\S]+?)$/) {
-#                push(@gotoLdapServer, $1);
-#            }
-#        }
-#        close(PIPE);
-#    }
-#
-#    # still no gotoLdapServer found
-#    if (@gotoLdapServer == 0) {
-#        daemon_log("ERROR: cannot find gotoLdapServer entry in command: $gosaGroupOfNames_cmd", 1);
-#        return;
-#    }
-#
-#    # sort @gotoLdapServer and then split of ranking
-#    my @sorted_gotoLdapServer = sort(@gotoLdapServer);
-#    @gotoLdapServer = reverse(@sorted_gotoLdapServer);
-#    foreach (@gotoLdapServer) {
-#        $_ =~ s/^\d://;
-#    }
-#
-#    my $t = join(" ", @gotoLdapServer);
-# 
-#    my $out_hash = &create_xml_hash("new_ldap_config", $server_address, $address);
-#    map(&add_content2xml_hash($out_hash, "new_ldap_config", $_), @gotoLdapServer);
-#    &send_msg_hash2address($out_hash, $address);
-#
-#    return;
-#}
-
-
-##===  FUNCTION  ================================================================
-##         NAME:  execute_actions
-##   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-##      RETURNS:  nothing
-##  DESCRIPTION:  invokes the script specified in msg_hash which is located under
-##                /etc/gosad/actions
-##===============================================================================
-#sub execute_actions {
-#    my ($msg_hash) = @_ ;
-#    my $configdir= '/etc/gosad/actions/';
-#    my $result;
-#
-#    my $header = &get_content_from_xml_hash($msg_hash, 'header');
-#    my $source = &get_content_from_xml_hash($msg_hash, 'source');
-#    my $target = &get_content_from_xml_hash($msg_hash, 'target');
-#
-#
-#    if((not defined $source)
-#            && (not defined $target)
-#            && (not defined $header)) {
-#        daemon_log("ERROR: Entries missing in XML msg for gosad actions under /etc/gosad/actions");
-#    } else {
-#        my $parameters="";
-#        my @params = &get_content_from_xml_hash($msg_hash, $header);
-#        my $params = join(", ", @params);
-#        daemon_log("execute_actions: got parameters: $params", 5);
-#
-#        if (@params) {
-#            foreach my $param (@params) {
-#                my $param_value = (&get_content_from_xml_hash($msg_hash, $param))[0];
-#                daemon_log("execute_actions: parameter -> value: $param -> $param_value", 7);
-#                $parameters.= " ".$param_value;
-#            }
-#        }
-#
-#        my $cmd= $configdir.$header."$parameters";
-#        daemon_log("execute_actions: executing cmd: $cmd", 7);
-#        $result= "";
-#        open(PIPE, "$cmd 2>&1 |");
-#        while(<PIPE>) {
-#            $result.=$_;
-#        }
-#        close(PIPE);
-#    }
-#
-#    # process the event result
-#
-#
-#    return;
-#}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  print_known_daemons
-#   PARAMETERS:  nothing
-#      RETURNS:  nothing
-#  DESCRIPTION:  nomen est omen
-#===============================================================================
-sub print_known_daemons {
-    my ($tmp) = @_ ;
-    print "####################################\n";
-    print "# status of known_daemons\n";
-    $shmda->shlock(LOCK_EX);
-    my @hosts = keys %$known_daemons;
-    foreach my $host (@hosts) {
-        my $status = $known_daemons->{$host}->{status} ;
-        my $passwd = $known_daemons->{$host}->{passwd};
-        my $timestamp = $known_daemons->{$host}->{timestamp};
-        print "$host\n";
-        print "\tstatus:    $status\n";
-        print "\tpasswd:    $passwd\n";
-        print "\ttimestamp: $timestamp\n";
-    }
-    $shmda->shunlock(LOCK_EX);
-    print "####################################\n";
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_known_daemon
-#   PARAMETERS:  hostname - string - key for the hash known_daemons
-#      RETURNS:  nothing
-#  DESCRIPTION:  creates a dummy entry for hostname in known_daemons
-#===============================================================================
-sub create_known_daemon {
-    my ($hostname) = @_;
-    $shmda->shlock(LOCK_EX);
-    $known_daemons->{$hostname} = {};
-    $known_daemons->{$hostname}->{status} = "none";
-    $known_daemons->{$hostname}->{passwd} = "none";
-    $known_daemons->{$hostname}->{timestamp} = "none";
-    $shmda->shunlock(LOCK_EX); 
-    return;  
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  add_content2known_daemons
-#   PARAMETERS:  hostname - string - ip address and port of host (required)
-#                status - string - (optional)
-#                passwd - string - (optional)
-#                mac_address - string - mac address of host (optional)
-#      RETURNS:  nothing
-#  DESCRIPTION:  nome est omen and updates each time the timestamp of hostname
-#===============================================================================
-sub add_content2known_daemons {
-    my $arg = {
-        hostname => undef, status => undef, passwd => undef,
-        mac_address => undef, events => undef, 
-        @_ };
-    my $hostname = $arg->{hostname};
-    my $status = $arg->{status};
-    my $passwd = $arg->{passwd};
-    my $mac_address = $arg->{mac_address};
-    my $events = $arg->{events};
-
-    if (not defined $hostname) {
-        daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1);
-        return;
-    }
-
-    my ($seconds, $minutes, $hours, $monthday, $month,
-    $year, $weekday, $yearday, $sommertime) = localtime(time);
-    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
-    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
-    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
-    $month+=1;
-    $month = $month < 10 ? $month = "0".$month : $month;
-    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
-    $year+=1900;
-    my $t = "$year$month$monthday$hours$minutes$seconds";
-    
-    $shmda->shlock(LOCK_EX);
-    if (defined $status) {
-        $known_daemons->{$hostname}->{status} = $status;
-    }
-    if (defined $passwd) {
-        $known_daemons->{$hostname}->{passwd} = $passwd;
-    }
-    if (defined $mac_address) {
-        $known_daemons->{$hostname}->{mac_address} = $mac_address;
-    }
-    if (defined $events) {
-        $known_daemons->{$hostname}->{events} = $events;
-    }
-    $known_daemons->{$hostname}->{timestamp} = $t;
-    $shmda->shlock(LOCK_EX);
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  update_known_daemons
-#   PARAMETERS:  hostname - string - ip address and port of host (required)
-#                status - string - (optional)
-#                passwd - string - (optional)
-#                client - string - ip address and port of client (optional)
-#      RETURNS:  nothing
-#  DESCRIPTION:  nome est omen and updates each time the timestamp of hostname
-#===============================================================================
-sub update_known_daemons {
-    my $arg = {
-        hostname => undef, status => undef, passwd => undef,
-        @_ };
-    my $hostname = $arg->{hostname};
-    my $status = $arg->{status};
-    my $passwd = $arg->{passwd};
-
-    if (not defined $hostname) {
-        daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1);
-        return;
-    }
-
-    my ($seconds, $minutes, $hours, $monthday, $month,
-    $year, $weekday, $yearday, $sommertime) = localtime(time);
-    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
-    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
-    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
-    $month+=1;
-    $month = $month < 10 ? $month = "0".$month : $month;
-    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
-    $year+=1900;
-    my $t = "$year$month$monthday$hours$minutes$seconds";
-
-    $shmda->shlock(LOCK_EX);
-    if (defined $status) {
-        $known_daemons->{$hostname}->{status} = $status;
-    }
-    if (defined $passwd) {
-        $known_daemons->{$hostname}->{passwd} = $passwd;
-    }
-    $known_daemons->{$hostname}->{timestamp} = $t;
-    $shmda->shunlock(LOCK_EX);
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  print_known_clients 
-#   PARAMETERS:  nothing
-#      RETURNS:  nothing
-#  DESCRIPTION:  nomen est omen
-#===============================================================================
-sub print_known_clients {
-
-    print "####################################\n";
-    print "# status of known_clients\n";
-    $shmcl->shlock(LOCK_EX);
-    my @hosts = keys %$known_clients;
-    if (@hosts) {
-        foreach my $host (@hosts) {
-            my $status = $known_clients->{$host}->{status} ;
-            my $passwd = $known_clients->{$host}->{passwd};
-            my $timestamp = $known_clients->{$host}->{timestamp};
-            my $mac_address = $known_clients->{$host}->{mac_address};
-            my $events = $known_clients->{$host}->{events};
-            print "$host\n";
-            print "\tstatus:      $status\n";
-            print "\tpasswd:      $passwd\n";
-            print "\ttimestamp:   $timestamp\n";
-            print "\tmac_address: $mac_address\n";
-            print "\tevents:      $events\n";
-        }
-    }
-    $shmcl->shunlock(LOCK_EX);
-    print "####################################\n";
-    return;
-}
-
-
-
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  create_known_client
-#   PARAMETERS:  hostname - string - key for the hash known_clients
-#      RETURNS:  nothing
-#  DESCRIPTION:  creates a dummy entry for hostname in known_clients
-#===============================================================================
-sub create_known_client {
-    my ($hostname) = @_;
-    $shmcl->shlock(LOCK_EX);
-    $known_clients->{$hostname} = {};
-    $known_clients->{$hostname}->{status} = "none";
-    $known_clients->{$hostname}->{passwd} = "none";
-    $known_clients->{$hostname}->{timestamp} = "none";
-    $known_clients->{$hostname}->{mac_address} = "none";
-    $known_clients->{$hostname}->{events} = "none";
-    $shmcl->shunlock(LOCK_EX); 
-    return;  
-}
-
-
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  add_content2known_clients
-#   PARAMETERS:  hostname - string - ip address and port of host (required)
-#                status - string - (optional)
-#                passwd - string - (optional)
-#                mac_address - string - (optional)
-#                events - string - event of client, executable skripts under /etc/gosac/events
-#      RETURNS:  nothing
-#  DESCRIPTION:  nome est omen and updates each time the timestamp of hostname
-#===============================================================================
-sub add_content2known_clients {
-    my $arg = {
-        hostname => undef, status => undef, passwd => undef,
-        mac_address => undef, events => undef, 
-        @_ };
-    my $hostname = $arg->{hostname};
-    my $status = $arg->{status};
-    my $passwd = $arg->{passwd};
-    my $mac_address = $arg->{mac_address};
-    my $events = $arg->{events};
-
-    if (not defined $hostname) {
-        daemon_log("ERROR: function add_content2known_clients is not invoked with requiered parameter 'hostname'", 1);
-        return;
-    }
-
-    my ($seconds, $minutes, $hours, $monthday, $month,
-    $year, $weekday, $yearday, $sommertime) = localtime(time);
-    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
-    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
-    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
-    $month+=1;
-    $month = $month < 10 ? $month = "0".$month : $month;
-    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
-    $year+=1900;
-    my $t = "$year$month$monthday$hours$minutes$seconds";
-    
-    $shmcl->shlock(LOCK_EX);
-    if (defined $status) {
-        $known_clients->{$hostname}->{status} = $status;
-    }
-    if (defined $passwd) {
-        $known_clients->{$hostname}->{passwd} = $passwd;
-    }
-    if (defined $mac_address) {
-        $known_clients->{$hostname}->{mac_address} = $mac_address;
-    }
-    if (defined $events) {
-        $known_clients->{$hostname}->{events} = $events;
-    }
-    $known_clients->{$hostname}->{timestamp} = $t;
-    $shmcl->shlock(LOCK_EX);
-    return;
-}
-
-#===  FUNCTION  ================================================================
-#         NAME:  
-#   PARAMETERS:  
-#      RETURNS:  
-#  DESCRIPTION:  
-#===============================================================================    
-sub clean_up_known_clients {
-    my ($address) = @_ ;
-    
-    if (not exists $known_clients->{$address}) {
-        daemon_log("cannot prune known_clients from $address, client not known", 5);
-        return;
-    }
-
-    delete $known_clients->{$address};
-
-    # send bus a msg that address was deleted from known_clients
-    my $out_hash = &create_xml_hash('delete_client', $server_address, $bus_address, $address);
-    &send_msg_hash2bus($out_hash);
-
-    daemon_log("client $address deleted from known_clients because of multiple down time", 3);
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  update_known_clients
-#   PARAMETERS:  hostname - string - ip address and port of host (required)
-#                status - string - (optional)
-#                passwd - string - (optional)
-#                client - string - ip address and port of client (optional)
-#      RETURNS:  nothing
-#  DESCRIPTION:  nome est omen and updates each time the timestamp of hostname
-#===============================================================================
-sub update_known_clients {
-    my $arg = {
-        hostname => undef, status => undef, passwd => undef,
-        mac_address => undef, events => undef,
-        @_ };
-    my $hostname = $arg->{hostname};
-    my $status = $arg->{status};
-    my $passwd = $arg->{passwd};
-    my $mac_address = $arg->{mac_address};
-    my $events = $arg->{events};
-
-    if (not defined $hostname) {
-        daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1);
-        return;
-    }
-
-    my ($seconds, $minutes, $hours, $monthday, $month,
-    $year, $weekday, $yearday, $sommertime) = localtime(time);
-    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
-    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
-    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
-    $month+=1;
-    $month = $month < 10 ? $month = "0".$month : $month;
-    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
-    $year+=1900;
-    my $t = "$year$month$monthday$hours$minutes$seconds";
-
-    $shmcl->shlock(LOCK_EX);
-    if (defined $status) {
-        $known_clients->{$hostname}->{status} = $status;
-    }
-    if (defined $passwd) {
-        $known_clients->{$hostname}->{passwd} = $passwd;
-    }
-    if (defined $mac_address) {
-        $known_clients->{$hostname}->{mac_address} = $mac_address; 
-    }
-    if (defined $events) {
-        $known_clients->{$hostname}->{events} = $events;
-    }
-    $known_clients->{$hostname}->{timestamp} = $t;
-    $shmcl->shunlock(LOCK_EX);
-    return;
-}
-
-
-
-
-
-
-
-#==== MAIN = main ==============================================================
-
-#  parse commandline options
-Getopt::Long::Configure( "bundling" );
-GetOptions("h|help" => \&usage,
-        "c|config=s" => \$cfg_file,
-        "f|foreground" => \$foreground,
-        "v|verbose+" => \$verbose,
-        "no-bus+" => \$no_bus,
-        "no-arp+" => \$no_arp,
-           );
-
-#  read and set config parameters
-&check_cmdline_param ;
-&read_configfile;
-&check_pid;
-&import_modules;
-
-$SIG{CHLD} = 'IGNORE';
-
-# restart daemon log file
-if(-e $log_file ) { unlink $log_file }
-daemon_log(" ", 1);
-daemon_log("gosad started!", 1);
-
-# Just fork, if we"re not in foreground mode
-if( ! $foreground ) { $pid = fork(); }
-else { $pid = $$; }
-
-# Do something useful - put our PID into the pid_file
-if( 0 != $pid ) {
-    open( LOCK_FILE, ">$pid_file" );
-    print LOCK_FILE "$pid\n";
-close( LOCK_FILE );
-    if( !$foreground ) { exit( 0 ) };
-}
-
-# detect own ip and mac address
-($server_ip, $server_mac_address) = &get_ip_and_mac(); 
-if (not defined $server_ip) {
-    die "EXIT: ip address of $0 could not be detected";
-}
-daemon_log("server ip address detected: $server_ip", 1);
-daemon_log("server mac address detected: $server_mac_address", 1);
-
-# setup xml parser
-$xml = new XML::Simple();
-
-# create cipher object
-$bus_cipher = &create_ciphering($bus_passwd);
-$bus_address = "$bus_ip:$bus_port";
-
-# create reading and writing vectors
-my $rbits = my $wbits = my $ebits = "";
-
-# open server socket
-$server_address = "$server_ip:$server_port";
-if($server_activ eq "on"){
-    daemon_log(" ", 1);
-    $server = IO::Socket::INET->new(LocalPort => $server_port,
-            Type => SOCK_STREAM,
-            Reuse => 1,
-            Listen => 20,
-            ); 
-    if(not defined $server){
-        daemon_log("cannot be a tcp server at $server_port : $@");
-    } else {
-        daemon_log("start server:", 1);
-        daemon_log("\t$server_ip:$server_port",1) ;
-        vec($rbits, fileno $server, 1) = 1;
-        vec($wbits, fileno $server, 1) = 1;
-    }
-}
-
-# register at bus
-if ($no_bus > 0) {
-    $bus_activ = "off"
-}
-if($bus_activ eq "on") {
-    daemon_log(" ", 1);
-    &register_at_bus();
-}
-
-
-daemon_log(" ", 1);
-
-# start arp fifo
-if ($no_arp > 0) {
-    $arp_activ = "off";
-}
-my $my_fifo;
-if($arp_activ eq "on") {
-    $my_fifo = &open_fifo($arp_fifo_path);
-    if($my_fifo == 0) { die "fifo file disappeared\n" }
-    sysopen($arp_fifo, $arp_fifo_path, O_RDWR) or die "can't read from $arp_fifo: $!" ;
-    
-    vec($rbits, fileno $arp_fifo, 1) = 1;
-}
-
-$gosa_address = "$gosa_ip:$gosa_port";
-# start gosa inferface fifos
-if ($gosa_activ eq "on") {
-    daemon_log(" ",1);
-    $gosa_server = IO::Socket::INET->new(LocalPort => $gosa_port,
-            Type => SOCK_STREAM,
-            Reuse => 1,
-            Listen => 1,
-            );
-    if (not defined $gosa_server) {
-        daemon_log("cannot start tcp server at $gosa_port for communication to gosa: $@", 1);
-    } else {
-        daemon_log("start server at for communication to gosa", 1);
-        daemon_log("\t$server_ip:$gosa_port");
-        vec($rbits, fileno $gosa_server, 1) = 1;
-        
-    }
-
-
-    #&open_fifo($gosa_fifo_in);
-    #sysopen(GOSA_FIFO_IN, $gosa_fifo_in, O_RDWR) or die "can't read from GOSA_FIFO_IN: $!" ;
-    #vec($rbits, fileno GOSA_FIFO_IN, 1) = 1;
-
-    #&open_fifo($gosa_fifo_out);
-    #sysopen(GOSA_FIFO_OUT, $gosa_fifo_out, O_RDWR) or die "can't read from GOSA_FIFO_IN: $!" ;
-    
-}
-
-
-###################################
-#everything ready, okay, lets start
-###################################
-while(1) {
-
-    # add all handles from the childs
-    while ( my ($pid, $child_hash) = each %busy_child ) {
-        
-        # check whether process still exists
-        my $exitus_pid = waitpid($pid, WNOHANG);
-        if($exitus_pid != 0) {
-            delete $busy_child{$pid};
-            next;
-        }
-     
-        # add child fhd to the listener    
-        my $fhd = $$child_hash{'pipe_rd'};
-        vec($rbits, fileno $fhd, 1) = 1;
-    }
-
-    my ($rout, $wout);
-    my $nf = select($rout=$rbits, $wout=$wbits, undef, undef);
-
-    # error handling
-    if($nf < 0 ) {
-    }
-
-    # something is coming in
-    if($server_activ eq "on" && vec($rout, fileno $server, 1)) {
-        daemon_log(" ", 1);
-        my $client = $server->accept();
-        my $other_end = getpeername($client);
-        if(not defined $other_end) {
-            daemon_log("client cannot be identified: $!");
-        } else {
-            my ($port, $iaddr) = unpack_sockaddr_in($other_end);
-            my $actual_ip = inet_ntoa($iaddr);
-            daemon_log("accept client at daemon socket from $actual_ip", 5);
-            my $in_msg = &read_from_socket($client);
-            if(defined $in_msg){
-                chomp($in_msg);
-                &activating_child($in_msg, $actual_ip);
-            } else {
-                daemon_log("cannot read from $actual_ip", 5);
-            }
-        }
-        close($client);
-    }
-
-    if($arp_activ eq "on" && vec($rout, fileno $arp_fifo, 1)) {
-        my $in_msg = <$arp_fifo>;
-        chomp($in_msg);
-        print "arp_activ: msg: $in_msg\n";
-        my $act_passwd = $known_daemons->{$bus_address}->{passwd};
-        print "arp_activ: arp_passwd: $act_passwd\n";
-
-        my $in_msg_hash = $xml->XMLin($in_msg, ForceArray=>1);
-
-        my $target = &get_content_from_xml_hash($in_msg_hash, 'target');
-
-        if ($target eq $server_address) { 
-             print "arp_activ: forward to server\n";
-            my $arp_cipher = &create_ciphering($act_passwd);
-            my $crypted_msg = &encrypt_msg($in_msg, $arp_cipher);
-            &activating_child($crypted_msg, $server_ip);
-        } else {
-            print "arp_activ: send to bus\n";
-            &send_msg_hash2address($in_msg_hash, $bus_address);
-        }
-        print "\n";
-    }
-
-    if($gosa_activ eq "on" && vec($rout, fileno $gosa_server, 1)) {
-        daemon_log(" ", 1);
-        my $client = $gosa_server->accept();
-        my $other_end = getpeername($client);
-        if(not defined $other_end) {
-            daemon_log("client cannot be identified: $!");
-        } else {
-            my ($port, $iaddr) = unpack_sockaddr_in($other_end);
-            my $actual_ip = inet_ntoa($iaddr);
-            daemon_log("accept client at gosa socket from $actual_ip", 5);
-            my $in_msg = <$client>;
-            #my $in_msg = &read_from_socket($client);
-            
-            daemon_log(">>>>>>>>>>> frisch vom socket gelesen\n!$in_msg!\n",1);
-            if(defined $in_msg){
-                chomp($in_msg);
-                &activating_child($in_msg, $actual_ip, $client);
-            } else {
-                daemon_log("cannot read from $actual_ip", 5);
-            }
-        }
-        #close($client);
-    }
-
-    # check all processing childs whether they are finished ('done') or 
-    while ( my ($pid, $child_hash) = each %busy_child ) {
-        my $fhd = $$child_hash{'pipe_rd'};
-
-        if (vec($rout, fileno $fhd, 1) ) {
-            daemon_log("process child $pid is ready to read", 5);
-
-            $fhd->blocking(1);
-            my $in_msg = <$fhd>;
-            $fhd->blocking(0);
-            my $part_in_msg;
-            while ($part_in_msg = <$fhd>) {
-                if (not defined $part_in_msg) {
-                    last;
-                }
-                $in_msg .= $part_in_msg;
-            }
-            chomp($in_msg);
-
-            daemon_log("process child read: $in_msg", 5);
-            if (not defined $in_msg) { 
-                next; 
-            } elsif ($in_msg =~ "done") {
-                delete $busy_child{$pid};
-                $free_child{$pid} = $child_hash;
-            } else {
-                my $act_client = $busy_child{$pid}{client_ref};
-                print $act_client $in_msg."\n";
-                my $act_pipe = $busy_child{$pid}{pipe_rd};
-                sleep(10);
-                close ($act_client);   
-                delete $busy_child{$pid};
-                $free_child{$pid} = $child_hash;
-
-            }
-        }
-    }
-
-
-}
diff --git a/contrib/daemon/gosa-si-server.conf-template b/contrib/daemon/gosa-si-server.conf-template
deleted file mode 100644 (file)
index 8a07a63..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-[general]
-log_file = /var/log/gosa-si-daemon.log
-pid_file = /var/run/gosa-si-daemon.pid
-child_max = 10
-child_min = 2
-child_timeout = 10
-
-[bus]
-bus_activ = on
-bus_passwd = secret-bus-password
-bus_ip = 127.0.0.1
-bus_port = 20080
-
-[server]
-server_activ = on
-server_port = 20081
-server_passwd = secret-server-password
-max_clients = 5
-
-[arp]
-arp_activ = off
-arp_fifo_path = /var/run/gosa-si/arp-notify
-
-[gosa]
-gosa_activ = on
-gosa_ip = 127.0.0.1
-gosa_port = 20082
-gosa_passwd = secret-gosa-password
-gosa_timeout = 5                   
-
diff --git a/contrib/daemon/modules/GosaPackages.pm b/contrib/daemon/modules/GosaPackages.pm
deleted file mode 100644 (file)
index ab5938d..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-package GosaPackages;
-
-use Exporter;
-@ISA = ("Exporter");
-
-# Each module has to have a function 'process_incoming_msg'. This function works as a interface to gosa-sd and recieves the msg hash from gosa-sd. 'process_incoming_function checks, wether it has a function to process the incoming msg and forward the msg to it. 
-
-
-use strict;
-use warnings;
-use GosaSupportDaemon;
-
-BEGIN{}
-
-END{}
-
-
-### START ##########################
-
-# create general settings for this module
-my $gosa_cipher = &create_ciphering($main::gosa_passwd);
-
-sub get_module_tags {
-    
-    # dort stehen drei packettypen, für die sich das modul anmelden kann, gosa-admin-packages, 
-    #   server-packages, client-packages
-    my %tag_hash = (gosa_admin_packages => "yes", 
-                    server_packages => "no", 
-                    client_packages => "no");
-    return \%tag_hash;
-}
-
-
-sub process_incoming_msg {
-    my ($crypted_msg) = @_ ;
-    if(not defined $crypted_msg) {
-        &main::daemon_log("function 'process_incoming_msg': got no msg", 7);
-    }
-    &main::daemon_log("GosaPackages: crypted_msg:$crypted_msg", 7);
-    &main::daemon_log("GosaPackages: crypted_msg len:".length($crypted_msg), 7);
-
-    $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
-    $crypted_msg = $1;
-    my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
-    &main::daemon_log("GosaPackages: crypted_msg:$crypted_msg", 7);
-    &main::daemon_log("GosaPackages: crypted_msg len:".length($crypted_msg), 7);
-
-
-    # collect addresses from possible incoming clients
-    # only gosa is allowd as incoming client
-    &main::daemon_log("GosaPackages: host_key: $host", 7);
-    &main::daemon_log("GosaPackages: key_passwd: $main::gosa_passwd", 7);
-
-    $gosa_cipher = &main::create_ciphering($main::gosa_passwd);
-    # determine the correct passwd for deciphering of the incoming msgs
-    my $msg = "";
-    my $msg_hash;
-    eval{
-        $msg = &main::decrypt_msg($crypted_msg, $gosa_cipher);
-        &main::daemon_log("GosaPackages: decrypted_msg: $msg", 7);
-
-        $msg_hash = $main::xml->XMLin($msg, ForceArray=>1);
-    };
-    if($@) {
-        &main::daemon_log("WARNING: GosaPackages do not understand the message:", 5);
-        &main::daemon_log("$@", 7);
-        return;
-    }
-
-    &main::daemon_log("GosaPackages: msg for daemon from host:", 1);
-    &main::daemon_log("\t$host", 1);
-    &main::daemon_log("GosaPackages: msg to process:", 5);
-    &main::daemon_log("\t$msg", 5);
-    
-    $msg = "gosaPackages hat was bekommen";
-    
-    my $out_cipher = &main::create_ciphering($main::gosa_passwd);
-    my $out_msg = &main::encrypt_msg($msg, $out_cipher);
-    return $out_msg;
-
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  got_ping
-#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  process this incoming message
-#===============================================================================
-sub got_ping {
-    my ($msg_hash) = @_;
-    
-    my $source = @{$msg_hash->{source}}[0];
-    my $target = @{$msg_hash->{target}}[0];
-    my $header = @{$msg_hash->{header}}[0];
-    
-    if(exists $main::known_daemons->{$source}) {
-        &main::add_content2known_daemons(hostname=>$source, status=>$header);
-    } else {
-        &main::add_content2known_clients(hostname=>$source, status=>$header);
-    }
-    
-    return;
-}
-
-
-1;
diff --git a/contrib/daemon/modules/ServerPackages.pm b/contrib/daemon/modules/ServerPackages.pm
deleted file mode 100644 (file)
index c2fc7ee..0000000
+++ /dev/null
@@ -1,455 +0,0 @@
-package ServerPackages;
-
-use Exporter;
-@ISA = ("Exporter");
-
-# Each module has to have a function 'process_incoming_msg'. This function works as a interface to gosa-sd and recieves the msg hash from gosa-sd. 'process_incoming_function checks, wether it has a function to process the incoming msg and forward the msg to it. 
-
-
-use strict;
-use warnings;
-use GosaSupportDaemon;
-
-BEGIN{}
-
-END {}
-
-
-### START ##########
-
-
-
-sub get_module_tags {
-    
-    # lese config file aus dort gibt es eine section Basic
-    # dort stehen drei packettypen, für die sich das modul anmelden kann, gosa-admin-packages, 
-    #   server-packages, client-packages
-    my %tag_hash = (gosa_admin_packages => "yes", 
-                    server_packages => "yes", 
-                    client_packages => "yes",
-                    );
-    return \%tag_hash;
-}
-
-
-sub process_incoming_msg {
-    my ($crypted_msg) = @_ ;
-    if(not defined $crypted_msg) {
-        &main::daemon_log("function 'process_incoming_msg': got no msg", 7);
-    }
-    $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
-    $crypted_msg = $1;
-    my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
-
-    # collect addresses from possible incoming clients
-    my @valid_keys;
-    my @host_keys = keys %$main::known_daemons;
-    foreach my $host_key (@host_keys) {    
-        if($host_key =~ "^$host") {
-            push(@valid_keys, $host_key);
-        }
-    }
-    my @client_keys = keys %$main::known_clients;
-    foreach my $client_key (@client_keys) {
-        if($client_key =~ "^$host"){
-            push(@valid_keys, $client_key);
-        }
-    }
-    push(@valid_keys, $main::server_address);
-    
-    my $l = @valid_keys;
-    my $msg_hash;
-    my $msg_flag = 0;    
-    my $msg = "";
-
-    # determine the correct passwd for deciphering of the incoming msgs
-    foreach my $host_key (@valid_keys) {
-        eval{
-            &main::daemon_log("ServerPackage: host_key: $host_key", 7);
-            my $key_passwd;
-            if (exists $main::known_daemons->{$host_key}) {
-                $key_passwd = $main::known_daemons->{$host_key}->{passwd};
-            } elsif (exists $main::known_clients->{$host_key}) {
-                $key_passwd = $main::known_clients->{$host_key}->{passwd};
-            } elsif ($host_key eq $main::server_address) {
-                $key_passwd = $main::server_passwd;
-            } 
-            &main::daemon_log("ServerPackage: key_passwd: $key_passwd", 7);
-            my $key_cipher = &create_ciphering($key_passwd);
-            $msg = &decrypt_msg($crypted_msg, $key_cipher);
-            &main::daemon_log("ServerPackages: decrypted msg: $msg", 7);
-            $msg_hash = $main::xml->XMLin($msg, ForceArray=>1);
-            #my $tmp = printf Dumper $msg_hash;
-            #&main::daemon_log("DEBUG: ServerPackages: xml hash: $tmp", 7);
-        };
-        if($@) {
-            &main::daemon_log("ServerPackage: key raise error: $@", 7);
-            $msg_flag += 1;
-        } else {
-            last;
-        }
-    } 
-    
-    if($msg_flag >= $l)  {
-        &main::daemon_log("WARNING: ServerPackage do not understand the message:", 5);
-        &main::daemon_log("$@", 7);
-        return;
-    }
-
-    # process incoming msg
-    my $header = @{$msg_hash->{header}}[0]; 
-    my $source = @{$msg_hash->{source}}[0];
-
-    &main::daemon_log("ServerPackages: msg from host:", 5);
-    &main::daemon_log("\t$host", 5);
-    &main::daemon_log("ServerPackages: header from msg:", 5);
-    &main::daemon_log("\t$header", 5);
-    &main::daemon_log("ServerPackages: msg to process:", 5);
-    &main::daemon_log("\t$msg", 5);
-
-    my @targets = @{$msg_hash->{target}};
-    my $len_targets = @targets;
-    if ($len_targets == 0){     
-        &main::daemon_log("ERROR: ServerPackages: no target specified for msg $header", 1);
-
-    }  elsif ($len_targets == 1){
-        # we have only one target symbol
-
-        my $target = $targets[0];
-        &main::daemon_log("SeverPackages: msg is for:", 7);
-        &main::daemon_log("\t$target", 7);
-
-        if ($target eq $main::server_address) {
-            # msg is for server
-            if ($header eq 'new_passwd'){ &new_passwd($msg_hash)}
-            elsif ($header eq 'here_i_am') { &here_i_am($msg_hash)}
-            elsif ($header eq 'who_has') { &who_has($msg_hash) }
-            elsif ($header eq 'who_has_i_do') { &who_has_i_do($msg_hash)}
-            elsif ($header eq 'update_status') { &update_status($msg_hash) }
-            elsif ($header eq 'got_ping') { &got_ping($msg_hash)}
-            elsif ($header eq 'get_load') { &execute_actions($msg_hash)}
-            else { &main::daemon_log("ERROR: ServerPackages: no function assigned to this msg", 5) }
-
-        
-       } elsif ($target eq "*") {
-            # msg is for all clients
-
-            my @target_addresses = keys(%$main::known_clients);
-            foreach my $target_address (@target_addresses) {
-                if ($target_address eq $source) { next; }
-                $msg_hash->{target} = [$target_address];
-                &send_msg_hash2address($msg_hash, $target_address);
-            }           
-        } else {
-            # msg is for one host
-
-            if (exists $main::known_clients->{$target}) {
-                &send_msg_hash2address($msg_hash, $target);
-            } elsif (exists $main::known_daemons->{$target}) {
-                # target is known
-                &send_msg_hash2address($msg_hash, $target);
-            } else {
-                # target is not known
-                &main::daemon_log("ERROR: ServerPackages: target $target is not known neither in known_clients nor in known_daemons", 1);
-            }
-        }
-    }
-
-    return ;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  got_ping
-#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  process this incoming message
-#===============================================================================
-sub got_ping {
-    my ($msg_hash) = @_;
-    
-    my $source = @{$msg_hash->{source}}[0];
-    my $target = @{$msg_hash->{target}}[0];
-    my $header = @{$msg_hash->{header}}[0];
-    
-    if(exists $main::known_daemons->{$source}) {
-        &main::add_content2known_daemons(hostname=>$source, status=>$header);
-    } else {
-        &main::add_content2known_clients(hostname=>$source, status=>$header);
-    }
-    
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  new_passwd
-#   PARAMETERS:  msg_hash - ref - hash from function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  process this incoming message
-#===============================================================================
-sub new_passwd {
-    my ($msg_hash) = @_;
-
-    my $source = @{$msg_hash->{source}}[0];
-    my $passwd = @{$msg_hash->{new_passwd}}[0];
-
-    if (exists $main::known_daemons->{$source}) {
-        &main::add_content2known_daemons(hostname=>$source, status=>"new_passwd", passwd=>$passwd);
-        my $hash = &create_xml_hash("confirm_new_passwd", $main::server_address, $source);
-        &send_msg_hash2address($hash, $source);
-
-    } elsif (exists $main::known_clients->{$source}) {
-        &main::add_content2known_clients(hostname=>$source, status=>"new_passwd", passwd=>$passwd);
-
-    } else {
-        &main::daemon_log("ERROR: $source not known, neither in known_daemons nor in known_clients", 1)   
-    }
-
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  here_i_am
-#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  process this incoming message
-#===============================================================================
-sub here_i_am {
-    my ($msg_hash) = @_;
-
-    my $source = @{$msg_hash->{source}}[0];
-    my $mac_address = @{$msg_hash->{mac_address}}[0];
-    my $out_hash;
-
-    # number of known clients
-    my $nu_clients = keys %$main::known_clients;
-
-    # check wether client address or mac address is already known
-    if (exists $main::known_clients->{$source}) {
-        &main::daemon_log("WARNING: $source is already known as a client", 1);
-        &main::daemon_log("WARNING: values for $source are being overwritten", 1);   
-        $nu_clients --;
-    }
-
-    # number of actual activ clients
-    my $act_nu_clients = $nu_clients;
-
-    &main::daemon_log("number of actual activ clients: $act_nu_clients", 5);
-    &main::daemon_log("number of maximal allowed clients: $main::max_clients", 5);
-
-    if($main::max_clients <= $act_nu_clients) {
-        my $out_hash = &create_xml_hash("denied", $main::server_address, $source);
-        &add_content2xml_hash($out_hash, "denied", "I_cannot_take_any_more_clients!");
-        my $passwd = @{$msg_hash->{new_passwd}}[0]; 
-        &send_msg_hash2address($out_hash, $source, $passwd);
-        return;
-    }
-    
-    # new client accepted
-    my $new_passwd = @{$msg_hash->{new_passwd}}[0];
-
-    # create known_daemons entry
-    my $events = @{$msg_hash->{events}}[0];
-    &main::create_known_client($source);
-    &main::add_content2known_clients(hostname=>$source, events=>$events, mac_address=>$mac_address, 
-                                status=>"registered", passwd=>$new_passwd);
-
-    # return acknowledgement to client
-    $out_hash = &create_xml_hash("registered", $main::server_address, $source);
-    &send_msg_hash2address($out_hash, $source);
-
-    # notify registered client to bus
-    $out_hash = &main::create_xml_hash("new_client", $main::server_address, $main::bus_address, $source);
-    &main::send_msg_hash2bus($out_hash);
-
-    # give the new client his ldap config
-    &new_ldap_config($source);
-
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  who_has
-#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-#      RETURNS:  nothing 
-#  DESCRIPTION:  process this incoming message
-#===============================================================================
-sub who_has {
-    my ($msg_hash) = @_ ;
-    
-    # what is your search pattern
-    my $search_pattern = @{$msg_hash->{who_has}}[0];
-    my $search_element = @{$msg_hash->{$search_pattern}}[0];
-    &main::daemon_log("who_has-msg looking for $search_pattern $search_element", 7);
-
-    # scanning known_clients for search_pattern
-    my @host_addresses = keys %$main::known_clients;
-    my $known_clients_entries = length @host_addresses;
-    my $host_address;
-    foreach my $host (@host_addresses) {
-        my $client_element = $main::known_clients->{$host}->{$search_pattern};
-        if ($search_element eq $client_element) {
-            $host_address = $host;
-            last;
-        }
-    }
-        
-    # search was successful
-    if (defined $host_address) {
-        my $source = @{$msg_hash->{source}}[0];
-        my $out_msg = &main::create_xml_hash("who_has_i_do", $main::server_address, $source, "mac_address");
-        &main::add_content2xml_hash($out_msg, "mac_address", $search_element);
-        &main::send_msg_hash2address($out_msg, $main::bus_address);
-    }
-    return;
-}
-
-
-sub who_has_i_do {
-    my ($msg_hash) = @_ ;
-    my $header = @{$msg_hash->{header}}[0];
-    my $source = @{$msg_hash->{source}}[0];
-    my $search_param = @{$msg_hash->{$header}}[0];
-    my $search_value = @{$msg_hash->{$search_param}}[0];
-    print "\ngot msg $header:\nserver $source has client with $search_param $search_value\n";
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  new_ldap_config
-#   PARAMETERS:  address - string - ip address and port of a host
-#      RETURNS:  nothing
-#  DESCRIPTION:  send to address the ldap configuration found for dn gotoLdapServer
-#===============================================================================
-sub new_ldap_config {
-    my ($address) = @_ ;
-    
-    if (not exists $main::known_clients->{$address}) {
-        &main::daemon_log("ERROR: $address does not exist in known_clients, cannot send him his ldap config", 1);
-        return;
-    }
-    
-    my $mac_address = $main::known_clients->{$address}->{"mac_address"};
-    if (not defined $mac_address) {
-        &main::daemon_log("ERROR: no mac address found for client $address", 1);
-        return;
-    }
-
-    # fetch dn
-    my $goHard_cmd = "ldapsearch -x '(&(objectClass=goHard)(macAddress=00:11:22:33:44:57))' dn gotoLdapServer";
-    my $dn;
-    my @gotoLdapServer;
-    open (PIPE, "$goHard_cmd 2>&1 |");
-#    my $rbits = "";
-#    vec($rbits, fileno PIPE, 1) = 1;
-#    my $rout;
-#    my $nf = select($rout=$rbits, undef, undef, $ldap_timeout);
-    while(<PIPE>) {
-        chomp $_;
-        # If it's a comment, goto next
-        if ($_ =~ m/^[#]/) { next;}
-        if ($_ =~ m/^dn: ([\S]+?)$/) {
-            $dn = $1;
-        } elsif ($_ =~ m/^gotoLdapServer: ([\S]+?)$/) {
-            push(@gotoLdapServer, $1);
-        }
-    }
-    close(PIPE);
-    
-    # no dn found
-    if (not defined $dn) {
-        &main::daemon_log("ERROR: no dn arose from command: $goHard_cmd", 1);
-        return;
-    }
-    
-    # no gotoLdapServer found
-    my $gosaGroupOfNames_cmd = "ldapsearch -x '(&(objectClass=gosaGroupOfNames)(member=$dn))' gotoLdapServer";
-    if (@gotoLdapServer == 0) {
-        open (PIPE, "$gosaGroupOfNames_cmd 2>&1 |");
-        while(<PIPE>) {
-            chomp $_;
-            if ($_ =~ m/^[#]/) { next; }
-            if ($_ =~ m/^gotoLdapServer: ([\S]+?)$/) {
-                push(@gotoLdapServer, $1);
-            }
-        }
-        close(PIPE);
-    }
-
-    # still no gotoLdapServer found
-    if (@gotoLdapServer == 0) {
-        &main::daemon_log("ERROR: cannot find gotoLdapServer entry in command: $gosaGroupOfNames_cmd", 1);
-        return;
-    }
-
-    # sort @gotoLdapServer and then split of ranking
-    my @sorted_gotoLdapServer = sort(@gotoLdapServer);
-    @gotoLdapServer = reverse(@sorted_gotoLdapServer);
-    foreach (@gotoLdapServer) {
-        $_ =~ s/^\d://;
-    }
-
-    my $t = join(" ", @gotoLdapServer);
-    my $out_hash = &main::create_xml_hash("new_ldap_config", $main::server_address, $address);
-    map(&main::add_content2xml_hash($out_hash, "new_ldap_config", $_), @gotoLdapServer);
-    &main::send_msg_hash2address($out_hash, $address);
-
-    return;
-}
-
-
-#===  FUNCTION  ================================================================
-#         NAME:  execute_actions
-#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
-#      RETURNS:  nothing
-#  DESCRIPTION:  invokes the script specified in msg_hash which is located under
-#                /etc/gosad/actions
-#===============================================================================
-sub execute_actions {
-    my ($msg_hash) = @_ ;
-    my $configdir= '/etc/gosad/actions/';
-    my $result;
-
-    my $header = @{$msg_hash->{header}}[0];
-    my $source = @{$msg_hash->{source}}[0];
-    my $target = @{$msg_hash->{target}}[0];
-    if((not defined $source)
-            && (not defined $target)
-            && (not defined $header)) {
-        &main::daemon_log("ERROR: Entries missing in XML msg for gosad actions under /etc/gosad/actions");
-    } else {
-        my $parameters="";
-        my @params = @{$msg_hash->{$header}};
-        my $params = join(", ", @params);
-        &main::daemon_log("execute_actions: got parameters: $params", 5);
-
-        if (@params) {
-            foreach my $param (@params) {
-                my $param_value = (&get_content_from_xml_hash($msg_hash, $param))[0];
-                &main::daemon_log("execute_actions: parameter -> value: $param -> $param_value", 7);
-                $parameters.= " ".$param_value;
-            }
-        }
-
-        my $cmd= $configdir.$header."$parameters";
-        &main::daemon_log("execute_actions: executing cmd: $cmd", 7);
-        $result= "";
-        open(PIPE, "$cmd 2>&1 |");
-        while(<PIPE>) {
-            $result.=$_;
-        }
-        close(PIPE);
-    }
-
-    # process the event result
-
-
-    return;
-}
-
-1;
diff --git a/contrib/daemon/tests/testGOsa.pl b/contrib/daemon/tests/testGOsa.pl
deleted file mode 100644 (file)
index 9ecb8f3..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/perl 
-#===============================================================================
-#
-#         FILE:  testGosa.pl
-#
-#        USAGE:  ./testGosa.pl 
-#
-#  DESCRIPTION:  
-#
-#      OPTIONS:  ---
-# REQUIREMENTS:  ---
-#         BUGS:  ---
-#        NOTES:  ---
-#       AUTHOR:   (), <>
-#      COMPANY:  
-#      VERSION:  1.0
-#      CREATED:  06.12.2007 14:31:37 CET
-#     REVISION:  ---
-#===============================================================================
-
-use strict;
-use warnings;
-use IO::Socket::INET;
-use Digest::MD5  qw(md5 md5_hex md5_base64);
-use Crypt::Rijndael;
-use MIME::Base64;
-
-sub create_ciphering {
-    my ($passwd) = @_;
-
-    $passwd = substr(md5_hex("$passwd") x 32, 0, 32);
-    my $iv = substr(md5_hex('GONICUS GmbH'),0, 16);
-    print "iv: $iv\n";
-    print "key: $passwd\n";
-
-    my $my_cipher = Crypt::Rijndael->new($passwd ,Crypt::Rijndael::MODE_CBC() );
-    $my_cipher->set_iv($iv);
-    return $my_cipher;
-}
-
-sub decrypt_msg {
-    my ($crypted_msg, $my_cipher) = @_ ;
-    $crypted_msg = &decode_base64($crypted_msg);
-    my $msg = $my_cipher->decrypt($crypted_msg); 
-    return $msg;
-}
-
-sub encrypt_msg {
-    my ($msg, $my_cipher) = @_;
-    if(not defined $my_cipher) { print "no cipher object\n"; }
-    $msg = "\0"x(16-length($msg)%16).$msg;
-    my $crypted_msg = $my_cipher->encrypt($msg);
-    chomp($crypted_msg = &encode_base64($crypted_msg));
-    return $crypted_msg;
-}
-
-
-
-my $gosa_server = IO::Socket::INET->new(LocalPort => "9999",
-        Type => SOCK_STREAM,
-        Reuse => 1,
-        Listen => 1,
-        );
-
-
-
-
-
-my $client = $gosa_server->accept();
-my $other_end = getpeername($client);
-if(not defined $other_end) {
-    print "client cannot be identified:";
-} else {
-    my ($port, $iaddr) = unpack_sockaddr_in($other_end);
-    my $actual_ip = inet_ntoa($iaddr);
-    print "accept client at gosa socket from $actual_ip\n";
-    chomp(my $crypted_msg = <$client>);
-    print "crypted msg: <<<$crypted_msg<<<\n";
-
-    my $cipher = &create_ciphering("ferdinand_frost");
-
-    my $msg = &decrypt_msg($crypted_msg, $cipher);
-    print "msg: <<<$msg<<<\n";
-
-    print "\n#################################\n\n";
-
-    my $answer = "gosa answer: $msg";
-
-    print "answer: $answer\n";
-    
-    my $out_cipher = &create_ciphering("ferdinand_frost");
-    my $crypted_answer = &encrypt_msg($answer, $out_cipher);
-    
-    print $client $crypted_answer."\n";
-
-}
-
-sleep(3);
-close($client);
-
-
-
-
-
-
-
-
diff --git a/contrib/demo.ldif b/contrib/demo.ldif
deleted file mode 100644 (file)
index dc2ce2f..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-dn: dc=gonicus,dc=de
-objectClass: dcObject
-objectClass: organization
-description: Base object
-dc: gonicus
-o: GONICUS GmbH
-
-dn: cn=terminal-admin,dc=gonicus,dc=de
-objectClass: person
-cn: terminal-admin
-sn: Upload user
-description: GOto Upload Benutzer
-userPassword:: e2tlcmJlcm9zfXRlcm1pbmFsYWRtaW5AR09OSUNVUy5MT0NBTAo=
-
-dn: ou=groups,dc=gonicus,dc=de
-objectClass: organizationalUnit
-ou: groups
-
-dn: ou=people,dc=gonicus,dc=de
-objectClass: organizationalUnit
-ou: people
-
-dn: cn=admin,ou=people,dc=gonicus,dc=de
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-objectClass: gosaAccount
-uid: admin
-cn: admin
-givenName: admin
-sn: GOsa main administrator
-sambaLMPassword: 10974C6EFC0AEE1917306D272A9441BB
-sambaNTPassword: 38F3951141D0F71A039CFA9D1EC06378
-userPassword:: dGVzdGVy
-
-dn: cn=administrators,ou=groups,dc=gonicus,dc=de
-objectClass: gosaObject
-objectClass: posixGroup
-objectClass: top
-gosaSubtreeACL: :all
-cn: administrators
-gidNumber: 999
-memberUid: admin
-
-dn: ou=incoming,dc=gonicus,dc=de
-objectClass: organizationalUnit
-ou: incoming
-
diff --git a/contrib/encodings b/contrib/encodings
deleted file mode 100755 (executable)
index 51d6f82..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# Encodings for class_servNfs.inc
-# This file should be placed in /etc/gosa/
-UTF-8=UTF-8
-ISO8859-1=ISO8859-1 (Latin 1)
-ISO8859-2=ISO8859-2 (Latin 2)
-ISO8859-3=ISO8859-3 (Latin 3)
-ISO8859-4=ISO8859-4 (Latin 4)
-ISO8859-5=ISO8859-5 (Latin 5)
-cp850=CP850 (Europe)
diff --git a/contrib/fai/README.fai b/contrib/fai/README.fai
deleted file mode 100644 (file)
index 89afff5..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-FAI support for GOsa
-====================
-
-Please note, that FAI support is work in progress. Anyway here's a quick
-guide how it works:
-
-1) Preparing FAI
-
- a) adjust the secrets file to match the password of your terminal-admin
-    ldap user
- b) build the debian package in goto-fai (i.e. using dpkg-buidpackage)
- c) add the resulting package to your fai nfs-root
-
-2) Preparing GOsa
-
- a) use the get-packages.pl script to generate a stripped down list of your
-    packages lists, move them to /etc/gosa/fai/servername/dist/.
-
- b) use the get-debconf.sh script to extract the debconf templates from
-    your mirror, move the resulting debconf.d directory to
-       /etc/gosa/fai/servername/dist/debconf.d
-
-3) Create classes/etc in GOsa, follow the ordinary fai documentation to
-   get your clients booted
-
-
diff --git a/contrib/fai/get-debconf.sh b/contrib/fai/get-debconf.sh
deleted file mode 100755 (executable)
index dc7d2ed..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-# Call with:
-# find /path/to/your/debmirror -name \*.deb | xargs ./get-debconf
-# Move result to /etc/gosa/fai/server/debconf.d
-
-[ -d /tmp/debconf.d ] && mkdir /tmp/debconf.d
-for i in $@; do
-    dpkg -e $i /tmp/debconf.d/DEBIAN
-    if [ -f /tmp/debconf.d/DEBIAN/templates ]; then
-       pp=$(basename $i)
-       p=${pp%%_*}
-        echo $p has debconf template
-       mv /tmp/debconf.d/DEBIAN/templates /tmp/debconf.d/$p.templates
-    fi
-done
-
-
diff --git a/contrib/fai/get-packages.pl b/contrib/fai/get-packages.pl
deleted file mode 100755 (executable)
index 7df4194..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-use File::Path;
-use File::Basename;
-
-# Check for parameters
-if ($ARGV[0] eq ""){
-       die ("Usage: parse-pkg <config-file>\n");
-}
-
-# Generate cache
-gen_cache($ARGV[0]);
-exit 0;
-
-#-----------------------------------------------------------------------------
-
-sub gen_cache
-{
-       my ($conffile)= @_;
-       my $line;
-
-       print "Generating GOsa package cache - this may take some time\n";
-       open(CONFIG, "<$conffile") or die("Failed to open '$conffile' - aborted\n");
-       
-       # Read lines
-       while ($line = <CONFIG>){
-               # Unify
-               chop($line);
-               $line =~ s/^\s+//;
-               $line =~ s/^\s+/ /;
-
-               # Strip comments
-               $line =~ s/#.*$//g;
-
-               # Skip empty lines
-               if ($line =~ /^\s*$/){
-                       next;
-               }
-
-               # Interpret deb line
-               if ($line =~ /^deb [^\s]+\s[^\s]+\s[^\s]+/){
-                       my ($baseurl)  = ($line =~ /^deb\s([^\s]+)/);
-                       my ($dist)     = ($line =~ /^deb\s[^\s]+\s([^\s]+)/);
-                       my ($sections) = ($line =~ /^deb\s[^\s]+\s[^\s]+\s(.*)$/);
-                       
-                       my $section;
-                       foreach $section (split(" ", $sections)){
-                               parse_package_info ("$baseurl", "$dist", "$section");
-                       }
-               }
-       }
-
-       close (CONFIG);
-}
-
-#-----------------------------------------------------------------------------
-
-sub parse_package_info
-{
-       my ($baseurl, $dist, $section)= @_;
-       my ($package, $server);
-
-       foreach $package ("Packages.gz"){
-               print ("* trying to retrieve $baseurl/dists/$dist/$section/binary-i386/$package\n");
-       
-               ($server)= ($baseurl =~ /^[^\/]+\/\/([^\/]+)\/.*$/);
-               get_package("$baseurl/dists/$dist/$section/binary-i386/$package", "/etc/gosa/fai/$server/$dist/$section");
-               parse_package("/etc/gosa/fai/$server/$dist/$section");
-               last;
-       }
-}
-
-#-----------------------------------------------------------------------------
-
-sub get_package
-{
-       my ($url, $dest)= @_;
-
-       # This is ugly, but I've no time to take a look at "how it works in perl"
-       system("wget '$url' -O '$dest'");
-       system("gzip -cd '$dest' > '$dest.in'");
-       system("rm -f '$dest'");
-
-       return 0;
-}
-
-#-----------------------------------------------------------------------------
-
-sub parse_package
-{
-       my ($path)= @_;
-       my ($name, $desc, $vers, $sect, $line);
-
-       my $tpath= dirname($path);
-       -d "$tpath" || mkpath "$tpath";
-
-       open(PACKAGES, "<$path.in") or die("Failed to open '$path.in' - aborted\n");
-       open(OUT, ">$path") or die("Failed to open '$path' - aborted\n");
-       
-       # Read lines
-       while ($line = <PACKAGES>){
-               # Unify
-               chop($line);
-
-               # Use empty lines as a trigger
-               if ($line =~ /^\s*$/){
-                       print OUT "$name|$vers|$sect|$desc\n";
-                       next;
-               }
-
-               # Trigger for package name
-               if ($line =~ /^Package:\s/){
-                       ($name)= ($line =~ /^Package: (.*)$/);
-                       next;
-               }
-
-               # Trigger for version
-               if ($line =~ /^Version:\s/){
-                       ($vers)= ($line =~ /^Version: (.*)$/);
-                       next;
-               }
-
-               # Trigger for description
-               if ($line =~ /^Description:\s/){
-                       ($desc)= ($line =~ /^Description: (.*)$/);
-                       next;
-               }
-
-               # Trigger for description
-               if ($line =~ /^Section:\s/){
-                       ($sect)= ($line =~ /^Section: (.*)$/);
-                       next;
-               }
-       }
-
-       close (OUT);
-       close (PACKAGES);
-}
-
diff --git a/contrib/fai/goto-fai/Makefile b/contrib/fai/goto-fai/Makefile
deleted file mode 100644 (file)
index 85756c2..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-all:
-       @echo "Nothing to do for all"
-
-install:
-       mkdir -p $(DESTDIR)/usr/sbin
-       mkdir -p $(DESTDIR)/etc/goto
-       mkdir -p $(DESTDIR)/usr/lib/goto
-       mkdir -p $(DESTDIR)/fai/hooks
-       cp secret $(DESTDIR)/etc/goto
-       cp -a get_fai_dir faimond $(DESTDIR)/usr/sbin
-       cp -a goto-support.lib $(DESTDIR)/usr/lib/goto
-       cp -a ldap2fai $(DESTDIR)/usr/sbin
-       cp confdir.DEFAULT.source $(DESTDIR)/fai/hooks
-       chmod go-rwx $(DESTDIR)/etc/goto/secret
-
-       # Install diversions
-       mkdir -p $(DESTDIR)/usr/lib/fai/sbin
-       cp diversions/setup_harddisks $(DESTDIR)/usr/lib/fai/sbin
-
diff --git a/contrib/fai/goto-fai/confdir.DEFAULT.source b/contrib/fai/goto-fai/confdir.DEFAULT.source
deleted file mode 100755 (executable)
index afed2a2..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-# undef default shell subroutine get_fai_dir
-# instead the new script get_fai_dir will be used
-
-setterm -cursor off >/dev/tty3
-/usr/sbin/faimond >/dev/tty3 & 
-chvt 3
-unset get_fai_dir
-unset sndmon
-
-sndmon() {
-       # send message to monitor daemon
-       [ "$faimond" -eq 0 ] && return 0
-       if [ "$debug" ];then
-               echo "$sndhostname $*" | nc localhost 4711
-       else
-               echo "$sndhostname $*" | nc localhost 4711 2>/dev/null
-       fi
-       return $?
-}
diff --git a/contrib/fai/goto-fai/debian/README.debian b/contrib/fai/goto-fai/debian/README.debian
deleted file mode 100644 (file)
index 584b1da..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-goto-fai for Debian
--------------------
-
-Comments regarding the Package
-
-Cajus Pollmeier <pollmeier@gonicus.de>, Thu, 17 Mar 2005 09:05:17 +0100
diff --git a/contrib/fai/goto-fai/debian/changelog b/contrib/fai/goto-fai/debian/changelog
deleted file mode 100644 (file)
index 905c15e..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-goto-fai (2.0-1) unstable; urgency=low
-
-  * Initial release.
-
- -- Cajus Pollmeier <pollmeier@gonicus.de>  Thu, 17 Mar 2005 09:05:17 +0100
diff --git a/contrib/fai/goto-fai/debian/control b/contrib/fai/goto-fai/debian/control
deleted file mode 100644 (file)
index 1cf6184..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-Source: goto-fai
-Section: lhm/main
-Priority: optional
-Maintainer: Cajus Pollmeier <pollmeier@gonicus.de>
-Standards-Version: 3.6.1
-Build-Depends: debmake
-
-Package: goto-fai
-Architecture: any
-Depends: ${shlibs:Depends}, libnet-ldap-perl, hwdata-knoppix, hwsetup, ddcxinfo-knoppix
-Description: GOto support scripts
- Support and build scripts for terminal server
diff --git a/contrib/fai/goto-fai/debian/copyright b/contrib/fai/goto-fai/debian/copyright
deleted file mode 100644 (file)
index e18fe19..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-This package was debianized by cajus cajus@ots-2.gonicus.local on
-Thu, 17 Mar 2005 09:05:17 +0100.
-
-It was downloaded from <fill in ftp site>
-
-Copyright:
-
-<Must follow here>
diff --git a/contrib/fai/goto-fai/debian/dirs b/contrib/fai/goto-fai/debian/dirs
deleted file mode 100644 (file)
index ca882bb..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin
-usr/sbin
diff --git a/contrib/fai/goto-fai/debian/postrm b/contrib/fai/goto-fai/debian/postrm
deleted file mode 100755 (executable)
index 526aaad..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh -e
-
-#DEBHELPER#
-
-if [ "remove" = "$1" ]; then
-       dpkg-divert --package goto-fai --remove --rename \
-               --divert /usr/lib/fai/sbin/setup_harddisks.goto-fai \
-                       /usr/lib/fai/sbin/setup_harddisks
-fi
-
-exit 0
diff --git a/contrib/fai/goto-fai/debian/preinst b/contrib/fai/goto-fai/debian/preinst
deleted file mode 100755 (executable)
index fa469b9..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh -e
-
-#DEBHELPER#
-#
-if [ ! -e /usr/lib/fai/sbin/setup_harddisks.goto-fai ]; then
-       dpkg-divert --package goto-fai --add --rename \
-               --divert /usr/lib/fai/sbin/setup_harddisks.goto-fai \
-               /usr/lib/fai/sbin/setup_harddisks
-fi
-
-exit 0
diff --git a/contrib/fai/goto-fai/debian/rules b/contrib/fai/goto-fai/debian/rules
deleted file mode 100755 (executable)
index 6967ca5..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/make -f
-# Made with the aid of debmake, by Christoph Lameter,
-# based on the sample debian/rules file for GNU hello by Ian Jackson.
-
-package=goto
-
-build:
-       $(checkdir)
-       
-       $(MAKE) CFLAGS="-O2 -g -Wall"
-       touch build
-
-clean:
-       $(checkdir)
-       rm -f build
-       -$(MAKE) clean
-       rm -f `find . -name "*~"`
-       rm -rf debian/tmp debian/files* core debian/substvars
-
-binary-indep: checkroot build
-       $(checkdir)
-# There are no architecture-independent files to be uploaded
-# generated by this package.  If there were any they would be
-# made here.
-
-binary-arch: checkroot build
-       $(checkdir)
-       rm -rf debian/tmp
-       install -d debian/tmp
-       cd debian/tmp && install -d `cat ../dirs`
-       $(MAKE) install DESTDIR=`pwd`/debian/tmp
-# Must have debmake installed for this to work. Otherwise please copy
-# /usr/bin/debstd into the debian directory and change debstd to debian/debstd
-       debstd 
-       dpkg-gencontrol -isp
-       chown -R root:root debian/tmp
-       chmod -R go=rX debian/tmp
-       dpkg --build debian/tmp ..
-
-define checkdir
-       test -f debian/rules
-endef
-
-binary: binary-indep binary-arch
-
-checkroot:
-       $(checkdir)
-       test root = "`whoami`"
-
-.PHONY: binary binary-arch binary-indep clean checkroot
diff --git a/contrib/fai/goto-fai/diversions/setup_harddisks b/contrib/fai/goto-fai/diversions/setup_harddisks
deleted file mode 100755 (executable)
index de1427c..0000000
+++ /dev/null
@@ -1,954 +0,0 @@
-#!/usr/bin/perl
-
-# $Id: setup_harddisks,v 1.41 2005/04/08 10:08:54 lange Exp $
-#*********************************************************************
-#
-# setup_harddisks -- create partitions and filesystems on harddisk
-#
-# This script is part of FAI (Fully Automatic Installation)
-# Copyright (c) 1999, 2000 by ScALE Workgroup, Universitaet zu Koeln
-# Copyright (c) 2000-2005 by Thomas Lange, Uni Koeln
-#
-#*********************************************************************
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING. If not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-# MA 02111-1307, USA.
-#*********************************************************************
-#
-# This program first read the configfiles, partitions and formats the harddisks,
-# produces fstab and FAI-variables-file.  It uses sfdisk, mke2fs, mkswap
-#
-# Parameters:
-# [-X]                     no test, your harddisks will be formated
-#                          default: only test, no real formating
-# [-f<config-filename>]    default: parse classes
-# [-c<class-path>]         default: $FAI/disk_config/
-# [-d]                     default: no DOS alignment
-#
-#---------------------------------------------------
-# Last changes:  31.3.2005 by Thomas Lange add sub mapdisk{}
-# Last changes:  8.11.2004 by Thomas Lange add $devdisklist when calling sfdisk
-# Last changes:   3.2.2004 by Thomas Lange typos
-# Last changes: 14.07.2003 by Thomas Lange add xfs filesystem support
-# Last changes: 23.01.2003 by Thomas Lange print info data to stdout
-# Last changes: 03.12.2002 by Thomas Lange remove ida, cciss stuff. Just match everything
-# Last changes: 27.11.2002 by Thomas Lange allow more that 3 primary partitions
-# Last changes: 14.05.2002 by Thomas Lange use strict
-# Last changes: 04.05.2002 by Thomas Lange use strict
-# Last changes: 29.04.2002 by Thomas Lange add swaplist
-# Last changes: 12.01.2002 by Thomas Lange
-# /dev/ida/ patch 12.01.2002 by Marc Martinez <lastxit+fai@technogeeks.org>
-# Last changes: 9.11.2001 by Thomas Lange
-# reiserfs patch 8.11.2001 by Diane Trout <diane@caltech.edu>
-# Last changes: 25.10.2001 by Thomas Lange
-# Last changes: 09.07.2001 by Thomas Lange
-# Last changes: 04.07.2001 by Thomas Lange
-# Last changes: 06.05.2001 by Thomas Lange
-# Last changes: 09.03.2001 by Thomas Lange
-# Last changes: 05.12.2000 by Thomas Lange
-# Last changes: 03.05.2000 by Thomas Lange
-# Last changes: 03.04.2000 by Mattias Gaertner
-#---------------------------------------------------
-#
-# config-file format:
-#   lines beginning with # are comments
-#
-# "disk_config <device>|first|end"
-#   The disk_config command starts the parsing.
-#   It has to be the first command.
-#    <device> is the harddisk to format in short form like "hda" or "sdc".
-#    if first is used, the first of $ENV{disklist} is used
-#    "end"    = end parsing here
-#   Example: "disk_config hdb"
-#   Example: "disk_config first"
-#
-# Defining one partition:
-# "primary|logical mountpoint|swap|- <size in mb>|preserve<No> [fstab-options][;extraordinary options]"
-#    "primary|logical":
-#      "primary": this are the bootable partitions like the
-#         root directory "/" or the DOS "C:" disk.
-#      "logical": this are all other partitions like a linux
-#         "/var" or a swap partition or a DOS disk.
-#
-#    "mountpoint|swap|-":
-#      "mountpoint": 
-#         This is the mount-point for fstab.
-#         For example "/","/var","/usr". There must not
-#         be a space in the mountpoint.
-#      "swap":
-#         swap-partitions
-#      "-":
-#         do not mount this partition.
-#
-#    "<size in mb>|preserve<No>":
-#      "<size in mb>":
-#        The size of the partition in megabyte
-#         Examples:
-#          "30"     = 30 mb
-#          "10-100" = 10 to 100 mb
-#          "20-"    = minimum of 20 mb
-#          "-500"   = 1 to 500 mb
-#          The megabytes will be rounded up to cylinders.
-#      "preserve<No>":
-#         This is the alternative for the size attribute.
-#         <No> is the partition number. For example
-#         preserve3 for the third partition. If the
-#         <device> was hda then this results in hda3.
-#         The partition will be left unchanged. This
-#         is useful if you have partitions that do not
-#         need re-installation or if you want to have
-#         other operation systems on the device together
-#         with Linux. Extended Partitions can not be preserved.
-#         The bootable flag will not be preserved.
-#         Preserved partitions are mounted readonly during
-#         installation.
-#
-#    "fstab-options":
-#         These options are copied to the fstab-file. The
-#         default is "default"
-#
-#   After the semicolon there could be extra options like:
-#     -i <bytes>   : Bytes per inodes
-#                    (only ext2/3 filesystem)
-#     -m <blocks>% : reserved blocks percentage for superuser
-#                    (only ext2/3 filesystem)
-#     -j          : format in ext3
-#     -c           : check for bad blocks
-#     format       : Always format this partition even if preserve
-#     lazyformat   : Do not format if partition has not moved
-#                    (useful for testing the installation)
-#     boot         : make this partition the boot-partition (the
-#                    linux root filesystem is the default)
-#     ext2         : Extended 2 filesystem (this is the default)
-#     swap         : swap partition
-#     dosfat16     : DOS 16bit FAT file system
-#     winfat32     : Win95 FAT32 file system
-#     writable     : mounts a preserved partition writable
-#     xfs          : xfs
-#     reiser       : reiserfs
-#       -h <hash>  : set reiserfs hash
-#       -v <ver>   : set reiserfs version
-#
-use strict;
-# getopts variables:
-our ($opt_X, $opt_f, $opt_c, $opt_d);
-my $test;
-
-$| = 1;                     # flush always
-
-#****************************************************
-# Variables
-#****************************************************
-
-my $Version = "version 0.35fai";
-
-my $megabyte = 1024 * 1024;    # guess
-# $gigabyte = 1024 * $megabyte;
-my $sectorsize = 512;
-
-# used programs
-my $sfdisk_options = "-q $ENV{sfdisk}";     # be quiet
-my $mke2fs_options = "-q";     # be quiet
-my $mkreiserfs_options = "";
-my $mkxfs_options = "-f";
-my $mkswap_options = "";
-
-# FAI input variables
-my $ClassPath = "$ENV{FAI}/disk_config";# this directory contains the classes
-my $ConfigFileName = "";   # alternative classfile, only for tests
-my $DOS_Alignment = "";    # align partitions for tracks
-
-# FAI output variables
-my $BootPartition = "";    # the boot partition like "hda1"
-my $BOOT_DEVICE = "";      # the root device like "hda" or "sdb"
-my $FAIOutputFile = $ENV{diskvar}; # write output variables to this file
-
-# old partition tables
-my %DiskUnits = ();        # unit size of each disk in sectors
-my %DiskSize = ();         # size of every disk in units
-my %SectorsAlignment = ();  # tracksize in sectors
-my %PartOldBoot = ();      # partition was bootable. "yes"=yes
-my %PartOldStart = ();     # old startunit of partition
-my %PartOldEnd = ();       # old endunit of partition
-my %PartOldStartSec = ();  # old startsector of partition
-my %PartOldEndSec = ();    # old endsector of partition
-my %PartOldID = ();        # old ID of partition
-my %OldNotAligned = (); # "yes" if old partition boundaries are not DOS aligned
-
-# mountpoints  ("/<path>" or "swap<No>" or "no<No>" or "extended<disk>")
-my $NofSwapPart = 0;       # number of swap partitions
-my $NofNotMoPart = 0;      # number of not mountet partitions
-my %DiskMountpoints = ();  # mountpoints of every disk. separated by spaces
-my %MountpointPart = ();   # partition of every mountpoint. e.g. "hda2"
-my %PartMountpoint = ();   # mountpoint of every partition.
-my @swaplist;              # list of all swpa devices
-
-# size of partition/mountpoint
-my %MPMinSize = ();        # minimum size of mountpoint in units
-my %MPMaxSize = ();        # maximum size of mountpoint in units
-my %MPPreserve = ();       # preserve partition: "yes"=yes
-my %MPPrimary = ();        # primary partition: "yes"=yes
-my %MPStart = ();          # start of partition in units
-my %MPSize = ();           # size of partition in units
-my %MPID = ();             # id of partition
-
-# options
-my %MPfstaboptions = ();   # fstab options for every mountpoint
-my %MPOptions = ();        # extra options for every mountpoint
-
-# sfdisk partition tables
-my %sfdiskTables = ();     # partition tables for sfdisk
-
-my $verbose = 0;
-$verbose = $ENV{verbose} if $ENV{verbose};
-
-# Parse command line
-
-use Getopt::Std;
-&getopts('Xf:c:d') || die "
-USAGE: [-X]                     no test, your harddisks will be formated
-                                default: only test, no real formating
-       [-f<config-filename>]    default: parse classes
-       [-c<class-path>]         default: \$FAI/disk_config/
-       [-d]                     default: no DOS alignment
-";
-
-print "setup_harddisks $Version\n";
-if (defined $opt_X){
-    $test = 2;
-} else {
-    print "TEST ONLY - no real formating\n\n";
-    $test = 1;
-}
-$ConfigFileName = $opt_f if $opt_f;# alternative config file
-$ClassPath      = $opt_c if $opt_c;# search classes here
-$DOS_Alignment  = "yes" if $opt_d; # track alignment
-
-# main part
-&GetAllDisks;
-&ParseAllConfigFiles;
-&BuildNewPartTables;
-&PartitionPersfdisk;
-&FormatDisks;
-&WriteFSTab;
-&WriteFAIVariables;
-exit 0;
-#****************************************************
-
-#****************************************************
-# get a partition pathname
-#****************************************************
-sub PartName {
-    my ($disk, $partno) = @_;
-    my $ppath;
-    for ($disk) {
-       /^[a-z]+$/ and $ppath = "${disk}${partno}";
-       /\d$/ and $ppath = "${disk}p${partno}";
-    }
-    return $ppath;
-}
-
-#****************************************************
-# Read all partition tables of this machine
-#****************************************************
-sub GetAllDisks{
-    my $line=""; my $disk=""; my $device=""; my $rest; my $result; my $divi;
-    my $devdisklist="";
-
-    foreach my $device(split(/\s/,$ENV{disklist})){
-      $devdisklist = "$devdisklist /dev/$device";
-    }
-    print "Probing disks: $devdisklist\n";
-    print "Disks found:";
-    $result = `sh -c "LC_ALL=C sfdisk -g -q $devdisklist"`;
-    foreach my $line(split(/\n/,$result)){
-       if($line =~ m'^/dev/(.+?):\s+(\d+)\s+cylinders,\s+(\d+)\s+heads,\s+(\d+)\s+sectors'i){
-           $disk = $1;
-           $DiskUnits{$disk} = $3 * $4;# heads * sectors = cylinder size in sectors
-           $DiskSize{$disk} = $2;      # cylinders
-           ($DOS_Alignment eq "yes") ? ($SectorsAlignment{$disk} = $4) : ($SectorsAlignment{$disk} = 1);
-           print " $disk";
-       }
-    }
-    $result = `sh -c "LC_ALL=C sfdisk -d -q $devdisklist"`;
-    foreach my $line(split(/\n/,$result)){
-#      if($line =~ m'# partition table of /dev/(cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|[a-z]+)'i){
-# now just match all devices
-       if($line =~ m'# partition table of /dev/(\S+)$'i){
-          $disk = $1;
-        }
-       if($line =~ m#^/dev/(.+?)\s*:\s+start=\s*(\d+),\s+size=\s*(\d+),\s+Id=\s*([a-z0-9]+)\b(.*)$#i){
-           $device = $1;
-            # Sectors
-            $PartOldStartSec{$device} = $2;
-            $PartOldEndSec{$device} = $2 + $3 - 1;
-            # DiskUnits
-           $PartOldStart{$device} = int ($2 / $DiskUnits{$disk});
-           $PartOldEnd{$device} = int (($2 + $3 - 1) / $DiskUnits{$disk});
-           $divi = $2 / $SectorsAlignment{$disk};
-           ($divi != int ($divi)) && ($OldNotAligned{$device} = "yes");
-           $divi = $3 / $SectorsAlignment{$disk};
-           ($divi != int ($divi)) && ($OldNotAligned{$device} = "yes");
-           $PartOldID{$device} = $4;
-           $rest = $5;
-           $PartOldBoot{$device} = ($rest =~ /bootable/) ? "yes" : "";
-       }
-    }
-    print "\n\n";
-}
-
-#****************************************************
-# parse config file or all class files
-#****************************************************
-sub ParseAllConfigFiles{
-    my $ConfigFileExists = 0;  # no config file parsed yet
-    if ($ConfigFileName){
-       # Read config filename
-       &ParseConfigFile($ConfigFileName);
-       $ConfigFileExists = 1;
-    } else {
-       # Read classes
-       foreach my $classfile (reverse split(/\s+/,$ENV{"classes"})){
-           my $filename = "$ClassPath/$classfile";
-           if (($classfile) && (-r $filename)) {
-               &ParseConfigFile($filename);
-               $ConfigFileExists = 1;
-            }
-           ($ConfigFileExists) && last;
-       }
-    }
-    ($ConfigFileExists == 0) && die "ERROR: no config file for setup_harddisk found. Please check you classes and files in disk_config.\n";
-}
-
-#****************************************************
-# map "disk_config first" to real disk device
-#****************************************************
-sub mapdisk {
-
-  my ($disk) = @_;
-  my @dlist = split /\s+/,$ENV{disklist};
-
-  if ($disk eq "disk1") {
-    print "Mapping disk name disk1 to $dlist[0]\n";
-    $disk = $dlist[0];
-  }
-  if ($disk eq "disk2") {
-    print "Mapping disk name disk2 to $dlist[1]\n";
-    $disk = $dlist[1];
-  }
-  return $disk;
-}
-
-#****************************************************
-# parse config-file
-#****************************************************
-sub ParseConfigFile{
-    my $size=""; my $mountpoint=""; my $device ="";
-    my $fstaboptions=""; my $options=""; my $disk=""; my $command = "";
-    my $LogPartNo; my $PrimPartNo; my $NoMoreLogicals;
-    my $LastPresPart; my $extmp; my $Min; my $Max;
-    my $filename = shift;
-    open (FILE,"$filename")
-      || die "config file not found: $filename\n";
-    (print "Using config file: $filename\n");
-    $disk = "";
-    my $a = 1, my $paras ="", my $number=0;
-    while (my $line = <FILE>){
-       chomp($line);
-       $a++;
-       next if( $line =~ /^#|^\s*$/ );
-
-       # disk_config - command
-       if ($line =~ /^disk_config(.*)/i){
-           $paras = $1;
-           if ($paras =~ / end/i){
-               $disk = "";
-           } else {
-#              if($paras =~ m# (/dev/)?(cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|[a-z]+)#i){
-# now match all devives
-               if($paras =~ m# (/dev/)?(\S+)#i){
-                   $disk = mapdisk($2);
-                   ($DiskMountpoints{$disk})
-                     && die "ERROR: there are more than one configuration of disk $disk.\n";
-                   ($DiskSize{$disk}) || die "ERROR: could not read device /dev/$disk\n";
-                   ($test != 1) || (print "config: $disk\n");
-                   $DiskMountpoints{$disk} = "";
-                   $MPPrimary{"extended$disk"} = "";
-                   $LogPartNo = 4;
-                   $PrimPartNo = 0;
-                   $NoMoreLogicals = 0;
-                   $LastPresPart = "";
-                   $extmp = "extended$disk";
-               } else {
-                   die "SYNTAX ERROR: in config file line $a, unknown disk_config parameter $paras\n$line\n";
-               }
-           }
-       }
-
-       if ($disk){
-           # primary|partition - command
-           if($line =~ /^\s*(primary|logical)\s+(.*)$/i){
-               $command = $1;
-               # split variables
-               $paras = $2;
-               $options = "";
-               if($paras =~ /(.*?)\s*;\s*(.*)$/){
-                   $paras = $1;
-                   $options = $2;
-               }
-               $size="";
-               $mountpoint ="";
-               $fstaboptions = "";
-               ($mountpoint,$size,$fstaboptions)=split(/\s+/,$paras);
-               # mountpoint
-               ($mountpoint =~ m#^/.*|^swap$|^-$#i)
-                 || die "SYNTAX ERROR in config file line $a, mountpoint: $mountpoint\n$line\n";
-               ($MountpointPart{$mountpoint})
-                 && die "SYNTAX ERROR in config file line $a. Mountpoint $mountpoint redefined.\n$line\n";
-               if($mountpoint eq "/"){
-                   ($BootPartition) || ($BOOT_DEVICE = $disk);
-               }
-               if($mountpoint eq "-"){
-                   $NofNotMoPart++;
-                   $mountpoint = "no$NofNotMoPart";
-               }
-               if($mountpoint eq "swap"){
-                   $NofSwapPart++;
-                   $mountpoint = "swap$NofSwapPart";
-                   ($options !~ /\bswap\b/i) && ($options .= " swap");
-                   ($fstaboptions) || ($fstaboptions = "sw");
-               }
-               if($mountpoint =~ m#^/#){
-                   ($fstaboptions) || ($fstaboptions = "defaults");
-               }
-               if ($command eq "primary") {
-                   ($MPPrimary{$extmp} eq "yes") && ($NoMoreLogicals = 1);
-                   $MPPrimary{$mountpoint} = "yes";
-                   $PrimPartNo++;
-#                  ($PrimPartNo == 3) && ($disk =~ /^sd/) && ($PrimPartNo++);
-                    ($PrimPartNo >4 ) && die "ERROR: Too much primary partitions (max 4).".
-                                " All logicals together need one primary too.\n";
-                   $MountpointPart{$mountpoint} = PartName($disk,$PrimPartNo);
-                   if($options =~ /\bboot\b/i){
-                       ($BootPartition) && die "ERROR: only one partition can be bootable at a time.";
-                       $BootPartition = $MountpointPart{$mountpoint};
-                       $BOOT_DEVICE = $disk;
-                   }
-               } else {
-                   ($NoMoreLogicals != 0) && die "ERROR: the logical partitions must be together.\n";
-                   $MPPrimary{$mountpoint} = "";
-                   $LogPartNo++;
-                   $MountpointPart{$mountpoint} = PartName($disk,$LogPartNo);
-                   if (!$MPPrimary{$extmp}){
-                       $MPPreserve{$extmp} = "";
-                       $MPPrimary{$extmp} = "yes";
-                       $MPMinSize{$extmp} = 0;
-                       $MPMaxSize{$extmp} = 0;
-                       $MPID{$extmp} = 5;
-                       $PrimPartNo++;
-                       ($PrimPartNo == 3) && ($disk =~ /^sd/) && ($PrimPartNo++);
-                        ($PrimPartNo >4 ) 
-                         && die "ERROR: too much primary partitions (max 4).".
-                               " All logicals together need one primary too.\n";
-                       $MountpointPart{$extmp} = PartName($disk,$PrimPartNo);
-                       $DiskMountpoints{$disk} .= " $extmp";
-                   }
-#                  ($options =~ /\bboot\b/i) && die "ERROR: line $a, only primary partitions can be bootable.\n";
-               }
-               $DiskMountpoints{$disk} .= " $mountpoint";
-               # size
-               ($size =~ /^preserve\d+$|^\d+\-?\d*$|^-\d+$/i)
-                   || die "SYNTAX ERROR in config file line $a, size: $size\n$line\n";
-               if($size =~ /^preserve(\d+)$/i){
-                   my $number = $1;
-                   $device = PartName($disk,$number);
-                   ($OldNotAligned{$device} eq "yes")
-                     && die "ERROR: unable to preserve partition /dev/$device. Partition is not DOS aligned.";
-                   ($command eq "primary") && ($number != $PrimPartNo)
-                       && die "NUMERATION ERROR in line $a, the number of the partition can not be preserved:\n$line\n";
-                   ($command eq "logical") && ($number != $LogPartNo)
-                       && die "NUMERATION ERROR in line $a, the number of the partition can not be preserved:\n$line\n";
-                   if ($PartOldEnd{$device}){
-                       (($PartOldID{$device} == 5) || ($PartOldID{$device} == 85)) &&
-                         die "ERROR in config file line $a.".
-                              " Extended partitions can not be preserved. /dev/$device\n$line\n";
-                       $MPPreserve{$mountpoint}="yes";
-                       $MPMinSize{$mountpoint} = $PartOldEnd{$device}-$PartOldStart{$device}+1;
-                       $MPMaxSize{$mountpoint} = $MPMinSize{$mountpoint}; # Max=Min
-                       $MPStart{$mountpoint} = $PartOldStart{$device};
-                       $MPSize{$mountpoint} = $MPMinSize{$mountpoint};
-                       $MPID{$mountpoint} = $PartOldID{$device};
-                   } else {
-                       die "ERROR: cannot preserve partition $device. partition not found.$PartOldEnd{$device}\n";
-                   }
-                   if ($LastPresPart) {
-                       ($PartOldStart{$device} < $PartOldStart{$LastPresPart}) &&
-                         die "ERROR: misordered partitions: cannot preserve partitions $LastPresPart and $device\n".
-                              "       in this order because of their positions on disk.";
-                   }
-                   $LastPresPart = $device;
-                   ($MPMinSize{$mountpoint} < 1)
-                     && die "ERROR: unable to preserve partitions of size 0.\n$line\n ";
-                 } else {
-                   # If not preserve we must know the filesystemtype
-                   ($options !~ /\b(ext2|ext3|auto|swap|dosfat16|winfat32|reiser|xfs)\b/i ) && ($options .= " auto");
-                 }
-               if($size =~ /^(\d*)(\-?)(\d*)$/){
-                   $Min = $1;
-                   $Min||= 1;
-                   $Max = $3;
-                   $MPMinSize{$mountpoint} = int (($Min * $megabyte - 1) / ($DiskUnits{$disk} * $sectorsize)) + 1;
-                   if ($2 eq "-"){
-                       if($Max =~ /\d+/){
-                           $MPMaxSize{$mountpoint} = int (($Max * $megabyte - 1) / ($DiskUnits{$disk} * $sectorsize)) + 1;
-                       } else {
-                           $MPMaxSize{$mountpoint} = $DiskSize{$disk};
-                       }
-                   } else {
-                       $MPMaxSize{$mountpoint} = $MPMinSize{$mountpoint}; # Max=Min
-                   }
-                   ($MPMinSize{$mountpoint} > $DiskSize{$disk})
-                     && die "ERROR in config file line $a: Minsize larger than disk.\n$line\n";
-                   ($MPMinSize{$mountpoint} > $MPMaxSize{$mountpoint}) 
-                       && die "SYNTAX ERROR in config file line $a, MIN-MAX-size: $MPMinSize{$mountpoint}-$MPMaxSize{$mountpoint}\n$line\n";
-                   ($MPMinSize{$mountpoint} < 1)
-                     && die "SYNTAX ERROR in config file line $a. Minsize must be greater than 1.\n$line\n";
-                   $MPPreserve{$mountpoint} = "";
-               }
-               # fstaboptions
-               $MPfstaboptions{$mountpoint} = $fstaboptions;
-               # extra options
-               ($options =~ /\b(ext[23]|auto)\b/i) && ($MPID{$mountpoint} = 83); # Linux native
-               ($options =~ /\bswap\b/i) && ($MPID{$mountpoint} = 82); # Linux swap
-               ($options =~ /\bdosfat16\b/i) && ($MPID{$mountpoint} = 6); # DOS FAT 16bit (>=32MB, will be changed later)
-               ($options =~ /\bwinfat32\b/i) && ($MPID{$mountpoint} = "b"); # Win 95 FAT 32
-               $MPOptions{$mountpoint} = $options;
-               if($test == 1){
-                   print "$mountpoint,$MPMinSize{$mountpoint}-$MPMaxSize{$mountpoint},";
-                   print "$fstaboptions,$options";
-                   ($MPPreserve{$mountpoint} eq "yes") && (print " Preserve: $MountpointPart{$mountpoint}");
-                   print "\n";
-               }
-           }
-       }
-    }
-    close(FILE);
-}
-
-#****************************************************
-# Build all partition tables
-#****************************************************
-sub BuildNewPartTables{
-    my ($disk, $mountpoint, $part, $PrimaryMP, $LogicalMP);
-    ($test != 1) || (print "\nBuilding partition tables:\n");
-    # Build PartMountpoint array
-    foreach $disk(keys %DiskMountpoints) {
-       $DiskMountpoints{$disk} =~ s/\s(\s)/$1/g;
-       $DiskMountpoints{$disk} =~ s/^\s//;
-       $DiskMountpoints{$disk} =~ s/\s$//;
-       foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
-           $PartMountpoint{$MountpointPart{$mountpoint}} = $mountpoint;
-       }
-    }
-    foreach $disk(keys %DiskMountpoints) {
-       &SetPartitionPositions($disk);
-        # change units to sectors
-        foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
-            if($MPPreserve{$mountpoint} eq "yes"){
-               $MPStart{$mountpoint} = $PartOldStartSec{$MountpointPart{$mountpoint}};
-               $MPSize{$mountpoint} = $PartOldEndSec{$MountpointPart{$mountpoint}} - $MPStart{$mountpoint} + 1;
-           } else {
-               $MPStart{$mountpoint} *= $DiskUnits{$disk};
-               $MPSize{$mountpoint} *= $DiskUnits{$disk};
-               # align first partition for mbr
-               if($MPStart{$mountpoint} == 0){
-                   $MPStart{$mountpoint} += $SectorsAlignment{$disk};
-                   $MPSize{$mountpoint} -= $SectorsAlignment{$disk};
-               }
-           }
-       }
-       # align all logical partitions
-        foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
-            next if ($MPPrimary{$mountpoint} eq "yes");
-           if ($MountpointPart{$mountpoint} eq "${disk}5") {
-               # partition with number 5 is first logical partition and start of extended partition
-               $MPStart{"extended$disk"} = $MPStart{$mountpoint};
-                ($MPPreserve{$mountpoint} eq "yes") && ($MPStart{"extended$disk"} -= $SectorsAlignment{$disk});
-           }
-            if ($MPPreserve{$mountpoint} ne "yes") {
-               $MPStart{$mountpoint} += $SectorsAlignment{$disk};
-               $MPSize{$mountpoint} -= $SectorsAlignment{$disk};
-           }
-       }
-        &CalculateExtPartSize($disk);
-        # sort mountpoints of partition number
-        $PrimaryMP = "";
-        $LogicalMP = "";
-        foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
-         ($MPPrimary{$mountpoint} eq "yes") ? ($PrimaryMP .= " $mountpoint") : ($LogicalMP .= " $mountpoint");
-       }
-       $DiskMountpoints{$disk} = "$PrimaryMP$LogicalMP";
-       $DiskMountpoints{$disk} =~ s/^\s//;
-       # print partition table
-        ($test != 1) || (PrintPartitionTable($disk));
-    }
-    if (!$BootPartition){
-        $BootPartition = $MountpointPart{"/"};
-    }
-}
-
-#****************************************************
-# set position for every partition
-#****************************************************
-sub SetPartitionPositions{
-    my $disk = shift;
-    my $mountpoint; my $DynGroup =""; my $StartPos; my $EndPos;
-    # Build groups of unpreserved partitions between
-    # preserved partitions
-    $StartPos = 0;
-    foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
-        if ($MPPreserve{$mountpoint} eq "yes") {
-           $EndPos = $PartOldStart{$MountpointPart{$mountpoint}} - 1;
-            &SetGroupPos($DynGroup,$StartPos,$EndPos);
-           $DynGroup = "";
-           $StartPos = $PartOldEnd{$MountpointPart{$mountpoint}} + 1;
-        } else {
-           $DynGroup .= " $mountpoint";
-       }
-    }
-    $EndPos = $DiskSize{$disk} - 1;
-    &SetGroupPos($DynGroup,$StartPos,$EndPos);
-    foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
-       ($MPOptions{$mountpoint} =~ /\bdosfat16\b/i)
-           && (($MPSize{$mountpoint} * $DiskUnits{$disk} * $sectorsize) < 32 * $megabyte)
-               && ($MPID{$mountpoint} = 4); # DOS 16-bit FAT <32MB
-    }
-}
-
-#****************************************************
-# set position for a group of unpreserved partitions
-# between start and end
-#****************************************************
-sub SetGroupPos{
-    my ($PartGroup,$Start,$End) = @_;
-    $PartGroup =~ s/^ //;
-    ($PartGroup) || return;
-    my $totalsize = $End - $Start + 1;
-    ($totalsize <= 0) && return;
-    my $mountpoint; my $mintotal = 0; my $maxmintotal = 0; my $rest = 0; my $EndUnit = 0;
-    # compute total of MinSizes and difference to MaxSizes
-    foreach $mountpoint (split(/\s/,$PartGroup)) {
-        $mintotal += $MPMinSize{$mountpoint};
-        $maxmintotal += ($MPMaxSize{$mountpoint} - $MPMinSize{$mountpoint});
-        $MPSize{$mountpoint} = $MPMinSize{$mountpoint};
-    }
-    # Test if partitions fit
-    ($mintotal > $totalsize)
-      && die "ERROR: Mountpoints $PartGroup do not fit.\n";
-    # Maximize partitions
-    $rest = $totalsize - $mintotal;
-    ($rest > $maxmintotal) && ($rest = $maxmintotal);
-    if ($rest > 0) {
-        foreach $mountpoint (split(/\s/,$PartGroup)) {
-            $MPSize{$mountpoint} += int ((($MPMaxSize{$mountpoint} - $MPMinSize{$mountpoint}) * $rest) / $maxmintotal);
-        }
-    }
-    # compute rest
-    $rest = $totalsize;
-    foreach $mountpoint (split(/\s/,$PartGroup)) {
-        $rest -= $MPSize{$mountpoint};
-    }
-    # Minimize rest
-    foreach $mountpoint (split(/\s/,$PartGroup)) {
-        if (($rest >0) && ($MPSize{$mountpoint} < $MPMaxSize{$mountpoint})){
-            $MPSize{$mountpoint}++;
-           $rest--;
-       }
-    }
-    # Set start for every partition
-    foreach $mountpoint (split(/\s/,$PartGroup)) {
-        $MPStart{$mountpoint} = $Start;
-       $Start += $MPSize{$mountpoint};
-       $EndUnit = $MPStart{$mountpoint} + $MPSize{$mountpoint} - 1;
-    }
-}
-
-#****************************************************
-# calculate extended partition size
-#****************************************************
-sub CalculateExtPartSize{
-    my ($disk) = @_;
-    my $extmp = "extended$disk";
-    my $mountpoint; my $ExtEnd; my $NewEnd;
-    ($MPPrimary{$extmp}) || return;
-    $ExtEnd = $MPStart{$extmp};
-    foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
-        next if ($MPPrimary{$mountpoint} eq "yes");
-       $NewEnd = $MPStart{$mountpoint} + $MPSize{$mountpoint} - 1;
-       ($NewEnd > $ExtEnd) && ($ExtEnd = $NewEnd);
-    }
-    $MPSize{$extmp} = ($ExtEnd - $MPStart{$extmp} + 1);
-}
-
-#****************************************************
-# Print partition "number - mountpoint" table
-#****************************************************
-sub PrintPartitionTable{
-    my ($disk) = @_;
-    my $part; my $mountpoint; my $mountpointname; my $end;
-    foreach $part (sort %MountpointPart) {
-        next if($part !~ /^$disk/);
-       $mountpoint = $PartMountpoint{$part};
-        if ($mountpoint =~ /^no(.*)/){
-            $mountpointname = "no mountpoint ($1)";
-       } else {
-           $mountpointname = $mountpoint;
-       }
-       $end = $MPStart{$mountpoint} + $MPSize{$mountpoint} - 1;
-       print <<"EOM";
-/dev/$part $mountpointname start=$MPStart{$mountpoint} size=$MPSize{$mountpoint} end=$end id=$MPID{$mountpoint}
-EOM
-      }
-}
-
-#****************************************************
-# build all partition tables for sfdisk
-#****************************************************
-sub PartitionPersfdisk{
-    my ($disk, $mountpoint, $line, $part, $PrimaryNo);
-    my ($command, $result, $filename, $number);
-    print "Creating partition table: ";
-    foreach $disk(keys %DiskMountpoints) {
-        $sfdiskTables{$disk} = "# partition table of device: /dev/$disk\nunit: sectors\n\n";
-       $PrimaryNo = 1;
-        foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
-           $part = $MountpointPart{$mountpoint};
-           $part =~ /(\d+)$/;
-           ($1 < 5) && ($PrimaryNo++);
-           if ( ($1 == 5) && ($PrimaryNo < 5) ){
-               for my $number($PrimaryNo..4) {
-                   $sfdiskTables{$disk} .= BuildsfdiskDumpLine(PartName($disk,$number),0,0,0)."\n";
-               }
-           }
-           $line = BuildsfdiskDumpLine($MountpointPart{$mountpoint},$MPStart{$mountpoint},$MPSize{$mountpoint},$MPID{$mountpoint});
-            ($part eq $BootPartition) && ($line .= ", bootable");
-            $sfdiskTables{$disk} .= "$line\n";
-       }
-#      print $sfdiskTables{$disk};
-       $filename = "$ENV{LOGDIR}/partition." . (($disk=~ m#/#) ? join('_', split('/', $disk)) : $disk);
-       if(($test != 1) && ($filename)){
-           open(FILE, ">$filename") || die "unable to write temporary file $filename\n";
-           print FILE $sfdiskTables{$disk};
-           close(FILE);
-        }
-       $command = "LC_ALL=C sfdisk $sfdisk_options /dev/$disk < $filename";
-       if($test != 1){
-            print "$command\n";
-           $result = `sh -c "$command"`;
-           (($? >> 8) == 0) || (die "\nSFDISK ERROR:\n $result\n");
-       }
-    }
-}
-
-#****************************************************
-# build a sfdisk dump line
-#****************************************************
-sub BuildsfdiskDumpLine{
-
-  sprintf "/dev/%-5s: start=%10s, size=%10s, Id=%3s",@_;
-}
-
-#****************************************************
-# Format all disks
-#****************************************************
-sub FormatDisks{
-    my ($disk, $device, $mountpoint, $mountpointname, $command, $result);
-    print "Creating file systems:\n";
-    foreach $disk(keys %DiskMountpoints) {
-        foreach $mountpoint (split(/\s/,$DiskMountpoints{$disk})) {
-           $device = $MountpointPart{$mountpoint};
-            if ($mountpoint =~ /^no/){
-                $mountpointname = "no mountpoint";
-            } else {
-               $mountpointname = $mountpoint;
-           }
-           # preserved partition
-           if ( ($MPPreserve{$mountpoint} eq "yes") && ($MPOptions{$mountpoint} !~ /\bformat\b/i)){
-               print "Preserve partition $device";
-                if ($mountpoint =~ /^no$1/){
-                    print " with no mountpoint\n";
-                } else {
-                   print " with mountpoint $mountpoint\n";
-               }
-               next;
-           }
-           # lazy format
-           if ( ( $MPOptions{$mountpoint} =~ /\blazyformat\b/i )
-              && ($MPStart{$mountpoint} == $PartOldStartSec{$device})
-              && (($MPStart{$mountpoint} + $MPSize{$mountpoint} - 1) == $PartOldEndSec{$device}) ){
-               print "Lazy format: $device";
-                if ($mountpoint =~ /^no$1/){
-                    print " with no mountpoint";
-                } else {
-                   print " with mountpoint $mountpoint";
-               }
-                print " was neither moved nor formated.\n";
-               next;
-           }
-           # swap
-           if ($mountpoint =~ /^swap/i) {
-#              print "Make swap partition:\n";
-               $command = "mkswap $mkswap_options";
-               ($MPOptions{$mountpoint} =~ /(\-c)\b/i) && ($command .= " $1");
-               push @swaplist, "/dev/$device";
-               $command .= " /dev/$device";
-               print "  $command\n";
-               if($test != 1){
-                   $result = `$command`;
-                   (($? >> 8) == 0) || (die "\nMKSWAP ERROR:\n $result\n");
-               }
-               next;
-           }
-           # Linux Reiser file system
-           if ($MPOptions{$mountpoint} =~ /\breiser\b/i) {
-#              print "Make Reiser Filesystem:\n";
-               $command = "echo y | mkreiserfs $mkreiserfs_options";
-               ($MPOptions{$mountpoint} =~ /(\-h\s*\w+)\b/) && ($command .= " $1");
-               ($MPOptions{$mountpoint} =~ /(\-v\s*\d+)\b/) && ($command .= " $1");
-               $command .= " /dev/$device";
-               print "  $command\n";
-               if ($test != 1){
-                   $result = `$command`;
-                   (($? >> 8) == 0) || die "\nMKREISERFS ERROR:\n $result\n";
-               }
-               next;
-           }
-           # Linux XFS file system
-           if ($MPOptions{$mountpoint} =~ /\bxfs\b/i) {
-#              print "Make XFS Filesystem:\n";
-               $command = "mkfs.xfs $mkxfs_options";
-               $command .= " /dev/$device";
-               print "  $command\n";
-               if ($test != 1){
-                   $result = `$command`;
-                   (($? >> 8) == 0) || die "\nMKFS.XFS ERROR:\n $result\n";
-               }
-               next;
-           }
-           # Linux Extended 2 file system
-           if ($MPOptions{$mountpoint} =~ /\b(ext[23]|auto)\b/i) {
-#              print "Make Extended 2/3 Filesystem:\n";
-               $command = "mke2fs $mke2fs_options";
-               ($MPOptions{$mountpoint} =~ /(\-c)\b/i) && ($command .= " $1");
-               ($MPOptions{$mountpoint} =~ /(\-i\s*\d+)\b/) && ($command .= " $1");
-               ($MPOptions{$mountpoint} =~ /(\-m\s*\d+)\b/) && ($command .= " $1");
-               ($MPOptions{$mountpoint} =~ /(\-j)\b/) && ($command .= " $1");
-               $command .= " /dev/$device";
-               print "  $command\n";
-               if ($test != 1){
-                   $result = `$command`;
-                   (($? >> 8) == 0) || die "\nMKE2FS ERROR:\n $result\n";
-               }
-               next;
-           }
-           # DOS 16bit FAT / Win95 FAT 32
-           if ($MPOptions{$mountpoint} =~ /\b(dosfat16|winfat32)\b/i) {
-               print "Clear first sector for DOS/Windows\n";
-               $command = "dd if=/dev/zero of=/dev/$MountpointPart{$mountpoint} bs=512 count=1";
-               print "  $command\n";
-               if ($test != 1){
-                   $result = `$command`;
-                   (($? >> 8) == 0) || die "\nDD ERROR:\n $result\n";
-               }
-               next;
-           }
-        }
-    }
-}
-
-#****************************************************
-# Build fstab and write it to <root>/etc/fstab
-#****************************************************
-sub WriteFSTab{
-    my ($FileSystemTab, $device, $type, $filename);
-    $FileSystemTab  = << "EOM";
-# /etc/fstab: static file system information.
-#
-#<file sys>          <mount point>     <type>   <options>   <dump>   <pass>
-EOM
-    # 1. /
-    $type = "ext2";
-    ($MPOptions{'/'} =~ /\b(reiser)\b/i) && ($type = "reiserfs");
-    ($MPOptions{'/'} =~ /\b(xfs)\b/i) && ($type = "xfs");
-    ($MPOptions{'/'} =~ /\b(ext3)\b/i) && ($type = "ext3");
-    ($MPOptions{'/'} =~ /\b(ext2)\b/i) && ($type = "ext2");
-    $FileSystemTab .= BuildfstabLine("/dev/$MountpointPart{'/'}","/",$type,$MPfstaboptions{'/'},0,1);
-    # 2. swap partitions
-    foreach my $mountpoint (%PartMountpoint){
-       next if( $mountpoint !~ /^swap/i);
-       $FileSystemTab .= BuildfstabLine("/dev/$MountpointPart{$mountpoint}",
-                           "none","swap",$MPfstaboptions{$mountpoint},0,0);
-    }
-    # 3. /proc
-    $FileSystemTab .= BuildfstabLine("none","/proc","proc","defaults",0,0);
-    # 4. sorted others
-    foreach my $mountpoint (sort %PartMountpoint){
-       next if ( ($mountpoint !~ m#^/#) || ($mountpoint eq "/"));
-       $device = $MountpointPart{$mountpoint};
-       $type = "ext2";
-       ($MPOptions{$mountpoint} =~ /\b(dosfat16|winfat32)\b/i) && ($type = "vfat");
-       ($MPOptions{$mountpoint} =~ /\b(reiser)\b/i) && ($type = "reiserfs");
-       ($MPOptions{$mountpoint} =~ /\b(xfs)\b/i) && ($type = "xfs");
-       ($MPOptions{$mountpoint} =~ /\b(ext3)\b/i) && ($type = "ext3");
-       ($MPOptions{$mountpoint} =~ /\b(ext2)\b/i) && ($type = "ext2");
-       $FileSystemTab .= BuildfstabLine("/dev/$device",$mountpoint,$type,$MPfstaboptions{$mountpoint},0,2);
-    }
-    # write it
-    $filename = "$ENV{LOGDIR}/fstab";
-#    print $FileSystemTab;
-    print "Write fstab to $filename\n" if $verbose;
-    if($test != 1){
-       open(FILE, ">$filename") || die "unable to write fstab $filename\n";
-       print FILE $FileSystemTab;
-       close(FILE);
-    }
-}
-
-#****************************************************
-# Build fstab line
-#****************************************************
-sub BuildfstabLine{
-
-    sprintf "%-10s   %-15s   %-6s  %-8s  %-4s %-4s\n",@_;
-}
-
-#****************************************************
-# Write all FAI variables of this program to file
-#****************************************************
-sub WriteFAIVariables{
-
-  my $swaps;
-
-  print "Write FAI variables to file $FAIOutputFile\n" if $verbose;
-    return if ($test == 1);
-  $swaps = join ' ',@swaplist;
-    open(FILE, ">$FAIOutputFile") || die "Unable to write file $FAIOutputFile\n";
-    print FILE << "EOM";
-BOOT_DEVICE=/dev/$BOOT_DEVICE
-ROOT_PARTITION=/dev/$MountpointPart{'/'}
-BOOT_PARTITION=/dev/$BootPartition
-SWAPLIST="$swaps"
-EOM
-    close(FILE);
-}
diff --git a/contrib/fai/goto-fai/faimond b/contrib/fai/goto-fai/faimond
deleted file mode 100755 (executable)
index 3ebdd5d..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/perl
-
-# $Id: faimond,v 1.2 2004/06/27 11:18:55 lange Exp $
-#*********************************************************************
-#
-# faimond -- monitor daemon which collects client status info
-#
-# This script is part of FAI (Fully Automatic Installation)
-# (c) 2003-2004 by Thomas Lange, lange@informatik.uni-koeln.de
-# Universitaet zu Koeln
-#
-#*********************************************************************
-
-#use strict;
-use Socket;
-
-$| = 1;
-my $port = 4711;
-
-@tasklist = qw/confdir defclass defvar partition mountdisks extrbase updatebase instsoft configure finish/;
-
-%tasks = (
-confdir => [' ', "Beziehe System-Einstellungen"],
-defclass => [' ',"Definieren von Klassen"],
-defvar => [' ',"Definieren von Variablen"],
-partition => [' ',"Paritionieren der Festplatten"],
-mountdisks => [' ',"Einbinden der Dateisysteme"],
-extrbase => [' ',"Installieren des Basis-Systems"],
-updatebase => [' ',"Aktualisieren des Basis-Systems"],
-instsoft => [' ',"Installieren der Software"],
-configure => [' ',"Abschließende Konfiguration"],
-finish => [' ',"Abschließen der Installation"]
-);
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub server_init() {
-
-  my $proto = getprotobyname('tcp');
-  socket(SERVER, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
-  setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1) or die "setsock: $!";
-
-  my $paddr = sockaddr_in($port, INADDR_ANY);
-
-  bind(SERVER, $paddr) or die "bind: $!";
-  listen(SERVER, SOMAXCONN) or die "listen: $!";
-#  print "FAI monitoring daemon started on port $port\n";
-}
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub big_loop() {
-
-  # accept a connection, print message received and close
-  my ($client_addr,$inp);
-  while ($client_addr = accept(CLIENT, SERVER)) {
-    $inp = <CLIENT>;
-    close CLIENT;
-    ($host,$begend,$task,$ecode) = split /\s+/,$inp;
-    chomp $ecode;
-    $strecode = sprintf "%-3s",$ecode;
-    $sym = ($begend =~ /TASKEND/) ? "   \\Z2OK\\Zn" : "   ->";
-    $tasks{$task}[0] = $ecode ? " \\Z1E$strecode\\Zn" : $sym;
-    showtab();
-
-    # Stop if we've reached faiend
-    if ( $task =~ /faiend/ ){
-       system("dialog --timeout 60 --msgbox '\nDie Installation wurde abgeschlossen. Drücken Sie die Eingabetaste um das System neu zu starten.' 8 60");
-       break;
-    }
-  }
-}
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub showtab() {
-
-# nach taskbeg soll es blinken, bei taskend, X oder error code
-
-  my $pre = '--colors --title " Aktueller Installationsverlauf "';
-  my $s2 = " --infobox \"\n";
-  # show tabular %tasks
-
-  $str = "$pre $s2";
-  foreach (@tasklist) {
-    $x = sprintf "%5s  $tasks{$_}[1]\n", $tasks{$_}[0];
-    $str .= $x;
-  }
-
-  $str .=  "\" 14 50\n";
-#  print $str;
-  system("dialog $str");
-
-}
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-server_init;
-big_loop;
diff --git a/contrib/fai/goto-fai/get_fai_dir b/contrib/fai/goto-fai/get_fai_dir
deleted file mode 100755 (executable)
index 5f24697..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/bin/sh
-# FAI script for preparing LDAP objects. It calls ldap2fai to generate
-# the config space after everything is done.
-#
-# (C) 2005 Cajus Pollmeier <pollmeier@gonicus.de>
-echo 0 > /proc/sys/kernel/printk
-trap '' INT
-PATH=/bin:/sbin:/usr/bin:/usr/sbin:$PATH
-LANG=C
-
-. /usr/lib/goto/goto-support.lib
-
-#dialog() {
-#      echo $*
-#}
-
-abort() {
-       setterm -cursor off
-       while true; do sleep 60; done
-}
-       
-# Try to figure out which interface is configured, in doubt
-# choose the first one.
-interfaces=$(ifconfig | awk '/^[a-z0-9]/ {print $1}' | grep -v "lo")
-for int in $interfaces; do
-       ip=$(v=`ifconfig $int | awk '/inet addr/ {print $2}'`; echo ${v##*:})
-       mac=$(ifconfig $int | awk '/HWaddr/ {print $5}')
-       [ -n "$ip" ] && break
-done
-
-# Cancel if there's no IP available
-if [ -z "$ip" ]; then
-       dialog --title 'Fehler' --no-shadow --infobox 'Fehler: Das System konnte keine Netzwerk-Adresse ermitteln.\n\nDie Installation kann ohne diese Adresse nicht fortgesetzt werden.' 5 60
-       abort
-fi
-
-# Check if DNS setup is correct and set the hostname
-hostname=$(get_hostname_from_ip $ip)
-if [ "$hostname" == "unknown" ]; then
-       dialog --title 'Fehler' --no-shadow --infobox 'Fehler: Das System konnte keinen Rechner-Namen ermitteln.\n\nDie Installation kann ohne diese Information nicht fortgesetzt werden.' 5 60
-       abort
-fi
-
-echo "* setting hostname: $hostname"
-hostname "$hostname"
-mount -t tmpfs tmpfs /etc/ldap
-
-
-# Look for interesting parameters on kernel commandline
-ldap=""; splash=""
-for v in $(cat /proc/cmdline); do
-   case $v in
-      ldap=*)
-                echo -n "* found LDAP information, adapting configuration: "
-                ldap=$(echo ${v##ldap=}|base64-decode)
-
-               # ldap://hostname:389/basedn
-               LDAP_HOST=$(echo $ldap|sed 's!^[^:][^:]*://\([^:/][^:/]*\).*$!\1!g')
-               LDAP_PORT=$(echo $ldap|sed 's!^[^:]*://[^:][^:]*:\([0-9]*\)/.*$!\1!g')
-               echo -n $ldap_port | grep -q '^[0-9]*$' || LDAP_PORT=389
-               LDAP_BASE=$(echo $ldap|sed 's!^[^:][^:]*://[^/][^/]*/\(.*\)$!\1!g')
-               echo -e "BASE   $LDAP_BASE\nURI     ldap://$LDAP_HOST:$LDAP_PORT\n" > /etc/ldap/ldap.conf
-                echo "ok"
-                ;;
-      splash=*)
-                echo -n "* setting splash mode: "
-                splash=$(echo ${v##splash=})
-                [ $splash == "silent" ] && echo "silent" || echo "normal"
-                ;;
-    esac
-done
-
-[ -z "$ldap" ] && exit 0
-
-# Check if autosetup is needed at this point
-echo -n "* configurator: "
-if ! terminal_has_hardware_profile $mac; then
-    setterm -cursor off
-    echo "not configured yet - please wait, detecting hardware"
-
-    # Switch from bootsplash to normal screen, show dialog
-    [ -f /proc/splash ] && echo "verbose" > /proc/splash
-
-    setterm -blank 60
-    chvt 1
-    dialog --infobox 'Bitte warten, die installierte Hardware wird untersucht...' 3 64
-
-    # Get common config
-    hwsetup
-    terminal_alsa_setup
-    terminal_autofs_setup
-
-    # Save hardware profile
-    terminal_save_hardware_profile $mac
-fi
-
-if ! terminal_activated $mac; then
-    # wait till we get activated
-    setterm -blank 60
-    chvt 1
-    dialog --infobox 'Warte auf Aktivierung durch den Systemadministrator.' 3 60
-
-    while ! terminal_activated $mac; do
-                sleep 2
-    done
-
-    # GOsa writes the GOto entry in three steps. To continue, we check
-    # if XDRIVER is present.
-    dialog --infobox 'System wurde aktiviert. Eintr�e werden nun bernommen.' 3 60
-    while ! terminal_load_hardware_profile $mac &> /dev/null; do
-       cat /etc/sysconfig/GOto | grep -v 'XDRIVER="unknown"' | grep -q 'XDRIVER'
-       sleep 2
-    done
-
-    # Enable splash if it was enabled before
-    [ -f /proc/splash ] && echo "silent" > /proc/splash
-
-    echo -n "* configurator (pass2): "
-    setterm -cursor on
-fi
-
-# Mount configuration space
-[ ! -d /tmp/goto-fai ] && mkdir /tmp/goto-fai
-mount -obind /tmp/goto-fai /fai
-ldap2fai $mac
-
-chvt 3
-exit 0
diff --git a/contrib/fai/goto-fai/goto-support.lib b/contrib/fai/goto-fai/goto-support.lib
deleted file mode 100644 (file)
index c6bdbba..0000000
+++ /dev/null
@@ -1,510 +0,0 @@
-#!/bin/sh
-###############################################################################
-#                             GOsa agent library                              #
-###############################################################################
-
-SSH='ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile /dev/null" -o "BatchMode yes" '
-
-get_hostname_from_ip() {
-       v=$(host -i $1); w=${v##*[      ]}
-       echo ${w%%.*} | grep -q 'NX'
-       if [ $? -eq 0  ]; then
-               echo "unknown"
-       else
-               echo "$v" | grep -q ';;'
-               if [ $? -eq 0 ]; then
-                       if [ -n "$HOSTNAME" ]; then
-                               echo "$HOSTNAME"
-                       else
-                               echo "unknown"
-                       fi
-               else
-                       echo ${w%%.*}
-               fi
-       fi
-}
-
-get_hostname_from_display()
-{
-        if [ -n "$DISPLAY" ]; then
-
-                HOST=${DISPLAY%%:*}
-                NUMBER=${DISPLAY##*:}
-
-                # IP addresses are not supported here
-                echo $HOST | grep -q '^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$'
-                if [ $? -ne 0 ]; then
-                        echo ${DISPLAY%%.*}
-                               else
-                                       get_hostname_from_ip $HOST
-                               fi
-
-        else
-                echo "unknown"
-        fi
-}
-
-
-kill_user_processes() {
-       # don't let root do this
-       if [ "$USER" == "root" -o $UID -eq 0 ]; then
-               return
-       fi
-
-       # Preset, or load from file
-       candidates="kdeinit\: soffice.bin mozilla-bin"
-       [ -r /etc/goto/kill-process.conf ] && candidates=$(cat /etc/goto/kill-process.conf)
-
-       # kill old existing user processes
-       for process in $candidates; do
-               ps -fu $USER | grep "$process" | grep -v 'kprogress' | awk ' FS=" " { system("kill "$2) } '
-       done
-
-       # kill old existing user processes that didn't left us with SIGTERM
-       for process in $candidates; do
-               ps -fu $USER | grep "$process" | grep -v 'kprogress' | awk ' FS=" " { system("kill "$2) } '
-       done
-}
-
-fix_ldif() {
-        (cat -; echo "bank") | awk '
-/^[a-zA-Z]/     {
-        if(line!=""){
-                print line
-        }
-
-        line    = $0
-}
-/^ /    {
-        line    = line substr($0,2)
-}
-'
-}
-
-
-ldap_init() {
-       if [ $# -ne 2 ]; then
-               for config in /etc/*ldap/ldap.conf /etc/ldap.conf; do
-
-                       # Not readable? Continue
-                       [ ! -r $config ] && continue
-
-                       # Try to read config
-                       touch /tmp/agent.$$
-                       cat $config | while read line; do
-                               echo $line | grep -q '^BASE'
-                               [ $? -eq 0 ] && echo LDAP_BASE="\"$(echo $line|tr '\t' ' '|cut -d\  -f2-)\"" >>/tmp/agent.$$
-                               echo $line | grep -q '^HOST'
-                               [ $? -eq 0 ] && echo LDAP_HOST="$(echo $line|tr '\t' ' '|cut -d\  -f2-)" >>/tmp/agent.$$
-                               echo $line | grep -q '^URI'
-                               [ $? -eq 0 ] && echo LDAP_HOST="$(v=`echo $line|tr '\t' ' '|cut -d\  -f2-`;echo ${v##*://})" >> /tmp/agent.$$
-                       done
-                       eval $(cat /tmp/agent.$$)
-                       rm /tmp/agent.$$
-
-                       # One successful configuration should be enough
-                       break
-               done
-               if [ -z "$LDAP_HOST" -o -z "$LDAP_BASE" ]; then
-                       echo "Critical: no LDAP configuration found!"
-                       exit
-               fi
-       else
-               LDAP_HOST=$1
-               LDAP_BASE=$2
-       fi
-}
-
-
-ldap_count() {
-       ldapsearch -x -LLL -h "$LDAP_HOST" -b "$LDAP_BASE" "$1" dn | grep '^dn:' | wc -l
-}
-
-
-decode_blob() {
-       base64-decode > /tmp/agent-lib-decode.$$
-       file /tmp/agent-lib-decode.$$ 2>/dev/null| grep -qi 'text'
-       [ $? -eq 0 ] && cat /tmp/agent-lib-decode.$$ | recode 'utf8..latin1'
-       [ -f /tmp/agent-lib-decode.$$ ] && rm /tmp/agent-lib-decode.$$
-}
-
-ldap_import() {
-  for v in $(set grep ldap_import_ | cut -d= -f1); do unset $v; done
-  vname_lastrun=""
-  counter=0
-  > /tmp/agent-lib.$$
-  (ldapsearch -x -LLL -h "$LDAP_HOST" -b "$LDAP_BASE" $2 "$1" $3 2> /dev/null) | fix_ldif | sed 's/^\([^:]*\):\(.*\)$/\1="\2"/' | while read line; do
-               vname=$(echo $line|cut -d= -f1)
-               vvalue=$(echo $line|cut -d= -f2-)
-
-               echo $line | grep -q '=": '
-               if [ $? -eq 0 ]; then
-                       vvalue=`echo $line|sed 's/^[^="]*=": //'|decode_blob`
-                       vvalue="$vvalue\""
-               else
-                       vvalue=`echo $line|sed 's/^[^="]*=" //'`
-               fi
-
-               if [ "$vname_lastrun" == "$vname" ]; then
-                       counter=$(( $counter + 1 ));
-               else
-                       counter=0
-                       vname_lastrun=$vname
-               fi
-               
-               echo "ldap_import_$vname[$counter]=\"$vvalue" >> /tmp/agent-lib.$$
-       done
-
-       eval $(cat /tmp/agent-lib.$$)
-       rm /tmp/agent-lib.$$
-}
-
-ldap_cat() {
-   vname_lastrun=""
-   counter=0
-   > /tmp/agent-lib.$$
-   (ldapsearch -x -LLL -h "$LDAP_HOST" -b "$1" -s base 2> /dev/null) | fix_ldif | sed 's/
-^\([^:]*\):\(.*\)$/\1="\2"/' | while read line; do
-               vname=$(echo $line|cut -d= -f1)
-               vvalue=$(echo $line|cut -d= -f2-)
-
-               echo $line | grep -q '=": '
-               if [ $? -eq 0 ]; then
-                       vvalue=`echo $line|sed 's/^[^="]*=": //'|decode_blob`
-                       vvalue="$vvalue\""
-               else
-                       vvalue=`echo $line|sed 's/^[^="]*=" //'`
-               fi
-
-               if [ "$vname_lastrun" == "$vname" ]; then
-                       counter=$(( $counter + 1 ));
-               else
-                       counter=0
-                       vname_lastrun=$vname
-               fi
-
-               echo "ldap_import_$vname[$counter]=\"$vvalue" >> /tmp/agent-lib.$$
-       done
-
-       eval $(cat /tmp/agent-lib.$$)
-       rm /tmp/agent-lib.$$
- }
-
-
-
-ldap_get_group_membership_of() {
-       ldapsearch -x -LLL -h "$LDAP_HOST" -b "$LDAP_BASE" "(memberUid=$1)" \
-                               cn 2> /dev/null | fix_ldif | awk '/^cn: / {print $2}'
-}
-
-
-ldap_get_applications_of() {
-       ldapsearch -x -LLL "(memberUid=$1)" gosaMemberApplication | fix_ldif | \
-                               awk '/^gosaMemberApplication:/ {print $2}'| sort | uniq
-}
-
-
-ldap_get_appservers() {
-       ldapsearch -x -LLL "(objectclass=goTerminalServer)" cn | fix_ldif | grep -w cn: |cut -d' ' -f 2
-}
-
-
-translate() {
-       # Look for translation
-       while read line; do
-               string="${line%%=*}"
-               if [ "$string" == "$*" ]; then
-                       echo "${line##*=}"
-                       return
-               fi
-       done < /etc/goto/goto-locales.dat
-       echo $*
-}
-
-
-show_progress() {
-       # No translation available
-       echo $PROGRESS $(translate "$*")
-}
-
-
-create_desktop_link() {
-       echo "$gosaApplicationFlags" | grep -q "D"
-       if [ $? -eq 0 ]; then
-               [ $DEBUG -eq 1 ] && echo "goto_setup: creating desktop link for application $application" 1>&2
-               cat << EOF > ~/Desktop/$cn
-[Desktop Entry]
-Comment=$description
-Encoding=UTF-8
-Exec=$gosaApplicationExecute
-Icon=$HOME/.kde/share/icons/${cn}.png
-Name=$gosaApplicationName
-Type=Application
-EOF
-       fi
-}
-
-
-create_menu_entry() {
-       echo "$gosaApplicationFlags" | grep -q "M"
-       if [ $? -eq 0 ]; then
-               [ $DEBUG -eq 1 ] && echo "goto_setup: creating menu link for application $application" 1>&2
-               cat << EOF > ~/.local/share/applications/$cn.desktop
-[Desktop Entry]
-Type=Application
-Encoding=UTF-8
-Exec=$gosaApplicationExecute
-Name=$gosaApplicationName
-GenericName=
-Comment=$description
-Icon=$HOME/.kde/share/icons/${cn}.png
-Terminal=false
-Categories=$appcat;
-EOF
-       fi
-}
-
-delete_all_applinks() {
-       list=`ldapsearch -x "objectClass=gosaApplication" cn | fix_ldif | awk '/^cn: / {print $2}'`
-       for link in $list; do
-               [ -f $HOME/Desktop/$link ] && rm -f $HOME/Desktop/$link
-               [ -f $HOME/.kde/share/applnk/$link.desktop ] && rm -rf $HOME/.kde/share/applnk/$link.desktop
-       done
-}
-
-
-function terminal_load_hardware_profile() {
-       rm -f $RAM/etc/sysconfig/GOto && touch $RAM/etc/sysconfig/GOto
-       ldapsearch -x -LLL -h $LDAP_HOST -b "$LDAP_BASE" -D "cn=terminal-admin,$LDAP_BASE" -w "$(cat /etc/goto/secret)" "(&(objectClass=gotoWorkstation)(macAddress=$1))" 2> /dev/null | fix_ldif | sed -e 's/^\([^:]*\): \(.*\)$/\U\1\E="\2"/' -e 's/^GOTO//g' >> /etc/sysconfig/GOto
-
-       # Get DN and load all parent defaults from tree
-       current=$(grep "^DN=" /etc/sysconfig/GOto|sed 's/\"//g;s/, /,/g;s/^.*,ou=terminals,ou=systems,//g')
-
-       # Load potential object group entries 
-       ldapsearch -x -LLL -h $LDAP_HOST -b "$LDAP_BASE" -D "cn=terminal-admin,$LDAP_BASE" -w "$(cat /etc/goto/secret)" "(&(objectClass=gosaGroupOfNames)(member=$(echo -n $current|sed 's/^DN=//')))" 2> /dev/null | fix_ldif | sed -e 's/^\([^:]*\): \(.*\)$/\U\1\E="\2"/' -e 's/^GOTO//g' >> /etc/sysconfig/GOto
-
-       # get reverse list of potential default entries - for backward compatibility
-       { while true; do
-               # write out current value
-               echo "ou=terminals,ou=systems,$current"
-
-               # prepare next entry
-               echo $current | grep -q ','
-               [ $? -ne 0 ] && break
-               [ "$LDAP_BASE" == "$current" ] && break
-               current=${current#*,}
-       done } | tac | while read line; do
-
-    # Read potential default entries and append
-    # them to sysconfig/GOto
-       ldapsearch -x -LLL -h $LDAP_HOST -D "cn=terminal-admin,$LDAP_BASE" -w "$(cat /etc/goto/secret)" -b $line "(&(objectClass=gotoWorkstation)(cn=wdefault))" 2> /dev/null | fix_ldif | sed -e 's/^\([^:]*\): \(.*\)$/\U\1\E="\2"/' -e 's/^GOTO//g' >> /etc/sysconfig/GOto
-  done
-
-  # Reverse sysconfig/GOto
-  tac /etc/sysconfig/GOto > /etc/sysconfig/GOto.tmp
-  mv /etc/sysconfig/GOto.tmp /etc/sysconfig/GOto
-}
-
-
-terminal_has_hardware_profile() {
-       # Do we have a configuration?
-       terminal_load_hardware_profile $1
-       grep -v "cn=default," /etc/sysconfig/GOto | grep -q "DN="
-}
-
-
-terminal_activated() {
-       # Do we have a configuration?
-       terminal_load_hardware_profile $1
-       grep -v ',ou=incoming,' /etc/sysconfig/GOto | grep -v 'cn=default,' | grep -q "DN="
-}
-
-
-terminal_dump_hwprofile() {
-       # Save mac address
-       mac=$1
-       name=$(hostname)
-       
-       # Source hardware information detected by hwsetup
-       for module in xserver sound netcard mouse; do
-               [ -f /etc/sysconfig/$module ] && . /etc/sysconfig/$module
-       done
-
-       # Get hardware information directly from /proc
-       cpu=$(cat /proc/cpuinfo | awk 'BEGIN { FS=": "; ORS="" } /^vendor_id/ {print $2" / "} /^model name/{print $2" - "} /^cpu MHz/ {print $2" MHz"}')
-       mem=$(cat /proc/meminfo | awk '/^MemTotal:/ {print $2" KB"}')
-       modlist=$(lsmod | sed -e '/^Module/d;/^snd/d;s/^\(\w*\).*$/\1/g')
-       hsync=$(ddcxinfo-knoppix -hsync|tr -d ' ')
-       vsync=$(ddcxinfo-knoppix -vsync|tr -d ' ')
-
-       # USB support?
-       [ -d /proc/bus/usb ] && usb="true" || usb="false"
-
-       # Add floppy/cdrom
-       grep -q 'floppy' /etc/sysconfig/autofs && FLOPPY='YES' || FLOPPY='NO'
-       grep -q 'cdrom' /etc/sysconfig/autofs && CDROM='YES' || CDROM='NO'
-
-       cat << EOF
-dn: cn=$name,ou=incoming,$LDAP_BASE
-objectClass: gotoWorkstation
-objectClass: goHard
-cn: $name
-macAddress: $mac
-gotoMode: locked
-gotoXDriver: $XMODULE
-gotoXMouseType: $XMOUSETYPE
-gotoXMouseport: $DEVICE
-gotoXHsync: $hsync
-gotoXVsync: $vsync
-ghUsbSupport: $usb
-gotoFloppyEnable: $FLOPPY
-gotoCdromEnable: $CDROM
-gotoSndModule: $SNDMODULE
-EOF
-
-       # Insert IDE-Devices
-       for f in /proc/ide/ide?/hd?/model; do
-               [ -f $f ] && echo "ghIdeDev: "$(echo $f | cut -d/ -f5)" ("$(cat $f)")"
-       done
-
-       (cat /proc/scsi/scsi | sed -ne 's/.*Vendor: \([^ ]*\) *Model: \([^ ]*\) *.*$/\1 \2/p') 2> /dev/null|while read line; do
-               echo ghScsiDev: $line
-       done
-
-       # Insert modules
-       for m in $modlist; do
-               echo "gotoModules: $m"
-       done | sort | uniq
-
-       # Add potential swap filesystems
-       [ -f /etc/sysconfig/swap ] && cat /etc/sysconfig/swap | while read line; do
-               echo "gotoFilesystem: $line"
-       done
-
-       # Add autofs devices
-       [ -f /etc/sysconfig/autofs ] && cat /etc/sysconfig/autofs | while read line; do
-               echo "gotoAutoFs: $line"
-       done
-
-       cat << EOF
-ghGfxAdapter: $XDESC
-ghNetNic: `cat /etc/sysconfig/netcard|grep "^FULLNAME"|cut -d= -f2|tr -d "\""`
-ghSoundAdapter: `cat /etc/sysconfig/sound|grep "^FULLNAME"|cut -d= -f2|tr -d "\""`
-ghMemSize: $mem
-ghCpuType: $cpu
-EOF
-}
-
-
-terminal_save_hardware_profile() {
-       # Get hardware ldif and strip out possibly broken entries
-    terminal_dump_hwprofile $1 | grep -v '^[^:]*: *$' &> /tmp/upload.ldif
-
-       # Upload ldif
-       while true; do
-               error=$(ldapadd -x -h "$LDAP_HOST" -D "cn=terminal-admin,$LDAP_BASE" -w "$(cat /etc/goto/secret)" < /tmp/upload.ldif 2>&1)
-               if [ $? -ne 0 ]; then
-                       dialog --msgbox "Das Terminal konnte sich nicht am LDAP anmelden. Bitte prüfen Sie de Einstellungen: $error" 14 60
-               else
-                       break
-               fi
-       done
-}
-
-
-terminal_alsa_setup() {
-       audio=$(lspci -n | awk '/ 0401/ {print $3}' | sed 's/://g' | head -1)
-       KVER=$(uname -r)
-       MODULE=$(cat /lib/modules/$KVER/modules.pcimap | (while read driver vendor device dummy; do
-               if expr $driver : 'snd-.*' > /dev/null; then
-                       printf '%04x%04x %s\n' $vendor $device $driver | grep "^$audio" | cut -d\  -f2
-               fi
-       done))
-       echo "SNDMODULE=\"$MODULE\"" >> /etc/sysconfig/sound
-}
-
-
-terminal_autofs_setup(){
-       wcount=1
-       lcount=1
-
-       # Remove old ones
-       rm -f /etc/sysconfig/autofs /etc/sysconfig/swap
-
-       # Generate autofs entries for removable devices
-       for d in /dev/floppy/?; do
-               [ "$d" == "/dev/floppy/?" ] && break
-               nr=$(echo $d | sed 's/^.*\/\([^/]*$\)/\1/g')
-               echo "floppy$nr -fstype=auto,sync,nodev,nosuid,umask=000,quiet,rw :$d" >> /etc/sysconfig/autofs
-       done
-
-       for d in /dev/cdroms/*; do
-               [ "$d" == "/dev/cdroms/*" ] && break
-               name=`echo $d | sed 's/^.*\/\([^/]*$\)/\1/g'`
-               echo "$name -fstype=iso9660,sync,nodev,nosuid,umask=000,quiet,ro :$d" >> /etc/sysconfig/autofs
-       done
-
-       # Generate autofs entries for fixed drives
-       (sfdisk -qLl | grep "^/" | tr -d '\*') | while read device d1 d2 d3 d4 type d5; do
-        case $type in
-         [4bce])
-               echo "win$wcount -fstype=vfat,sync,nodev,nosuid,umask=000,quiet,rw :$device" >> /etc/sysconfig/autofs
-               wcount=$(( $wcount + 1 ))
-               ;;
-         7)
-               echo "win$wcount -fstype=ntfs,sync,nodev,nosuid,umask=000,quiet,ro :$device" >> /etc/sysconfig/autofs
-               wcount=$(( $wcount + 1 ))
-               ;;
-         83)
-               echo "linux$lcount -fstype=ext3,sync,nodev,nosuid,umask=000,quiet,rw :$device" >> /etc/sysconfig/autofs
-               lcount=$(( $lcount + 1 ))
-               ;;
-      82)
-                echo "$device none swap sw 0 0" >> /etc/sysconfig/swap
-               ;;
-        esac
-       done
-}
-
-
-get_xdmcp_server(){
-       SERVERS=$(ldapsearch -LLL -b "$LDAP_BASE" -H $LDAP_HOST -x '(&(objectclass=goTerminalServer)(goXdmcpIsEnabled=true))'| awk '/^cn/{print $2}' 2> /dev/null)
-
-       # Generate load sorted server list
-       { for s in $SERVERS; do
-               xdmping $s -v -t 1 2> /dev/null | awk '!/contacting/ {print $5"|"$1"|"$2}' | sed 's/[:,]//g'
-       done } | egrep "^[0-9]" | sort -n > /tmp/xservers.tmp
-
-       case $(cat /tmp/xservers.tmp | wc -w | awk '{print $1}') in
-               0)
-                       return
-                       ;;
-               1)
-                       cat /tmp/xservers.tmp | cut -d\| -f2
-                       return
-            ;;
-               *)
-                       AVAILABLE=""
-                       for i in $(cat /tmp/xservers.tmp); do
-                               NEW=$(echo "$i" | awk -F "|" '{if ($1 < 0.5) print $1"|"$2}')
-                               [ -n "$NEW" ] && AVAILABLE="$NEW\n$AVAILABLE"
-                       done
-                       if [ -n "$AVAILABLE" ]; then
-                               echo -e "$AVAILABLE" > /tmp/xservers.tmp
-                               NUM=$(cat /tmp/xservers.tmp | wc -l | awk '{print $1 - 1}')
-                               ROW=$(echo $NUM | awk '{print rand() * $1 + 1 ;}' | cut -d . -f1)
-                               cat /tmp/xservers.tmp | sed -n "${ROW}p" | cut -d\| -f2
-                       else
-                               cat /tmp/xservers.tmp|egrep "^[0-9]"|tr "." ","|sort -n|head -1|cut -d\| -f2
-                       fi
-                       ;;
-       esac
-}
-
-
-get_fontpath() {
-       ldapsearch -x -LLL -h $LDAP_HOST -b "$LDAP_BASE" "(&(objectClass=goTerminalServer)(cn=$1))" |
-               grep "^goFontPath" | cut -d\  -f2- | sed 's!\/!\/!g'
-}
-
diff --git a/contrib/fai/goto-fai/ldap2fai b/contrib/fai/goto-fai/ldap2fai
deleted file mode 100755 (executable)
index 50f315d..0000000
+++ /dev/null
@@ -1,630 +0,0 @@
-#!/usr/bin/perl
-# $Id$
-#*********************************************************************
-#
-# ldap2fai -- read FAI config from LDAP and create config space
-#
-# This script is part of FAI (Fully Automatic Installation)
-# (c) 2005, Thomas Lange <lange@informatik.uni-koeln.de>
-# (c) 2005, Jens Nitschke <jens.nitschke@2int.de>
-# (c) 2005, Jan-Marek Glogowski <glogow@fbihome.de>
-# (c) 2005, Cajus Pollmeier <pollmeier@gonicus.de>
-#
-#*********************************************************************
-
-use strict;
-use Net::LDAP;
-use MIME::Base64;
-use Getopt::Std;
-use File::Path;
-use File::Copy;
-use vars qw/ %opt /;
-
-my $base;
-my $ldapuri;
-my $ldapdir = "/etc/ldap/ldap.conf";
-my $outdir = "/fai";
-my $verbose = 0;
-my $opt_string = 'c:d:hv';
-my $hostname;
-
-getopts( "$opt_string", \%opt ) or usage("Hello");
-usage("Help") if $opt{h};
-
-$verbose = $opt{v} ? 1 : 0;
-$outdir  = $opt{d} ? $opt{d} : $outdir;
-$ldapdir = $opt{c} ? $opt{c} : $ldapdir;
-
-# Get MAC from cmdline
-my $mac = shift @ARGV;
-$mac eq '' && usage("MAC address not specified.");
-
-# Is outdir a directory
--d "$outdir" || usage("'$outdir' is not a directory.\n");
-
-my @classes=(); # the classes a host belongs to
-
-# initialize ldap
-setup();
-my $ldap = Net::LDAP->new("$ldapuri") or die "$@";
-my $mesg = $ldap->bind;
-
-# create class hooks debconf disk_config package_config scripts files
-my @dirs= qw/class hooks debconf disk_config package_config scripts files/;
-foreach (@dirs) {
-  -d "$outdir/$_" || mkpath "$outdir/$_" 
-    || warn "WARNING: Can't create subdir $outdir/$_ $!\n";
-}
-
-@classes= get_classes($mac);
-prt_scripts();
-prt_package_list();
-prt_debconf();
-prt_templates();
-prt_var();
-prt_hooks();
-prt_disk_config();
-
-# create sources list
-if (!$hostname) {
-  -d "${outdir}/files/etc/apt/sources.list" 
-    || mkpath "${outdir}/files/etc/apt/sources.list";
-  copy ("${outdir}/tmp/apt-sources.list",
-    "${outdir}/files/etc/apt/sources.list/$hostname") ;
-}
-
-$mesg = $ldap->unbind;   # take down session
-exit 0;
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub setup
-{
-  # Read LDAP
-  open (LDAPCONF,"${ldapdir}") 
-    || usage("Can't open LDAP configuration$!\n");
-  my @content=<LDAPCONF>;
-  close(LDAPCONF);
-
-  # Scan LDAP config
-  foreach my $line (@content) {
-    $line =~ /^\s*(#|$)/ && next;
-    chomp($line);
-
-    if ($line =~ /^BASE\s+(.*)$/) {
-      $base= $1;
-      next;
-    }
-    if ($line =~ m#^URI\s+ldaps?://([^/:]+).*$#) {
-      $ldapuri= $1;
-      next;
-    }
-  }
-}
-
-sub usage
-{
-  (@_) && print STDERR "\n@_\n\n";
-
-  print STDERR << "EOF";
-usage: $0 [-hv] [-c config] [-d outdir] <MAC>
-
--h        : this (help) message
--c        : LDAP config file (default: ${ldapdir})
--d        : output dir (default: ${outdir})
--v        : be verbose
-EOF
-       exit -1;
-}
-#-----------------------------------------------------------------------------------
-
-sub write_file {
-
-       my @opts = @_;
-       my $len = scalar @_;
-       ($len < 2) && return;
-
-       my $filename = shift;
-       my $data = shift;
-
-       open (SCRIPT,">${filename}") || warn "Can't create ${filename}. $!\n";
-       print SCRIPT $data;
-       close(SCRIPT);
-
-  ($opts[2] ne "") && chmod oct($opts[2]),${filename};
-       ($opts[3] ne "") && chown_files(${filename}, $opts[3]);
-}
-
-#-----------------------------------------------------------------------------------
-
-sub chown_files
-{
-  my @owner = split('.',@_[1]);
-  my $filename = @_[0];
-  my ($uid,$gid);
-  $uid = getpwnam(@owner[0]);
-  $gid = getgrnam(@owner[1]);
-  
-  chown $uid, $gid, $filename;
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub get_classes {
-
-       # return list of FAI classes defined for host
-       my $mac = shift;
-       my (@classes,$mesg,$entry);
-
-  $mesg = $ldap->search(
-    base => "ou=systems,$base",
-    filter => "(&(macAddress=$mac)(objectClass=gotoWorkstation))",
-    attrs => [ 'FAIclass', 'cn']);
-  $mesg->code && die $mesg->error;
-  # normally, only one value should be returned
-  if ($mesg->count != 1) {
-      die "LDAP search for client failed. ".$mesg->count." entries have been returned\n";
-    }
-  
-   # this assigns the last value to @classes     
-   $entry= ($mesg->entries)[0];
-   @classes= split /\s+/,$entry->get_value('FAIclass');
-
-  # get hostname
-       my $hname= $entry->get_value('cn');
-  my $dn= $entry->dn;
-  $hostname= $hname;
-
-  # Search for object groups containing this client
-  $mesg = $ldap->search(
-    base => "ou=groups,$base",
-    filter => "(&(objectClass=gosaGroupOfNames)(objectClass=FAIobject)(member=$dn))",
-    attrs => [ 'FAIclass' ]);
-  $mesg->code && die $mesg->error;
-       foreach my $m ($mesg->entries) {
-    push @classes, split /\s+/,$m->get_value('FAIclass');
-  }
-
-       # print all classes to the file with hostname
-       open (FAICLASS,">$outdir/class/$hname") || warn "Can't create $outdir/class/$hname. $!\n";
-  my @newclasses;
-       foreach my $class (@classes) {
-
-    # We need to walk through the list of classes and watch out for
-    # a profile which is named like the class. Replace the profile
-    # name by the names of the included classes.
-    $mesg = $ldap->search(
-      base => "ou=systems,$base",
-      filter => "(&(objectClass=FAIprofile)(cn=$class))",
-      attrs => [ 'FAIclass' ]);
-    $mesg->code && die $mesg->error;
-
-    if ($mesg->count > 0){
-      foreach my $m ($mesg->entries) {
-        foreach my $tc (split /\s+/,$m->get_value('FAIclass')){
-          print FAICLASS "$tc\n";
-          push @newclasses, $tc;
-        }
-      }
-    } else {
-      print FAICLASS "$class\n";
-      push @newclasses, $class;
-    }
-  }
-       close(FAICLASS);
-       print "Host $hname belongs to FAI classes: ",join ' ',@newclasses,"\n" if $verbose;
-       return @newclasses;
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub get_variables {
-       # gets all variables defined for a class
-       # returns a list of lines in bourne shell syntax
-
-   my $class = shift; 
-        my ($mesg,$var_base,$entry,$line,@vars);
-
-        $mesg = $ldap->search(
-                      base => "$base",
-                      filter => "(&(cn=$class)(objectClass=FAIvariable))",
-                      attrs => [ 'cn']);
-        return if ($mesg->count() == 0); # skip if no such object exists              
-        $mesg->code && die $mesg->error;
-
-        $entry=($mesg->entries)[0];
-        $var_base=$entry->dn;
-
-        $mesg = $ldap->search(
-                        base => "$var_base",
-                        filter => "(objectClass=FAIvariableEntry)",
-                        attrs => ['cn', 'FAIvariableContent']);
-        return if ($mesg->count() == 0); # skip if no such object exists
-        $mesg->code && die $mesg->error;
-                        
-
-        foreach $entry ($mesg->entries) {
-                $line= sprintf "%s=\'%s\'\n", $entry->get_value('cn'), 
-                        $entry->get_value('FAIvariableContent');
-                push @vars,$line;
-        }
-        return @vars;
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub prt_var {
-
-       my (@lines, $hname);
-
-       foreach my $class (@classes) {
-               @lines = get_variables($class);
-               next until @lines; # do not create .var file if no variables are defined
-               open (FAIVAR,">$outdir/class/${class}.var") 
-      || warn "Can't create $outdir/class/$hname.var.$!\n";
-               print FAIVAR @lines;
-               close(FAIVAR);
-       }
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub get_disk_config {
-
-       my $class = shift;
-  my ($mesg,$entry,$line,@diskconfig,$partition_base,$dn,%diskline,$xxmesg);
-
-       # Search for partition schema for the specified class
-       $mesg = $ldap->search(
-                     base => "$base",
-                     filter => "(&(cn=$class)(objectClass=FAIpartitionTable))" );
-
-       return if ($mesg->count() == 0); # skip if no such object exists
-       $mesg->code && die $mesg->error;
-
-       $entry=($mesg->entries)[0];
-       $partition_base= $entry->dn;
-       
-       # Search for disks
-       $mesg = $ldap->search(
-                     base => "$partition_base",
-                     filter => "(objectClass=FAIpartitionDisk)" );
-
-       return if ($mesg->code == 32); # skip if no such object exists
-       $mesg->code && die $mesg->error;
-
-       foreach $entry ($mesg->entries) {
-    my $logic_count= 4;
-    my $primary_count= 0;
-               my $dn=$entry->dn;
-               my $disk=$entry->get_value('cn');
-    my $part;
-               undef %diskline;
-               $diskline{0} = "disk_config $disk\n";
-               $xxmesg = $ldap->search(
-                       base => "$dn",
-                       filter => "objectClass=FAIpartitionEntry" );
-               $xxmesg->code && die $xxmesg->error;
-               foreach my $dl ($xxmesg->entries) {
-      if ($dl->get_value('FAIpartitionType') eq 'primary'){
-        $primary_count++;
-      } else {
-        $logic_count++;
-      }
-                       if ($dl->get_value('FAIpartitionFlags') eq 'preserve'){
-        if ($dl->get_value('FAIpartitionType') eq 'primary'){
-          $part= 'preserve'.$primary_count;
-        } else {
-          $part= 'preserve'.$logic_count;
-        }
-                               $line= sprintf "%-7s %-12s %-12s %-10s ; %s\n",
-                                       $dl->get_value('FAIpartitionType'),
-                                       $dl->get_value('FAImountPoint'),
-                                       $part,
-                                       $dl->get_value('FAImountOptions') eq '' 
-                                               ? 'rw' : $dl->get_value('FAImountOptions'),
-                                       $dl->get_value('FAIfsOptions');
-                       }         
-                       elsif ($dl->get_value('FAIfsType') eq 'swap'){
-                               $line= sprintf "%-7s %-12s %-12s %-10s\n",
-                               $dl->get_value('FAIpartitionType'),
-                               $dl->get_value('FAImountPoint'),
-                               $dl->get_value('FAIpartitionSize'),
-                               $dl->get_value('FAImountOptions') eq '' 
-                                       ? 'rw' : $dl->get_value('FAImountOptions');
-                       } 
-                       else {
-                               $line= sprintf "%-7s %-12s %-12s %-10s ; %s %s\n",
-                               $dl->get_value('FAIpartitionType'),
-                               $dl->get_value('FAImountPoint'),
-                               $dl->get_value('FAIpartitionSize'),
-                               $dl->get_value('FAImountOptions') eq '' 
-                                       ? 'rw' : $dl->get_value('FAImountOptions'),
-                               $dl->get_value('FAIfsOptions'),
-                               $dl->get_value('FAIfsType');
-                       }
-
-                       $diskline{$dl->get_value('FAIpartitionNr')}=$line;
-               }
-               foreach my $l (sort {$a <=> $b} keys %diskline) {
-                       push @diskconfig, $diskline{$l};
-               }
-       }
-       return @diskconfig;
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub prt_disk_config {
-
-       # create one disk_config file
-
-       my ($class,@lines);
-
-       foreach $class (reverse @classes) {
-               @lines=get_disk_config($class);
-               next until @lines; # skip if nothing is defined for this class
-
-    print "Generating partition layout for class '${class}'\n." if $verbose;
-               open (FAIVAR,">${outdir}/disk_config/${class}") 
-      || warn "Can't create $outdir/disk_config/$class. $!\n";
-               print FAIVAR join '',@lines;
-               close(FAIVAR);
-               last; # finish when one config file is created
-       }
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub get_packages {
-
-       # gets list of packages defined for a class
-
-       my $class = shift;
-       my ($mesg,$entry,$line,$method,%packlist);
-
-  -d "${outdir}/tmp" || mkpath "${outdir}/tmp"
-    || warn "Can't create ${outdir}/tmp. $!\n";
-  print "Generate sources.list for install\n" if $verbose;
-       open (SOURCES,">>${outdir}/tmp/apt-sources.list") 
-    || warn "Can't create ${outdir}/tmp/apt-sources.list. $!\n";
-
-       $mesg = $ldap->search(
-                       base => "$base",
-                       filter => "(&(cn=$class)(objectClass=FAIpackageList))" ,
-                       attrs => [ 'FAIpackage', 'FAIinstallMethod', 
-                 'FAIdebianMirror', 'FAIdebianRelease', 'FAIdebianSection']);
-
-       $mesg->code && die $mesg->error;
-       # should also return only one value
-
-       undef %packlist;
-       foreach $entry ($mesg->entries) {
-               $method=$entry->get_value('FAIinstallMethod');
-               push @{$packlist{$method}}, $entry->get_value('FAIpackage');
-
-               print SOURCES "deb ".$entry->get_value('FAIdebianMirror')." ".$entry->get_value('FAIdebianRelease')." ";
-    my $section;
-    foreach $section ($entry->get_value('FAIdebianSection')){
-      print SOURCES "$section ";
-    }
-    print SOURCES "\n";
-       }
-
-  close (SOURCES);
-
-       # return a ref to the hash of arrays (key of the hash is the method),
-       # the value is the array of package names for this method
-       return \%packlist;
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub prt_package_list {
-
-       my (@lines,$plist,$method,$value);
-
-       foreach my $class (@classes) {
-               $plist=get_packages($class);
-               # test if hash contains any keys or values
-               unless (keys %{$plist}) {
-                       next;
-               }
-
-    print "Generate package list for class '$class'.\n" if $verbose;
-               open (PACKAGES,">$outdir/package_config/$class") 
-      || warn "Can't create $outdir/package_config/$class. $!\n";
-               while (($method, $value) = each %{$plist}) {
-                       print PACKAGES "PACKAGES $method\n";
-                       print PACKAGES join "\n",@{$value};
-                       print PACKAGES "\n";
-               }
-               close(PACKAGES);
-       }
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub get_templates {
-
-       # get list of template-files defined for a class
-       my $class = shift;
-       my ($mesg,$entry,$str,$pfad,$name,$owner,$mode,$template_base,@template);
-
-       $mesg = $ldap->search(
-                       base => "$base",
-                       filter => "(&(cn=$class)(objectClass=FAItemplate))",
-                       attrs => ['cn']);
-       return if ($mesg->count() == 0); # skip if no such object exists
-       $mesg->code && die $mesg->error;
-
-       $entry=($mesg->entries)[0];
-       $template_base=$entry->dn;
-
-       $mesg = $ldap->search(
-                       base => "$template_base",
-                       filter => "(objectClass=FAItemplateEntry)",
-                       attrs => ['FAItemplateFile', 'FAItemplatePath', 'FAIowner', 'FAImode' ,'cn']);
-       return if ($mesg->count() == 0); # skip if no such object exists
-       $mesg->code && die $mesg->error;
-
-       foreach $entry ($mesg->entries) {
-               $name = $entry->get_value('cn');
-               $owner = $entry->get_value('FAIowner');
-               $owner = $entry->get_value('FAImode');
-               $pfad = $entry->get_value('FAItemplatePath');
-               chomp($pfad);
-               -d "${outdir}/files/${pfad}" || mkpath "${outdir}/files/${pfad}"
-      || warn "WARNING: Can't create subdir ${outdir}/files/${pfad} !$\n";
-    print "Generate template '$pfad' ($name) for class '$class'.\n" if $verbose;
-               write_file( "${outdir}/files/${pfad}/${class}", 
-                       $entry->get_value('FAItemplateFile'),$entry->get_value('FAImode'),$entry->get_value('FAIowner'));
-       }
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub prt_templates {
-       my ($class);
-
-       foreach $class (reverse @classes) {
-               get_templates($class);
-       }
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub get_debconf {
-
-       # gets list of packages defined for a class
-
-       my $class = shift; 
-       my ($mesg,$entry,$str,$debconf_base,@debconf);
-
-       $mesg = $ldap->search(
-                       base => "$base",
-                       filter => "(&(cn=$class)(objectClass=FAIpackageList))",
-                       attrs => ['cn']);
-       return if ($mesg->count() == 0); # skip if no such object exists
-       $mesg->code && die $mesg->error;
-
-       $entry=($mesg->entries)[0];
-       $debconf_base=$entry->dn;
-
-       $mesg = $ldap->search(
-                       base => "$debconf_base",
-                       filter => "(objectClass=FAIdebconfInfo)" ,
-                       attrs => [ 'FAIpackage', 'FAIvariable', 
-                               'FAIvariableType','FAIvariableContent']);
-       $mesg->code && die $mesg->error;
-
-       # undef @debconf;
-       foreach $entry ($mesg->entries) {
-               $str = sprintf "%s %s %s %s\n",
-               $entry->get_value('FAIpackage'),
-               $entry->get_value('FAIvariable'),
-               $entry->get_value('FAIvariableType'),
-               $entry->get_value('FAIvariableContent');
-               push @debconf, $str;
-       }
-       return @debconf;
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub prt_debconf {
-
-       my @lines;
-       my $class;
-
-       foreach $class (@classes) {
-               @lines = get_debconf($class);
-               next until @lines;
-    print "Generate DebConf for class '$class'.\n" if $verbose;
-               open (DEBCONF,">${outdir}/debconf/${class}") || warn "Can't create $outdir/debconf/$class. $!\n";
-               print DEBCONF @lines;
-               close(DEBCONF);
-       }
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub prt_scripts {
-       my ($class,@lines);
-
-       foreach $class (@classes) {
-               get_scripts($class);
-       }
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub get_scripts {
-
-       # gets list of packages defined for a class
-
-       my $class = shift;
-       my ($mesg,$entry,$str,$script_base,$prio,$name,$script);
-
-       $mesg = $ldap->search(
-                       base => "$base",
-                       filter => "(&(cn=$class)(objectClass=FAIscript))",
-                       attrs => ['cn']);
-       return if ($mesg->count() == 0); # skip if no such object exists
-       $mesg->code && die $mesg->error;
-
-       $entry=($mesg->entries)[0];
-       $script_base= $entry->dn;
-
-       $mesg = $ldap->search(
-                       base => "$script_base",
-                       filter => "(objectClass=FAIscriptEntry)",
-                       attrs => ['FAIpriority', 'FAIscript', 'cn']);
-       return if ($mesg->count() == 0); # skip if no such object exists
-       $mesg->code && die $mesg->error;
-       
-       foreach $entry ($mesg->entries) {
-               $name  = $entry->get_value('cn');
-               $prio  = $entry->get_value('FAIpriority');
-               $script= sprintf('%02d-%s', $prio, $name);
-
-    -d "$outdir/scripts/$class" || mkpath "$outdir/scripts/$class" ||
-       warn "WARNING: Can't create subdir $outdir/scripts/$class !$\n";
-
-               write_file("${outdir}/scripts/${class}/${script}",
-                       $entry->get_value('FAIscript'), "0700");
-       }
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub prt_hooks {
-       my ($class,@lines);
-
-       foreach $class (reverse @classes) {
-               get_hooks($class);
-       }
-}
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-sub get_hooks {
-
-       # gets list of packages defined for a class
-
-       my $class = shift;
-       my ($mesg,$entry,$str,$hook_base,$prio,$task,$hook,$name);
-
-       $mesg = $ldap->search(
-                       base => "$base",
-                       filter => "(&(cn=$class)(objectClass=FAIhook))",
-                       attrs => ['cn']);
-       return if ($mesg->count() == 0); # skip if no such object exists
-       $mesg->code && die $mesg->error;
-
-       $entry=($mesg->entries)[0];
-       $hook_base= $entry->dn;
-
-       $mesg = $ldap->search(
-                       base => "$hook_base",
-                       filter => "(objectClass=FAIhookEntry)",
-                       attrs => ['FAItask', 'FAIscript', 'cn']);
-       return if ($mesg->count() == 0); # skip if no such object exists
-       $mesg->code && die $mesg->error;
-       
-       foreach $entry ($mesg->entries) {
-               $name = $entry->get_value('cn');
-               $task = $entry->get_value('FAItask');
-               $prio = $entry->get_value('FAIpriority');
-               $hook = sprintf('%s.%s', ${task}, ${class});
-
-               write_file("${outdir}/hooks/${hook}", 
-                       $entry->get_value('FAIscript'), "0700");
-       }
-}
-
-# vim:ts=2:sw=2:expandtab:shiftwidth=2:syntax:paste
diff --git a/contrib/fai/goto-fai/secret b/contrib/fai/goto-fai/secret
deleted file mode 100644 (file)
index 7f480a8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-your secret terminal-admin password
diff --git a/contrib/fix_munged.php b/contrib/fix_munged.php
deleted file mode 100755 (executable)
index 405d345..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/php
-<?php
-require_once('../include/class_sambaMungedDial.inc');
-
-/*
-       * GOsa: fix_munged.php - Modify existings sambaMungedDial-Entries to work with latest Win2003SP1 
-       *
-       * Authors: Jan Wenzel    <jan.wenzel@GONICUS.de>
-       *
-       * Copyright (C) 2006 GONICUS GmbH
-       *
-       * This program is free software; you can redistribute it and/or modify
-       * it under the terms of the GNU General Public License as published by
-       * the Free Software Foundation; either version 2 of the License, or
-       * (at your option) any later version.
-       *
-       * This program is distributed in the hope that it will be useful,
-       * but WITHOUT ANY WARRANTY; without even the implied warranty of
-       * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       * GNU General Public License for more details.
-       *
-       * You should have received a copy of the GNU General Public License
-       * along with this program; if not, write to the Free Software
-       * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
-       * USA
-       *
-       * Contact information: GONICUS GmbH
-       * Moehnestrasse 11-17
-       * D-59755 Arnsberg
-       * Germany
-       * tel: ++49 2932 916 0
-       * fax: ++49 2932 916 230
-       * email: info@GONICUS.de
-       * http://www.GONICUS.de
-       * */
-
-/* Modify these settings to your needs */
-$ldap_host= "localhost";
-$ldap_port= "389";
-$ldap_base= "dc=gonicus,dc=de";
-$ldap_admin= "cn=ldapadmin,".$ldap_base;
-$ldap_password= "tester";
-
-/* Internal Settings */
-$ldap_protocol= "3";
-$filter= "(&(objectClass=sambaSamAccount)(sambaMungedDial=*))";
-$attributes= array("dn","sambaMungedDial");
-
-print("This script will try to convert all ldap entries that have the sambaMungedDial-Attribute set, into the new \n".
-           "format that win2003sp1 and later requires. If an entry is already in the new format, it is not touched. \n".
-                       "BEWARE: This script is not widely tested yet, so use it at your own risk! Be sure to backup your complete LDAP \n".
-                       "before running.\n".
-                       "Do you want to continue (y/n)?\n");
-
-$handle= fopen("php://stdin","r");
-$input=(fgets($handle,16));
-fclose($handle);
-if(substr(strtolower($input),0,1)!="y") {
-       exit(1);
-}
-/* Connect to server */
-$connection= ldap_connect($ldap_host,$ldap_port) 
-       or die ('Could not connect to server '.$ldap_host."\n!");
-ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, $ldap_protocol);
-ldap_bind($connection,$ldap_admin,$ldap_password)
-       or die ('Could not bind to server '.$ldap_host."!\n");
-
-$results= ldap_get_entries($connection, ldap_search($connection, $ldap_base, $filter, $attributes));
-
-$count= 0;
-
-if(array_key_exists('count', $results)) {
-       $count= $results['count'];
-}
-
-if($count > 0) {
-       print('We found '.$count.' matching '.(($count==1)?'entry':'entries').".\n");
-}
-
-for($i=0; $i<$count; $i++) {
-       $entry= $results[$i];
-       print('Converting '.$entry['dn'].'...'); 
-       $mungedDial = new sambaMungedDial();
-       $mungedDial->load($entry['sambamungeddial'][0]);
-       $modify['sambaMungedDial'][0]= $mungedDial->getMunged();
-       if(ldap_modify($connection,$entry['dn'],$modify)) {
-               print("done.\n");
-       } else {
-               print("failed.\n");
-       }
-}
-
-ldap_close($connection);
-?>
-
diff --git a/contrib/gosa.conf b/contrib/gosa.conf
deleted file mode 100644 (file)
index 26a9ee2..0000000
+++ /dev/null
@@ -1,571 +0,0 @@
-{literal}<?xml version="1.0"?>{/literal}
-<conf>
-       <menu>
-               <section name="My account">
-                       <plugin acl="users/generic" class="user" icon="personal.png"
-                               path="plugins/personal/generic" />
-                       <plugin acl="users/posixAccount" class="posixAccount" icon="posix.png"
-                               path="plugins/personal/posix" />
-                       <plugin acl="users/environment" class="environment" icon="env.png"
-{if $cv.optional.kioskpath_active}
-                               kioskpath="{$cv.optional.kioskpath}"
-{/if}
-                               path="plugins/personal/environment" />
-                       <plugin acl="users/mailAccount" class="mailAccount" icon="email.png"
-                               path="plugins/personal/mail" />
-                       <plugin acl="users/sambaAccount" class="sambaAccount" icon="samba.png"
-                               path="plugins/personal/samba" />
-{if $cv.use_netatalk}
-                       <plugin acl="users/netatalk" class="netatalk" icon="netatalk.png"
-                               path="plugins/personal/netatalk" />
-{else}
-<!--
-                       <plugin acl="default" class="netatalk" icon="netatalk.png"
-                               path="plugins/personal/netatalk" />
--->
-{/if}
-                       <plugin acl="users/connectivity" class="connectivity" icon="proxy.png"
-                               path="plugins/personal/connectivity" />
-                       <plugin acl="users/gofaxAccount" class="gofaxAccount" icon="fax.png"
-                               path="plugins/gofax/faxaccount" />
-                       <plugin acl="users/phoneAccount" class="phoneAccount" icon="phone.png"
-                               path="plugins/gofon/phoneaccount" />
-<!--
-                       <plugin acl="users/nagiosAccount" class="nagiosAccount" icon="monitoring.png"
-                               path="plugins/personal/nagios" />
--->
-                       <plugin acl="users/password" class="password" icon="password.png"
-                               path="plugins/personal/password" />
-               </section>
-               
-               <section name="Administration">
-                       <plugin acl="users" class="userManagement" icon="user.png"
-                               path="plugins/admin/users" />
-                       <plugin acl="groups" class="groupManagement" icon="group.png"
-                               path="plugins/admin/groups" />
-                       <plugin acl="ogroups" class="ogroupManagement" icon="ogroup.png"
-                               path="plugins/admin/ogroups" />
-                       <plugin acl="department" class="departmentManagement" icon="department.png"
-                               path="plugins/admin/departments" />
-                       <plugin acl="application" class="applicationManagement"
-                               icon="application.png" path="plugins/admin/applications" />
-                       <plugin acl="terminal,workstation,server,phone,printer,component,winworkstation" class="systems" icon="system.png"
-                               path="plugins/admin/systems" />
-{if $cv.enableMimeType}
-                       <plugin acl="mimetypes" class="mimetypeManagement"
-                               icon="mimetypes.png" path="plugins/admin/mimetypes" />
-{else}
-<!--
-                       <plugin acl="mimetype" class="mimetypeManagement"
-                               icon="mimetypes.png" path="plugins/admin/mimetypes" />
--->
-{/if}
-                       <plugin acl="devices" class="deviceManagement"
-                               icon="devices.png" path="plugins/admin/devices" />
-
-                       <!-- Use 'lock_dn'      for dn
-                               'lock_name'    for name
-                               'lock_type'    for branch/freeze -->
-{if $cv.enableFAI_management}
-                       <plugin acl="fai" class="faiManagement" icon="fai.png" 
-                               path="plugins/admin/fai" />
-{else}
-<!--
-                       <plugin acl="FAIclass" class="faiManagement" icon="fai.png" 
-                               path="plugins/admin/fai" />
--->
-{/if}
-                       <plugin acl="gofaxlist" class="blocklist" icon="blocklists.png"
-                               path="plugins/gofax/blocklists" />
-                       <plugin acl="gofonmacro" class="goFonMacro" icon="macros.png"
-                               path="plugins/gofon/macro" />
-                       <plugin acl="gofonconference" class="phoneConferenceManagment" icon="conference.png"
-                               path="plugins/gofon/conference" />
-                       <plugin acl="acl" class="acl" icon="acl.png"
-                               path="plugins/admin/acl" />
-               </section>
-
-               <section name="Addons">
-                       <plugin acl="addressbook" class="addressbook" icon="addressbook.png"
-                               path="plugins/addons/addressbook" />
-                       <plugin acl="faxreport" class="faxreport" icon="reports.png"
-                               path="plugins/gofax/faxreports" />
-                       <plugin acl="fonreport" class="fonreport" icon="phonereport.png"
-                               path="plugins/gofon/fonreports" />
-                       <plugin acl="logview" class="logview" icon="logview.png"
-                               path="plugins/addons/logview" />
-                       <plugin acl="mailqueue" class="mailqueue" icon="mailqueue.png"
-                               path="plugins/addons/mailqueue" />
-                       <plugin acl="ldapmanager" class="ldif" icon="ldif.png"
-                               path="plugins/addons/ldapmanager" />
-                       <plugin acl="msgplug" class="msgplug" icon="notifications.png"
-                               path="plugins/addons/notifications" />
-{if $cv.optional.gotomasses_active}
-                       <plugin acl="gotomasses" class="gotomasses" icon="system.png"
-                               storage_file="{$cv.optional.gotomasses_file}"
-                               path="plugins/addons/gotomasses" />
-{else}
-<!--
-                       <plugin acl="gotomasses" class="gotomasses" icon="system.png"
-                               path="plugins/addons/gotomasses" />
--->
-{/if}
-<!--
-                       <plugin acl="all" class="bugsubmitter" icon="bugsubmitter.png"
-                               path="plugins/addons/bugsubmitter" />
--->
-               </section>
-       </menu>
-
-       <aclroletab>
-               <tab class="aclRole" name="ACL Role" />
-       </aclroletab>
-
-       <usertabs>
-               <tab class="user" name="Generic" />
-               <tab class="posixAccount" name="Unix" />
-               <tab class="environment" name="Environment" />
-               <tab class="mailAccount" name="Mail" />
-               <tab class="sambaAccount" name="Samba" />
-{if $cv.use_netatalk}
-               <tab class="netatalk" name="Netatalk" />
-{else}
-<!--
-               <tab class="netatalk" name="Netatalk" />
--->
-{/if}
-               <tab class="connectivity" name="Connectivity" />
-               <tab class="gofaxAccount" name="Fax" />
-               <tab class="phoneAccount" name="Phone" />
-<!--
-               <tab class="scalixAccount" name="Scalix" />
--->
-<!--            
-               <tab class="nagiosAccount" name="Nagios" /> 
--->
-       </usertabs>
-
-       <faxblocktabs>
-               <tab class="blocklistGeneric" name="Generic" />
-       </faxblocktabs>
-
-       <mimetabs>
-               <tab class="mimetype" name="Generic" />
-       </mimetabs>
-
-       <devicetabs>
-               <tab class="deviceGeneric" name="Generic" />
-       </devicetabs>
-
-
-       <grouptabs>
-               <tab class="group" name="Generic" />
-               <tab class="environment" name="Environment" />
-               <tab class="appgroup" name="Applications" />
-               <tab class="mailgroup" name="Mail" />
-       </grouptabs>
-
-       <appstabs>
-               <tab class="application" name="Generic" />
-               <tab class="applicationParameters" name="Options" />
-       </appstabs>
-
-       <conferencetabs>
-               <tab class="conference" name="Generic" />
-       </conferencetabs>
-
-       <macrotabs>
-               <tab class="macro" name="Generic" />
-               <tab class="macroParameter" name="Parameter" />
-       </macrotabs>
-
-       <termtabs>
-               <tab class="termgeneric" name="Generic" />
-               <tab class="termstartup" name="Startup" />
-               <tab class="termservice" name="Devices" />
-               <tab class="printgeneric" name="Printer" />
-               <tab class="terminfo" name="Information" 
-                       snmpcommunity="{$cv.optional.snmpcommunity}" />
-               <tab class="glpiAccount" name="Inventory" />
-       </termtabs>
-
-       <servtabs>
-               <tab class="servgeneric" name="Generic" />
-               <tab class="workstartup" name="Startup" />
-               <tab class="ServerService" name="Services" />
-{if $cv.enableFAI_management}
-           <tab class="faiSummaryTab" name="FAI summary" />
-{else}
-<!--    <tab class="faiSummaryTab" name="FAI summary" /> -->
-{/if}
-               <tab class="terminfo" name="Information" 
-                       snmpcommunity="{$cv.optional.snmpcommunity}" />
-               <tab class="glpiAccount" name="Inventory" />
-       </servtabs>
-
-       <worktabs>
-               <tab class="workgeneric" name="Generic" />
-               <tab class="workstartup" name="Startup" />
-               <tab class="workservice" name="Devices" />
-               <tab class="printgeneric" name="Printer" />
-               <tab class="terminfo" name="Information" 
-                       snmpcommunity="{$cv.optional.snmpcommunity}" />
-{if $cv.enableFAI_management}
-           <tab class="faiSummaryTab" name="FAI summary" />
-{else}
-<!--    <tab class="faiSummaryTab" name="FAI summary" /> -->
-{/if}
-               <tab class="glpiAccount" name="Inventory" />
-       </worktabs>
-
-       <printtabs>
-               <tab class="printgeneric" name="Generic" />
-               <tab class="glpiPrinterAccount" name="Inventory" />
-       </printtabs>
-
-       <phonetabs>
-               <tab class="phoneGeneric" name="Generic" />
-               <tab class="glpiAccount" name="Inventory" />
-       </phonetabs>
-
-       <componenttabs>
-               <tab class="componentGeneric" name="Generic" />
-               <tab class="glpiAccount" name="Inventory" />
-       </componenttabs>
-
-       <wintabs>
-               <tab class="wingeneric" name="Generic" />
-               <tab class="glpiAccount" name="Inventory" />
-       </wintabs>
-
-       <serverservice>
-               <tab class="goMailServer" />
-{if $cv.mail == "kolab"}
-               <tab class="servkolab" />
-{/if}
-               <tab class="goNtpServer" />
-               <tab class="servrepository" />
-               <tab class="goImapServer" />
-               <tab class="goKrbServer" />
-               <tab class="goFaxServer" />
-               <tab class="goFonServer" />
-               <tab class="goLogDBServer" />
-               <tab class="goGlpiServer" />
-               <tab class="goCupsServer" />
-               <tab class="goKioskService" />
-               <tab class="goSyslogServer" />
-               <tab class="goTerminalServer" />
-               <tab class="goLdapServer" />
-               <tab class="goShareServer" />
-{if $cv.generic_settings.enableDHCP}
-               <tab class="servdhcp" />
-{/if}
-{if $cv.generic_settings.enableDNS}
-               <tab class="servdns" />
-{/if}
-               <tab class="gosaLogServer" />
-       </serverservice>
-
-       <deptabs>
-               <tab class="department" name="Generic" />
-       </deptabs>
-
-       <ogrouptabs>
-               <tab class="ogroup" name="Generic" />
-       </ogrouptabs>
-
-       <connectivity>
-{if $cv.mail == "kolab"}
-               <tab class='kolabAccount' /> 
-{/if}
-               <tab class="proxyAccount" />
-               <tab class="pureftpdAccount" />
-               <tab class="webdavAccount" />
-               <tab class="phpgwAccount" />
-               <tab class="intranetAccount" />
-               <tab class="opengwAccount"
-                       username="OGo"
-                       password=""
-                       database="OGo"
-                       datahost="localhost" />
-<!--   
-               <tab class="pptpAccount" /> 
-               <tab class="phpscheduleitAccount" /> 
--->
-       </connectivity>
-
-       <ldiftab>
-               <tab class="ldifexport" name="Export" />
-               <tab class="xlsexport" name="Excel Export" />
-               <tab class="ldifimport" name="Import" />
-               <tab class="csvimport" name="CSV Import" />
-       </ldiftab>
-
-{if $cv.enableFAI_management}
-       <faipartitiontabs>
-               <tab class="faiPartitionTable" name="Partitions" />
-       </faipartitiontabs>
-
-       <faiscripttabs>
-               <tab class="faiScript" name="Script" />
-       </faiscripttabs>
-
-       <faihooktabs>
-               <tab class="faiHook" name="Hooks" />
-       </faihooktabs>
-
-       <faivariabletabs>
-               <tab class="faiVariable" name="Variables" />
-       </faivariabletabs>
-
-       <faitemplatetabs>
-               <tab class="faiTemplate" name="Templates" />
-       </faitemplatetabs>
-
-       <faiprofiletabs>
-               <tab class="faiProfile" name="Profiles" />
-               <tab class="faiSummaryTab" name="Summary" />
-       </faiprofiletabs>
-
-       <faipackagetabs>
-               <tab class="faiPackage" name="Packages" />
-       </faipackagetabs>
-{else}
-<!-- 
-       <faipartitiontabs>
-               <tab class="faiPartitionTable" name="Partitions" />
-       </faipartitiontabs>
-
-       <faiscripttabs>
-               <tab class="faiScript" name="Script" />
-       </faiscripttabs>
-
-       <faihooktabs>
-               <tab class="faiHook" name="Hooks" />
-       </faihooktabs>
-
-       <faivariabletabs>
-               <tab class="faiVariable" name="Variables" />
-       </faivariabletabs>
-
-       <faitemplatetabs>
-               <tab class="faiTemplate" name="Templates" />
-       </faitemplatetabs>
-
-       <faiprofiletabs>
-               <tab class="faiProfile" name="Profiles" />
-               <tab class="faiSummaryTab" name="Summary" />
-       </faiprofiletabs>
-
-       <faipackagetabs>
-               <tab class="faiPackage" name="Packages" />
-       </faipackagetabs>
--->
-{/if}
-
-       <logtabs>
-                       <tab class="logview" name="System logs" />
-                       <tab class="gosa_logview" name="GOsa logs" />
-       </logtabs>
-       
-       <main default="{$cv.location}"
-{if $cv.optional.list_summary}
-               list_summary="true"
-{else}
-               list_summary="false"
-{/if}
-{if $cv.pwd_rules.pwminlen_active}
-               pwminlen="{$cv.pwd_rules.pwminlen}"
-{/if}
-{if $cv.pwd_rules.pwdiffer_active}
-               pwdiffer="{$cv.pwd_rules.pwdiffer}"
-{/if}
-{if $cv.pwd_rules.externalpwdhook_active}
-               externalpwdhook="{$cv.pwd_rules.externalpwdhook}"
-{/if}
-{if $cv.errorlvl}
-               displayerrors="true"
-{else}
-               displayerrors="false"
-{/if}
-{if $cv.enable_schema_check}
-               schema_check="true"
-{else}
-               schema_check="false"
-{/if}
-{if $cv.generic_settings.enableCopyPaste}
-               enableCopyPaste="true"
-{else}
-               enableCopyPaste="false"
-{/if}
-{if $cv.optional.forceglobals}
-               forceglobals="true"
-{else}
-               forceglobals="false"
-{/if}
-{if $cv.optional.forcessl}
-               forcessl="true"
-{else}
-               forcessl="false"
-{/if}
-{if $cv.optional.ldapstats}
-               ldapstats="true"
-{else}
-               ldapstats="false"
-{/if}
-{if $cv.optional.warnssl}
-               warnssl="true"
-{else}
-               warnssl="false"
-{/if}
-{if $cv.optional.ppd_path_active}
-               ppd_path="{$cv.optional.ppd_path}"
-{/if}
-{if $cv.optional.max_ldap_query_time_active}   
-               max_ldap_query_time="{$cv.optional.max_ldap_query_time}"
-{/if}
-{if $cv.optional.noprimarygroup}
-               noprimarygroup="true"
-{/if}
-{if $cv.optional.mailQueueScriptPath_active}
-               mailQueueScriptPath="{$cv.optional.mailQueueScriptPath}"
-{/if}
-{if $cv.optional.auto_network_hook_active}
-               auto_network_hook="{$cv.optional.auto_network_hook} "
-{/if}
-{if $cv.optional.user_filter_cookie}
-               save_filter="true"
-{else}
-               save_filter="false"
-{/if}
-{if $cv.compressed}
-               compressed="true"
-{else}
-               compressed="false"
-{/if}
-{if $cv.optional.uniq_identifier_active }
-               uniq_identifier="{$cv.optional.uniq_identifier}"
-{else}
-               uniq_identifier=""
-{/if}
-               lang="{$cv.lang_selected}"
-               theme="{$cv.theme}"
-               session_lifetime="{$cv.optional.session_lifetime}"
-               compile="{$cv.optional.compile}"
-               debuglevel="{$cv.optional.debuglevel}"
-               smbhash='{$cv.samba_settings.smbhash}'
-               >
-
-               <location name="{$cv.location}"
-                       hash="{$cv.encryption}"
-                       dnmode="{$cv.peopledn}"
-                       server="{$cv.connection}"
-                       people="{$cv.peopleou}"
-                       groups="{$cv.groupou}"
-                       gidbase="{$cv.uidbase}"
-                       uidbase="{$cv.uidbase}"
-{if $cv.optional.login_attribute}
-                       login_attribute="{$cv.optional.login_attribute}"
-{else}
-                       login_attribute="uid"
-{/if}
-{if $cv.timezone}
-                       timezone="{$cv.timezone}"
-{/if}
-{if $cv.optional.strict_units}
-                       strict_units="true"
-{else}
-                       strict_units="false"
-{/if}
-{if $cv.krbsasl}
-                       krbsasl="true"
-{else}
-                       krbsasl="false"
-{/if}
-{if $cv.rfc2307bis}
-                       rfc2307bis="true"
-{else}
-                       rfc2307bis="false"
-{/if}
-{if $cv.include_personal_title}
-                       include_personal_title="true"
-{else}
-                       include_personal_title="false"
-{/if}
-{if $cv.optional.notifydir_active }
-                       notifydir="{$cv.optional.notifydir}"
-{/if}
-{if $cv.base_hook_active}
-                       base_hook="{$cv.base_hook}"
-{/if}
-{if $cv.generic_settings.wws_ou_active}
-                       winstations="{$cv.generic_settings.wws_ou}"
-{/if}
-{if $cv.id_settings.idgen_active}
-                       idgen="{$cv.id_settings.idgen}"
-{/if}
-{if $cv.strict}
-                       strict="yes"
-{else}
-                       strict="no"
-{/if}
-{if $cv.id_settings.minid_active}
-                       minid="{$cv.id_settings.minid}"
-{/if}
-{if $cv.mail != "disabled"}
-                       mailMethod="{$cv.mail}"
-{if $cv.cyrusunixstyle}
-                       cyrusunixstyle="true"
-{else}
-                       cyrusunixstyle="false"
-{/if}
-{if $cv.mail_settings.vacationdir_active}
-                       vacationdir="{$cv.mail_settings.vacationdir}"
-{/if}
-{/if}
-{if $cv.tls}
-                       tls="true"
-{/if}
-{if $cv.governmentmode}
-                       governmentmode="true"
-{else}
-                       governmentmode="false"
-{/if}
-{if $cv.sambaidmapping}
-                       sambaidmapping="true"
-{/if}
-{if $cv.account_expiration}
-                       account_expiration="true"
-{/if}
-{if $cv.samba_settings.samba_sid_active}
-                       SID="{$cv.samba_settings.samba_sid}"
-{/if}
-{if $cv.samba_settings.samba_rid_active}
-                       RIDBASE="{$cv.samba_settings.samba_rid_active}"
-{/if}
-{if $cv.generic_settings.snapshot_active}      
-                       enable_snapshot="true"
-{if $cv.generic_settings.snapshot_base != ""}
-                       snapshot_base="{$cv.generic_settings.snapshot_base}"
-{/if}
-{if $cv.generic_settings.snapshot_user != ""}
-                       snapshot_user="{$cv.generic_settings.snapshot_user}"
-{/if}
-{if $cv.generic_settings.snapshot_password != ""}
-                       snapshot_password="{$cv.generic_settings.snapshot_password}"
-{/if}
-{if $cv.generic_settings.snapshot_server != ""}
-                       snapshot_server="{$cv.generic_settings.snapshot_server}"
-{/if}
-{/if}
-{if $cv.samba_version != 0}
-                       sambaversion="{$cv.samba_version}"
-{/if}
-                       config="ou=gosa,ou=configs,ou=systems,{$cv.base}">
-
-                       <referral url="{$cv.connection}/{$cv.base}"
-                               admin="{$cv.admin}"
-                               password="{$cv.password}" />
-               </location>
-       </main>
-</conf>
diff --git a/contrib/gosa.spec b/contrib/gosa.spec
deleted file mode 100644 (file)
index a737bfa..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-# Some sort of "detection" of suse
-%{?suse_version:%define suse 1}
-%{!?suse_version:%define suse 0}
-
-# Define Packagename, e.g.:
-# rpmbuild --rebuild --define 'sourcename gosa' gosa.srpm
-%{!?sourcename:%define sourcename %{name}-%{version}}
-
-#
-# Distribution
-#
-Summary:               Web Based LDAP Administration Program 
-Name:                  gosa
-Version:               2.5.99cvs
-Release:               1
-License:               GPL
-Source:                ftp://oss.GONICUS.de/pub/gosa/%{sourcename}.tar.bz2
-URL:                   http://oss.GONICUS.de/project/?group_id=6
-Group:                         System/Administration
-Vendor:                        GONICUS GmbH
-Packager:              Lars Scheiter <lars.scheiter@GONICUS.de>
-Buildarch:             noarch
-%if %{suse}
-Requires:              apache2,apache2-mod_php5,php5,php5-gd,php5-ldap,php5-mcrypt,php5-mysql,php5-imap,php5-iconv,php5-mbstring,php5-gettext,php5-session,ImageMagick
-%else
-Requires:              httpd,php,php-ldap,php-imap,php-snmp,php-mysql,php-mbstring,ImageMagick
-%endif
-BuildRoot:             %{_tmppath}/%{name}-%{version}-root
-BuildArch:             noarch
-
-%define confdir        /etc/%{name}
-
-%if %{suse}
-       %{echo:Building SuSE rpm}
-       %define apacheuser wwwrun
-       %define apachegroup root
-       %define webconf /etc/apache2/conf.d/
-       %define docdir /usr/share/doc/packages/gosa
-%else
-       %{echo:Building other rpm}
-       %define apacheuser apache 
-       %define apachegroup apache 
-       %define webconf /etc/httpd/conf.d/      
-       %define docdir /usr/share/doc/gosa-%{version}
-%endif
-
-%description
-GOsa is a combination of system-administrator and end-user web
-interface, designed to handle LDAP based setups.
-Provided is access to posix, shadow, samba, proxy, fax, and kerberos
-accounts. It is able to manage the postfix/cyrus server combination
-and can write user adapted sieve scripts.
-
-%package schema
-Group:                         System/Administration
-Summary:               Schema Definitions for the GOSA package
-%if %{suse}
-Requires:              openldap2 >= 2.1.22
-%else
-Requires:              openldap-servers >= 2.2.0
-%endif
-Obsoletes:             gosa-ldap
-
-%description schema
-Contains the Schema definition files for the GOSA admin package.
-
-%package mkntpasswd
-Group:                         System/Administration
-Summary:               Schema Definitions for the GOSA package
-%if %{suse}
-Requires:              perl-Crypt-SmbHash
-%else
-Requires:              perl-Crypt-SmbHash >= 0.02
-%endif
-
-%description mkntpasswd
-Wrapper Script around perl to create Samba Hashes on the fly, added for completeness only.
-If in doubt use sambas "native" mkntpwd tool to generate hashes for GOsa.
-
-%package help-en
-Group:                         System/Administration
-Summary:               English online manual for GOSA package
-Requires:              gosa >= %{version}
-
-%description help-en
-English online manual page for GOSA package
-
-%package help-de
-Group:                         System/Administration
-Summary:               German localized online manual for GOSA package
-Requires:              gosa >= %{version}
-
-%description help-de
-German localized online manual page for GOSA package
-
-%package help-fr
-Group:                         System/Administration
-Summary:               French localized online manual for GOSA package
-Requires:              gosa >= %{version}
-
-%description help-fr
-French localized online manual page for GOSA package
-
-%package help-nl
-Group:                         System/Administration
-Summary:               Dutch localized online manual for GOSA package
-Requires:              gosa >= %{version}
-
-%description help-nl
-Dutch localized online manual page for GOSA package
-
-%prep
-%setup -q -n %{sourcename}
-find . -depth -name CVS -type d | xargs rm -rf
-
-%build
-
-
-%install
-# Create buildroot
-mkdir -p %{buildroot}/usr/share/gosa
-
-# Copy
-DIRS="doc ihtml plugins html include locale setup"
-for i in $DIRS; do \
-  cp -ua $i %{buildroot}/usr/share/gosa/$i ; \
-done
-mkdir %{buildroot}/usr/bin
-cp bin/mkntpasswd %{buildroot}/usr/bin/
-
-# Create files for temporary stuff
-for i in compile config cache; do \
-  mkdir -p %{buildroot}/var/spool/gosa/$i ; \
-done
-
-# Cleanup manual dirs
-for i in admin devel; do \
-  rm -rf %{buildroot}/usr/share/gosa/doc/guide/$i ; \
-done
-
-# Remove (some) unneeded files
-for i in gen_locale.sh gen_online_help.sh gen_function_list.php update.sh; do \
- rm -rf %{buildroot}/usr/share/gosa/$i ; \
-done
-
-# Cleanup lyx warnings
-find %{buildroot}/usr/share/gosa -name WARNINGS |xargs rm
-
-
-# Cleanup guide
-rm -rf %{buildroot}/usr/share/gosa/doc/guide/user/*/lyx-source
-
-
-# Copy default config
-mkdir -p %{buildroot}%{confdir}
-mkdir -p %{buildroot}%{webconf}
-
-cat > %{buildroot}%{webconf}/gosa_include.conf <<EOF
-# Just to be sure
-<Directory "/usr/share/gosa/html">
-       Options None
-       AllowOverride None
-       Order allow,deny
-       Allow from all
-</Directory>
-# Set alias to gosa
-Alias /gosa /usr/share/gosa/html
-EOF
-
-mkdir -p %{buildroot}/etc/openldap/schema/gosa
-mv contrib/openldap/*.schema %{buildroot}/etc/openldap/schema/gosa
-sed 's%"CONFIG_TEMPLATE_DIR", "../contrib/"%"CONFIG_TEMPLATE_DIR", "%{docdir}/"%g' %{buildroot}/usr/share/gosa/include/functions.inc > %{buildroot}/usr/share/gosa/include/functions.inc.new
-mv -f %{buildroot}/usr/share/gosa/include/functions.inc.new %{buildroot}/usr/share/gosa/include/functions.inc
-
-mv -f doc manual
-mkdir -p %{buildroot}/etc/gosa/vacation
-mv -f %{buildroot}/usr/share/gosa/plugins/personal/mail/sieve-*.txt %{buildroot}/etc/gosa
-mkdir -p %{buildroot}/usr/share/doc/gosa-%{version}
-rm -rf %{buildroot}/usr/share/gosa/contrib
-#rm -rf %{buildroot}/usr/share/gosa/doc
-#rmdir contrib/openldap
-bzip2 -9 contrib/opensides/goSamba.pl
-
-%clean
-rm -rf %{buildroot}
-
-%post
-# Add shells file to /etc/gosa 
-/bin/cp /etc/shells /etc/gosa
-
-%pre
-# Cleanup compile dir on updates, always exit cleanly even on errors
-[ -d /var/spool/gosa ] && rm -rf /var/spool/gosa/* ; exit 0
-
-%postun
-# Remove temporary files, just to be sure
-[ -d /var/spool/gosa ] && rm -rf /var/spool/gosa/* ; exit 0
-
-%files
-%defattr(-,%{apacheuser},%{apachegroup})
-%doc %attr(-,root,root) AUTHORS TODO README README.safemode Changelog COPYING INSTALL FAQ
-%doc %attr(-,root,root) contrib/altlinux contrib/fix_config.sh contrib/gosa.conf contrib/mysql contrib/opensides
-%doc %attr(-,root,root) contrib/patches contrib/scripts contrib/vacation_example.txt contrib/demo.ldif contrib/openldap
-
-%config(noreplace) %attr(0600,%{apacheuser},%{apachegroup}) %{webconf}/gosa_include.conf
-%config(noreplace) %attr(0700,%{apacheuser},%{apachegroup}) /etc/gosa
-%attr(0700, %{apacheuser}, %{apachegroup}) /var/spool/gosa
-%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/html
-%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/ihtml
-%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/include
-%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/locale
-%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/setup
-%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/plugins
-%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/doc/guide.xml
-
-%files schema
-%defattr(-,root,root)
-%doc COPYING AUTHORS README contrib/demo.ldif contrib/openldap
-/etc/openldap/schema/gosa
-
-%files mkntpasswd
-%defattr(-,root,root)
-/usr/bin/mkntpasswd
-
-%files help-en
-%defattr(-,root,root)
-/usr/share/gosa/doc/guide/user/en
-
-%files help-de
-%defattr(-,root,root)
-/usr/share/gosa/doc/guide/user/de
-
-%files help-fr
-%defattr(-,root,root)
-/usr/share/gosa/doc/guide/user/fr
-
-%files help-nl
-%defattr(-,root,root)
-/usr/share/gosa/doc/guide/user/nl
-
-%changelog
-* Mon May 7 2007 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.99cvs
-- Changed packageversion to reflect CVS status of resulting build
-
-* Wed Apr 11 2007 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.10
-- New upstream
-- Added new subpackage mkntpasswd
-- Remove perl dependencies off of GOsa main package
-
-* Tue Mar 6 2007 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.9
-- New upstream
-- fixed typo in updateprocess
-
-* Mon Jan 15 2007 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.8
-- New upstream release with security fixes
-
-* Wed Dec 20 2006 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.7
-- New upstream
-- %pre and %postun always end successfully now, even on errors
-
-* Fri Nov 17 2006 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.6
-- New upstream
-- Cleanup temporary dir after package removal
-- Cleanup temporary dir before update
-
-* Thu Sep 28 2006 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.4
-- New upstream version
-- Downgraded SuSE dependencies to php4
-
-* Wed Jun 21 2006 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.1
-- New upstream version
-
-* Tue May 30 2006 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5
-- Updated RedHat dependencies
-- New upstream version
-- Spelling errors fixed ;)
-- Seperation of online manual
-
-* Mon Dec 19 2005 Lars Scheiter <lars.scheiter@GONICUS.de> 2.4-2
-- Updated SuSE dependencies to php5
-
-* Mon Nov 21 2005 Lars Scheiter <lars.scheiter@GONICUS.de> 2.4
-- New upstream version
-- Removed %doc for postgresql and openexchange
-
-* Wed Jun 01 2005 Lars Scheiter <lars.scheiter@GONICUS.de> 2.4beta1
-- New upstream version
-- Added gosa.conf to contrib dir
-- Rearranged documentation stuff
-- Updated dependencies
-- compress some files
-
-* Mon Feb 21 2005 Lars Scheiter <lars.scheiter@GONICUS.de> 2.3
-- Update version to 2.3 (upstream)
-
-* Mon Dec 13 2004 Lars Scheiter <lars.scheiter@GONICUS.de> 2.2-2
-- Optionally allow different sourcenames
-
-* Mon Nov 22 2004 Lars Scheiter <lars.scheiter@GONICUS.de> 2.2
-- Update to 2.2 (upstream)
-- reintroduction of suse detection
-- small fixes
-- Corrected URL
-- Synchronize schema package name with debian
-
-* Mon May 19 2004 Levente Farkas <lfarkas@lfarkas.org> 2.1.1
-- update to 2.1.1
-
-* Mon Apr 19 2004 Levente Farkas <lfarkas@lfarkas.org> 2.1
-- update to 2.1
-
-* Fri Apr 16 2004 Levente Farkas <lfarkas@lfarkas.org> 2.1
-- minor fixes
-- update to 2.1rc2
-
-* Tue Jan 24 2004 Henning P. Schmiedehausen <hps@intermeta.de> 2.1-2t
-- bumped to 2.1beta2
-- first INTERMETA internal build
-
-* Mon Oct 20 2003 Lars Scheiter <lars.scheiter@GONICUS.de>
-- Update to new upstream release (2.0rc1)
-
-* Fri Oct 17 2003 Lars Scheiter <lars.scheiter@GONICUS.de>
-- First build of GOsa as an RPM, should work on SuSE and RedHat
diff --git a/contrib/keyboardLayouts b/contrib/keyboardLayouts
deleted file mode 100644 (file)
index ca28248..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# Left side will be saved in ldap attribute
-# Right side will be displayed in the selectbox
-# (Terminal Workstation -> Services -> Keyboard )
-a:1
-b:2
-c:3
-d:4
diff --git a/contrib/latex2html b/contrib/latex2html
deleted file mode 100755 (executable)
index 5b4e3f7..0000000
+++ /dev/null
@@ -1,17413 +0,0 @@
-#! /usr/bin/perl
-#
-# $Id: latex2html.pin,v 1.71 2004/01/06 23:49:54 RRM Exp $
-#
-# Comprises patches and revisions by various authors:
-#   See Changes, the log file of LaTeX2HTML.
-#
-# Original Copyright notice:
-#
-# LaTeX2HTML by Nikos Drakos <nikos@cbl.leeds.ac.uk>
-
-# ****************************************************************
-# LaTeX To HTML Translation **************************************
-# ****************************************************************
-# LaTeX2HTML is a Perl program that translates LaTeX source
-# files into HTML (HyperText Markup Language). For each source
-# file given as an argument the translator will create a
-# directory containing the corresponding HTML files.
-#
-# The man page for this program is included at the end of this file
-# and can be viewed using "perldoc latex2html"
-#
-# For more information on this program and some examples of its
-# capabilities visit 
-#
-#          http://www.latex2html.org/
-#
-# or see the accompanying documentation in the docs/  directory
-#
-# or
-#
-#    http://www-texdev.ics.mq.edu.au/l2h/docs/manual/
-#
-# or
-#
-#    http://www.cbl.leeds.ac.uk/nikos/tex2html/doc/latex2html/
-#
-# Original code written by Nikos Drakos, July 1993.
-#
-# Address: Computer Based Learning Unit
-#          University of Leeds
-#          Leeds,  LS2 9JT
-#
-# Copyright (c) 1993-95. All rights reserved.
-#
-#
-# Extensively modified by Ross Moore, Herb Swan and others
-#
-# Address: Mathematics Department
-#          Macquarie University
-#          Sydney, Australia, 2109 
-#
-# Copyright (c) 1996-2001. All rights reserved.
-#
-# See general license in the LICENSE file.
-#
-##########################################################################
-
-use 5.003; # refuse to work with old and buggy perl version
-#use strict;
-#use diagnostics;
-
-# include some perl packages; these come with the standard distribution
-use Getopt::Long;
-use Fcntl;
-use AnyDBM_File;
-
-# The following are global variables that also appear in some modules
-use vars qw($LATEX2HTMLDIR $LATEX2HTMLPLATDIR $SCRIPT
-            %Month %used_icons $inside_tabbing $TABLE_attribs
-            %mathentities $date_name $outer_math $TABLE__CELLPADDING_rx);
-
-BEGIN {
-  # print "scanning for l2hdir\n";
-  if($ENV{'LATEX2HTMLDIR'}) {
-    $LATEX2HTMLDIR = $ENV{'LATEX2HTMLDIR'};
-  } else {
-    $ENV{'LATEX2HTMLDIR'} = $LATEX2HTMLDIR = '/usr/share/latex2html';
-  }
-
-  if($ENV{'LATEX2HTMLPLATDIR'}) {
-    $LATEX2HTMLPLATDIR = $ENV{'LATEX2HTMLPLATDIR'};
-  } else {
-    $LATEX2HTMLPLATDIR = '/usr/share/latex2html'||$LATEX2HTMLDIR;
-    $ENV{'LATEX2HTMLPLATDIR'} = $LATEX2HTMLPLATDIR;
-  }
-  if(-d $LATEX2HTMLPLATDIR) {
-    push(@INC,$LATEX2HTMLPLATDIR);
-  }
-
-  if(-d $LATEX2HTMLDIR) {
-    push(@INC,$LATEX2HTMLDIR);
-  } else {
-    die qq{Fatal: Directory "$LATEX2HTMLDIR" does not exist.\n};
-  }
-}
-
-use L2hos; # Operating system dependent routines
-
-# $^W = 1; # turn on warnings
-
-my $RELEASE = '2002-2-1';
-my ($REVISION) = q$Revision: 1.71 $ =~ /:\s*(\S+)/;
-
-# The key, which delimts expressions defined in the environment
-# depends on the operating system. 
-$envkey = L2hos->pathd();
-
-# $dd is the directory delimiter character
-$dd = L2hos->dd();
-
-# make sure the $LATEX2HTMLDIR is on the search-path for forked processes
-if($ENV{'PERL5LIB'}) {
-  $ENV{'PERL5LIB'} .= "$envkey$LATEX2HTMLDIR"
-    unless($ENV{'PERL5LIB'} =~ m|\Q$LATEX2HTMLDIR\E|o);
-} else {
-  $ENV{'PERL5LIB'} = $LATEX2HTMLDIR;
-}
-
-# Local configuration, read at runtime
-# Read the $CONFIG_FILE  (usually l2hconf.pm )
-if($ENV{'L2HCONFIG'}) {
-  require $ENV{'L2HCONFIG'} ||
-    die "Fatal (require $ENV{'L2HCONFIG'}): $!";
-} else {
-  eval 'use l2hconf';
-  if($@) {
-    die "Fatal (use l2hconf): $@\n";
-  }
-}
-
-# MRO: Changed this to global value in config/config.pl
-# change these whenever you do a patch to this program and then
-# name the resulting patch file accordingly
-# $TVERSION = "2002-2-1";
-#$TPATCHLEVEL = " beta";
-#$TPATCHLEVEL = " release";
-#$RELDATE = "(March 30, 1999)";
-#$TEX2HTMLV_SHORT = $TVERSION . $TPATCHLEVEL;
-
-$TEX2HTMLV_SHORT = $RELEASE;
-$TEX2HTMLVERSION = "$TEX2HTMLV_SHORT ($REVISION)";
-$TEX2HTMLADDRESS = "http://www.latex2html.org/";
-$AUTHORADDRESS = "http://cbl.leeds.ac.uk/nikos/personal.html";
-#$AUTHORADDRESS2 = "http://www-math.mpce.mq.edu.au/%7Eross/";
-$AUTHORADDRESS2 = "http://www.maths.mq.edu.au/&#126;ross/";
-
-# Set $HOME to what the system considers the home directory
-$HOME = L2hos->home();
-push(@INC,$HOME);
-
-# flush stdout with every print -- gives better feedback during
-# long computations
-$| = 1;
-
-# set Perl's subscript separator to LaTeX's illegal character.
-# (quite defensive but why not)
-$; = "\000";
-
-# No arguments!!
-unless(@ARGV) {
-  die "Error: No files to process!\n";
-}
-
-# Image prefix
-$IMAGE_PREFIX = '_image';
-
-# Partition prefix 
-$PARTITION_PREFIX = 'part_' unless $PARTITION_PREFIX;
-
-# Author address
-@address_data = &address_data('ISO');
-$ADDRESS = "$address_data[0]\n$address_data[1]";
-
-# ensure non-zero defaults
-$MAX_SPLIT_DEPTH = 4 unless ($MAX_SPLIT_DEPTH);
-$MAX_LINK_DEPTH = 4 unless ($MAX_LINK_DEPTH);
-$TOC_DEPTH = 4 unless ($TOC_DEPTH);
-
-# A global value may already be set in the $CONFIG_FILE
-$INIT_FILE_NAME = $ENV{'L2HINIT_NAME'} || '.latex2html-init'
-   unless $INIT_FILE_NAME;
-
-# Read the $HOME/$INIT_FILE_NAME if one is found
-if (-f "$HOME$dd$INIT_FILE_NAME" && -r _) {
-    print "Note: Loading $HOME$dd$INIT_FILE_NAME\n";
-    require("$HOME$dd$INIT_FILE_NAME");
-    $INIT_FILE = "$HOME$dd$INIT_FILE_NAME";
-    # _MRO_TODO_: Introduce a version to be checked?
-    die "Error: You have an out-of-date " . $HOME .
-       "$dd$INIT_FILE_NAME file.\nPlease update or delete it.\n"
-       if ($DESTDIR eq '.');
-}
-
-# Read the $INIT_FILE_NAME file if one is found in current directory
-if ( L2hos->Cwd() ne $HOME && -f ".$dd$INIT_FILE_NAME" && -r _) {
-    print "Note: Loading .$dd$INIT_FILE_NAME\n";
-    require(".$dd$INIT_FILE_NAME");
-    $INIT_FILE = "$INIT_FILE_NAME";
-}
-die "Error: '.' is an incorrect setting for DESTDIR.\n" .
-    "Please check your $INIT_FILE_NAME file.\n"
-    if ($DESTDIR eq '.');
-
-# User home substitutions
-$LATEX2HTMLSTYLES =~ s/~([$dd$dd$envkey]|$)/$HOME$1/go;
-# the next line fails utterly on non-UNIX systems
-$LATEX2HTMLSTYLES =~ s/~([^$dd$dd$envkey]+)/L2hos->home($1)/geo;
-
-#absolutise the paths
-$LATEX2HTMLSTYLES = join($envkey,
-                        map(L2hos->Make_directory_absolute($_),
-                                split(/$envkey/o, $LATEX2HTMLSTYLES)));
-
-#HWS:  That was the last reference to HOME.  Now set HOME to $LATEX2HTMLDIR,
-#      to enable dvips to see that version of .dvipsrc!  But only if we
-#      have DVIPS_MODE not set - yes - this is a horrible nasty kludge
-# MRO: The file has to be updated by configure _MRO_TODO_
-
-if ($PK_GENERATION && ! $DVIPS_MODE) {
-    $ENV{HOME} =  $LATEX2HTMLDIR;
-    delete $ENV{PRINTER}; # Overrides .dvipsrc
-}
-
-# language of the DTD specified in the <DOCTYPE...> tag
-$ISO_LANGUAGE = 'EN' unless $ISO_LANGUAGE;
-
-# Save the command line arguments, quote where necessary
-$argv = join(' ', map {/[\s#*!\$%]/ ? "'$_'" : $_ } @ARGV);
-
-# Pre-process the command line for backward compatibility
-foreach(@ARGV) {
-  s/^--?no_/-no/; # replace e.g. no_fork by nofork
-  # s/^[+](\d+)$/$1/; # remove + in front of integers
-}
-
-# Process command line options
-my %opt;
-unless(GetOptions(\%opt, # all non-linked options go into %opt
-        # option                linkage (optional)
-        'help|h',
-        'version|V',
-        'split=s',
-        'link=s',
-        'toc_depth=i',          \$TOC_DEPTH,
-        'toc_stars!',           \$TOC_STARS,
-        'short_extn!',          \$SHORTEXTN,
-        'iso_language=s',       \$ISO_LANGUAGE,
-        'validate!',            \$HTML_VALIDATE,
-        'latex!',
-        'djgpp!',               \$DJGPP,
-        'fork!',                \$CAN_FORK,
-        'external_images!',     \$EXTERNAL_IMAGES,
-        'ascii_mode!',          \$ASCII_MODE,
-        'lcase_tags!',          \$LOWER_CASE_TAGS,
-        'ps_images!',           \$PS_IMAGES,
-        'font_size=s',          \$FONT_SIZE,
-        'tex_defs!',            \$TEXDEFS,
-        'navigation!',
-        'top_navigation!',      \$TOP_NAVIGATION,
-        'bottom_navigation!',   \$BOTTOM_NAVIGATION,
-        'auto_navigation!',     \$AUTO_NAVIGATION,
-        'index_in_navigation!', \$INDEX_IN_NAVIGATION,
-        'contents_in_navigation!', \$CONTENTS_IN_NAVIGATION,
-        'next_page_in_navigation!', \$NEXT_PAGE_IN_NAVIGATION,
-        'previous_page_in_navigation!', \$PREVIOUS_PAGE_IN_NAVIGATION,
-        'footnode!',
-        'numbered_footnotes!',  \$NUMBERED_FOOTNOTES,
-        'prefix=s',             \$PREFIX,
-        'auto_prefix!',         \$AUTO_PREFIX,
-        'long_titles=i',        \$LONG_TITLES,
-        'custom_titles!',       \$CUSTOM_TITLES,
-        'title|t=s',            \$TITLE,
-        'rooted!',              \$ROOTED,
-        'rootdir=s',
-        'dir=s',                \$FIXEDDIR,
-        'mkdir',                \$MKDIR,
-        'address=s',            \$ADDRESS,
-        'noaddress',
-        'subdir!',
-        'info=s',               \$INFO,
-        'noinfo',
-        'auto_link!',
-        'reuse=i',              \$REUSE,
-        'noreuse',
-        'antialias_text!',      \$ANTI_ALIAS_TEXT,
-        'antialias!',           \$ANTI_ALIAS,
-        'transparent!',         \$TRANSPARENT_FIGURES,
-        'white!',               \$WHITE_BACKGROUND,
-        'discard!',             \$DISCARD_PS,
-        'image_type=s',         \$IMAGE_TYPE,
-        'images!',
-        'accent_images=s',      \$ACCENT_IMAGES,
-        'noaccent_images',
-        'style=s',              \$STYLESHEET,
-        'parbox_images!',
-        'math!',
-        'math_parsing!',
-        'latin!',
-        'entities!',            \$USE_ENTITY_NAMES,
-        'local_icons!',         \$LOCAL_ICONS,
-        'scalable_fonts!',      \$SCALABLE_FONTS,
-        'images_only!',         \$IMAGES_ONLY,
-        'show_section_numbers!',\$SHOW_SECTION_NUMBERS,
-        'show_init!',           \$SHOW_INIT_FILE,
-        'init_file=s',          \$INIT_FILE,
-        'up_url=s',             \$EXTERNAL_UP_LINK,
-        'up_title=s',           \$EXTERNAL_UP_TITLE,
-        'down_url=s',           \$EXTERNAL_DOWN_LINK,
-        'down_title=s',         \$EXTERNAL_DOWN_TITLE,
-        'prev_url=s',           \$EXTERNAL_PREV_LINK,
-        'prev_title=s',         \$EXTERNAL_PREV_TITLE,
-        'index=s',              \$EXTERNAL_INDEX,
-        'biblio=s',             \$EXTERNAL_BIBLIO,
-        'contents=s',           \$EXTERNAL_CONTENTS,
-        'external_file=s',      \$EXTERNAL_FILE,
-        'short_index!',         \$SHORT_INDEX,
-        'unsegment!',           \$UNSEGMENT,
-        'debug!',               \$DEBUG,
-        'tmp=s',                \$TMP,
-        'ldump!',               \$LATEX_DUMP,
-        'timing!',              \$TIMING,
-        'verbosity=i',          \$VERBOSITY,
-        'html_version=s',       \$HTML_VERSION,
-        'strict!',              \$STRICT_HTML,
-        'xbit!',                \$XBIT_HACK,
-        'ssi!',                 \$ALLOW_SSI,
-        'php!',                 \$ALLOW_PHP,
-        'test_mode!' # undocumented switch
-       )) {
-    &usage();
-    exit 1;
-}
-
-# interpret options, check option consistency
-if(defined $opt{'split'}) {
-    if ($opt{'split'} =~ /^(\+?)(\d+)$/) {
-        $MAX_SPLIT_DEPTH = $2;
-        if ($1) { $MAX_SPLIT_DEPTH *= -1; $REL_DEPTH = 1; }
-    } else { 
-        &usage;
-        die "Error: Unrecognised value for -split: $opt{'split'}\n";
-    }
-}
-if(defined $opt{'link'}) {
-    if ($opt{'link'} =~ /^(\+?)(\d+)$/) {
-        $MAX_LINK_DEPTH = $2;
-        if ($1) { $MAX_LINK_DEPTH *= -1 }
-    } else { 
-        &usage;
-        die "Error: Unrecognised value for -link: $opt{'link'}\n";
-    }
-}
-unless ($ISO_LANGUAGE =~ /^[A-Z.]+$/) {
-    die "Error: Language (-iso_language) must be uppercase and dots only: $ISO_LANGUAGE\n";
-}
-if ($HTML_VALIDATE && !$HTML_VALIDATOR) {
-    die "Error: Need a HTML_VALIDATOR when -validate is specified.\n";
-}
-&set_if_false($NOLATEX,$opt{latex}); # negate the option...
-if ($ASCII_MODE || $PS_IMAGES) {
-    $EXTERNAL_IMAGES = 1;
-}
-if ($FONT_SIZE && $FONT_SIZE !~ /^\d+pt$/) {
-    die "Error: Font size (-font_size) must end with 'pt': $FONT_SIZE\n"
-}
-&set_if_false($NO_NAVIGATION,$opt{navigation});
-&set_if_false($NO_FOOTNODE,$opt{footnode});
-if (defined $TITLE && !length($TITLE)) {
-    die "Error: Empty title (-title).\n";
-}
-if ($opt{rootdir}) {
-    $ROOTED = 1;
-    $FIXEDDIR = $opt{rootdir};
-}
-if ($FIXEDDIR && !-d $FIXEDDIR) {
-    if ($MKDIR) {
-       print "\n *** creating directory: $FIXEDDIR ";
-       die "Failed: $!\n" unless (mkdir($FIXEDDIR, 0755));
-        # _TODO_ use File::Path to create a series of directories
-    } else {
-       &usage;
-       die "Error: Specified directory (-rootdir, -dir) does not exist.\n";
-    }
-}
-&set_if_false($NO_SUBDIR, $opt{subdir});
-&set_if_false($NO_AUTO_LINK, $opt{auto_link});
-if ($opt{noreuse}) {
-    $REUSE = 0;
-}
-unless(grep(/^\Q$IMAGE_TYPE\E$/o, @IMAGE_TYPES)) {
-    die <<"EOF";
-Error: No such image type '$IMAGE_TYPE'.
-       This installation supports (first is default): @IMAGE_TYPES
-EOF
-}
-&set_if_false($NO_IMAGES, $opt{images});
-if ($opt{noaccent_images}) {
-    $ACCENT_IMAGES = '';
-}
-if($opt{noaddress}) {
-    $ADDRESS = '';
-}
-if($opt{noinfo}) {
-    $INFO = 0;
-}
-if($ACCENT_IMAGES && $ACCENT_IMAGES !~ /^[a-zA-Z,]+$/) {
-    die "Error: Single word or comma-list of style words needed for -accent_images, not: $_\n";
-}
-&set_if_false($NO_PARBOX_IMAGES, $opt{parbox_images});
-&set_if_false($NO_SIMPLE_MATH, $opt{math});
-if (defined $opt{math_parsing}) {
-    $NO_MATH_PARSING = !$opt{math_parsing};
-    $NO_SIMPLE_MATH = !$opt{math_parsing} unless(defined $opt{math});
-}
-&set_if_false($NO_ISOLATIN, $opt{latin});
-if ($INIT_FILE) {
-    if (-f $INIT_FILE && -r _) {
-        print "Note: Initialising with file: $INIT_FILE\n"
-            if ($DEBUG || $VERBOSITY);
-        require($INIT_FILE);
-    } else {
-        die "Error: Could not find file (-init_file): $INIT_FILE\n";
-    }
-}
-foreach($EXTERNAL_UP_LINK, $EXTERNAL_DOWN_LINK, $EXTERNAL_PREV_LINK,
-        $EXTERNAL_INDEX, $EXTERNAL_BIBLIO, $EXTERNAL_CONTENTS) {
-    $_ ||= ''; # initialize
-    s/~/&#126;/g; # protect `~'
-}
-if($TMP && !(-d $TMP && -w _)) {
-    die "Error: '$TMP' not usable as temporary directory.\n";
-}
-if ($opt{help}) {
-    L2hos->perldoc($SCRIPT);
-    exit 0;
-}
-if ($opt{version}) {
-    &banner();
-    exit 0;
-}
-if ($opt{test_mode}) {
-    return; # make /usr/bin/latex2html non-exploitable
-    $TITLE = 'LaTeX2HTML Test Document';
-    $TEXEXPAND = "$PERL /build/buildd/latex2html-2002-2-1-20050114${dd}texexpand";
-    $PSTOIMG   = "$PERL /build/buildd/latex2html-2002-2-1-20050114${dd}pstoimg";
-    $ICONSERVER = L2hos->path2URL("/build/buildd/latex2html-2002-2-1-20050114${dd}icons");
-    $TEST_MODE  = 1;
-    $RGBCOLORFILE = "/build/buildd/latex2html-2002-2-1-20050114${dd}styles${dd}rgb.txt";
-    $CRAYOLAFILE = "/build/buildd/latex2html-2002-2-1-20050114${dd}styles${dd}crayola.txt";
-}
-if($DEBUG) {
-    # make the OS-dependent functions more chatty, too
-    $L2hos::Verbose = 1;
-}
-
-undef %opt; # not needed any more
-
-
-$FIXEDDIR = $FIXEDDIR || $DESTDIR || '';  # for backward compatibility
-
-if ($EXTERNAL_UP_TITLE xor $EXTERNAL_UP_LINK) {
-    warn "Warning (-up_url, -up_title): Need to specify both a parent URL and a parent title!\n";
-    $EXTERNAL_UP_TITLE = $EXTERNAL_UP_LINK = "";
-}
-
-if ($EXTERNAL_DOWN_TITLE xor $EXTERNAL_DOWN_LINK) {
-    warn "Warning (-down_url, -down_title): Need to specify both a parent URL and a parent title!\n";
-    $EXTERNAL_DOWN_TITLE = $EXTERNAL_DOWN_LINK = "";
-}
-
-# $NO_NAVIGATION = 1 unless $MAX_SPLIT_DEPTH;  #  Martin Wilck
-
-if ($MAX_SPLIT_DEPTH && $MAX_SPLIT_DEPTH < 0) {
-    $MAX_SPLIT_DEPTH *= -1; $REL_DEPTH = 1;
-}
-if ($MAX_LINK_DEPTH && $MAX_LINK_DEPTH < 0) {
-    $MAX_LINK_DEPTH *= -1; $LEAF_LINKS = 1;
-}
-
-$FOOT_FILENAME = 'footnode' unless ($FOOT_FILENAME);
-$NO_FOOTNODE = 1 unless ($MAX_SPLIT_DEPTH || $NO_FOOTNODE);
-$NO_SPLIT = 1 unless $MAX_SPLIT_DEPTH; # _MRO_TODO_: is this needed at all?
-$SEGMENT = $SEGMENTED = 0;
-$NO_MATH_MARKUP = 1;
-
-# specify the filename extension to use with the generated HTML files
-if ($SHORTEXTN) { $EXTN = ".htm"; }    # for HTML files on CDROM
-elsif ($ALLOW_PHP) { $EXTN = ".php"; }  # has PHP dynamic includes
-       # with server-side includes (SSI) :
-elsif ($ALLOW_SSI && !$XBIT_HACK) { $EXTN = ".shtml"; }
-       # ordinary names, valid also for SSI with XBit hack :
-else { $EXTN = ".html"; }
-
-$NODE_NAME = 'node' unless (defined $NODE_NAME);
-
-# space for temporary files
-# different to the $TMPDIR for image-generation
-# MRO: No directory should end with $dd!
-$TMP_ = "TMP";
-
-$TMP_PREFIX = "l2h" unless ($TMP_PREFIX);
-
-# This can be set to 1 when using a version of dvips that is safe
-# from the "dot-in-name" bug.
-# _TODO_ this should be determined by configure
-$DVIPS_SAFE = 1;
-
-$CHARSET = $charset || 'iso-8859-1';
-
-####################################################################
-#
-# If possible, use icons of the same type as generated images
-#
-if ($IMAGE_TYPE && defined %{"icons_$IMAGE_TYPE"}) {
-    %icons = %{"icons_$IMAGE_TYPE"};
-}
-
-####################################################################
-#
-# Figure out what options we need to pass to DVIPS and store that in
-# the $DVIPSOPT variable.  Also, scaling is taken care of at the
-# dvips level if PK_GENERATION is set to 1, so adjust SCALE_FACTORs
-# accordingly.
-#
-if ($SCALABLE_FONTS) {
-    $PK_GENERATION = 0;
-    $DVIPS_MODE = '';
-}
-
-if ($PK_GENERATION) {
-    if ($MATH_SCALE_FACTOR <= 0) { $MATH_SCALE_FACTOR = 2; }
-    if ($FIGURE_SCALE_FACTOR <= 0) { $FIGURE_SCALE_FACTOR = 2; }
-    my $saveMSF = $MATH_SCALE_FACTOR;
-    my $saveFSF = $FIGURE_SCALE_FACTOR;
-    my $desired_dpi = int($MATH_SCALE_FACTOR*75);
-    $FIGURE_SCALE_FACTOR = ($METAFONT_DPI / 72) *
-       ($FIGURE_SCALE_FACTOR / $MATH_SCALE_FACTOR) ;
-    $MATH_SCALE_FACTOR = $METAFONT_DPI / 72;
-    $dvi_mag = int(1000 * $desired_dpi / $METAFONT_DPI);
-    if ($dvi_mag > 1000) {
-       &write_warnings(
-           "WARNING: Your SCALE FACTOR is too large for PK_GENERATION.\n" .
-           "         See $CONFIG_FILE for more information.\n");
-    }
-
-    # RRM: over-sized scaling, using dvi-magnification
-    if ($EXTRA_IMAGE_SCALE) {
-       print "\n *** Images at $EXTRA_IMAGE_SCALE times resolution of displayed size ***\n";
-       $desired_dpi = int($EXTRA_IMAGE_SCALE * $desired_dpi+.5);
-       print "    desired_dpi = $desired_dpi  METAFONT_DPI = $METAFONT_DPI\n"
-            if $DEBUG;
-       $dvi_mag = int(1000 * $desired_dpi / $METAFONT_DPI);
-       $MATH_SCALE_FACTOR = $saveMSF;
-       $FIGURE_SCALE_FACTOR = $saveFSF;
-    }
-    # no space after "-y", "-D", "-e" --- required by DVIPS under DOS !
-    my $mode_switch = "-mode $DVIPS_MODE" if $DVIPS_MODE;
-    $DVIPSOPT .= " -y$dvi_mag -D$METAFONT_DPI $mode_switch -e5 ";
-} else { # no PK_GENERATION
-#    if ($EXTRA_IMAGE_SCALE) {
-#      &write_warnings(
-#         "the \$EXTRA_IMAGE_SCALE feature requires either \$PK_GENERATION=1"
-#                      . " or the '-scalable_fonts' option");
-#      $EXTRA_IMAGE_SCALE = '';
-#    }
-    # MRO: shifted to l2hconf
-    #$DVIPSOPT .= ' -M';
-} # end PK_GENERATION
-
-# The mapping from numbers to accents.
-# These are required to process the \accent command, which is found in
-# tables of contents whenever there is an accented character in a
-# caption or section title.  Processing the \accent command makes
-# $encoded_*_number work properly (see &extract_captions) with
-# captions that contain accented characters.
-# I got the numbers from the plain.tex file, version 3.141.
-
-# Missing entries should be looked up by a native speaker.
-# Have a look at generate_accent_commands and $iso_8859_1_character_map.
-
-# MEH: added more accent types
-# MRO: only uppercase needed!
-%accent_type = (
-   '18' => 'grave',            # \`
-   '19' => 'acute',            # `'
-   '20' => 'caron',            # \v
-   '21' => 'breve',            # \u
-   '22' => 'macr',             # \=
-   '23' => 'ring',             #
-   '24' => 'cedil',            # \c
-   '94' => 'circ',             # \^
-   '95' => 'dot',              # \.
-   '7D' => 'dblac',            # \H
-   '7E' => 'tilde',            # \~
-   '7F' => 'uml',              # \"
-);
-
-&driver;
-
-exit 0; # clean exit, no errors
-
-############################ Subroutines ##################################
-
-#check that $TMP is writable, if so create a subdirectory
-sub make_tmp_dir {
-    &close_dbm_database if $DJGPP; # to save file-handles
-
-    # determine a suitable temporary path
-    #
-    $TMPDIR = '';
-    my @tmp_try = ();
-    push(@tmp_try, $TMP) if($TMP);
-    push(@tmp_try, "$DESTDIR$dd$TMP_") if($TMP_);
-    push(@tmp_try, $DESTDIR) if($DESTDIR);
-    push(@tmp_try, L2hos->Cwd());
-
-    my $try;
-    TempTry: foreach $try (@tmp_try) {
-      next unless(-d $try && -w _);
-      my $tmp = "$try$dd$TMP_PREFIX$$";
-      if(mkdir($tmp,0755)) {
-        $TMPDIR=$tmp;
-       last TempTry;
-      } else {
-        warn "Warning: Cannot create temporary directory '$tmp': $!\n";
-      }
-    }
-
-    $dvips_warning = <<"EOF";
-
-Warning: There is a '.' in \$TMPDIR, $DVIPS will probably fail.
-Set \$TMP to use a /tmp directory, or rename the working directory.
-EOF
-    die ($dvips_warning . "\n\$TMPDIR=$TMPDIR  ***\n\n")
-       if ($TMPDIR =~ /\./ && $DVIPS =~ /dvips/ && !$DVIPS_SAFE);
-
-    &open_dbm_database if $DJGPP;
-}
-
-# MRO: set first parameter to the opposite of the second if second parameter is defined
-sub set_if_false {
-    $_[0] = !$_[1] if(defined $_[1]);
-}
-
-sub check_for_dots {
-    local($file) = @_;
-    if ($file =~ /\.[^.]*\./ && !$DVIPS_SAFE) {
-       die "\n\n\n *** Fatal Error --- but easy to fix ***\n"
-           . "\nCannot have '.' in file-name prefix, else dvips fails on images"
-           . "\nChange the name from  $file  and try again.\n\n";
-    }
-}
-
-# Process each file ...
-sub driver {
-    local($FILE, $orig_cwd, %unknown_commands, %dependent, %depends_on
-         , %styleID, %env_style, $bbl_cnt, $dbg, %numbered_section);
-    # MRO: $texfilepath has to be global!
-    local(%styles_loaded);
-    $orig_cwd = L2hos->Cwd();
-
-    print "\n *** initialise *** " if ($VERBOSITY > 1);
-    &initialise;               # Initialise some global variables
-
-    print "\n *** check modes *** " if ($VERBOSITY > 1);
-    &ascii_mode if $ASCII_MODE;        # Must come after initialization
-    &titles_language($TITLES_LANGUAGE);
-    &make_numbered_footnotes if ($NUMBERED_FOOTNOTES);
-    $dbg = $DEBUG ? "-debug" : "";
-    $dbg .= (($VERBOSITY>2) ? " -verbose" : "");
-
-    #use the same hashes for all files in a batch
-    local(%cached_env_img, %id_map, %symbolic_labels, %latex_labels)
-       if ($FIXEDDIR && $NO_SUBDIR);
-
-    local($MULTIPLE_FILES,$THIS_FILE);
-    $MULTIPLE_FILES = 1+$#ARGV if $ROOTED;
-    print "\n *** $MULTIPLE_FILES file".($MULTIPLE_FILES ? 's: ' : ': ')
-       . join(',',@ARGV) . " *** " if ($VERBOSITY > 1);
-
-    local(%section_info, %toc_section_info, %cite_info, %ref_files);
-    
-    foreach $FILE (@ARGV) {
-       &check_for_dots($FILE) unless $DVIPS_SAFE;
-       ++$THIS_FILE if $MULTIPLE_FILES;
-       do {
-           %section_info = ();
-           %toc_section_info = ();
-           %cite_info = ();
-           %ref_files = ();
-       } unless $MULTIPLE_FILES;
-       local($bbl_nr) = 1;
-
-       # The number of reused images and those in images.tex
-       local($global_page_num) = (0) unless($FIXEDDIR && $NO_SUBDIR);
-       # The number of images in images.tex
-       local($new_page_num) = (0); # unless($FIXEDDIR && $NO_SUBDIR);
-       local($pid, $sections_rx,
-           , $outermost_level, %latex_body, $latex_body
-           , %encoded_section_number
-           , %verbatim, %new_command, %new_environment
-           , %provide_command, %renew_command, %new_theorem
-           , $preamble, $aux_preamble, $prelatex, @preamble);
-
-       # must retain these when all files are in the same directory
-       # else the images.pl and labels.pl files get clobbered
-       unless ($FIXEDDIR && $NO_SUBDIR) {
-           print "\nResetting image-cache" if ($#ARGV);
-           local(%cached_env_img, %id_map, %symbolic_labels, %latex_labels)
-       }
-
-## AYS: Allow extension other than .tex and make it optional
-       ($EXT = $FILE) =~ s/.*\.([^\.]*)$/$1/;
-       if ( $EXT eq $FILE ) {
-           $EXT = "tex";
-           $FILE =~ s/$/.tex/;
-       }
-
-       #RRM: allow user-customisation, dependent on file-name
-       # e.g. add directories to $TEXINPUTS named for the file
-       # --- idea due to Fred Drake <fdrake@acm.org>
-       &custom_driver_hook($FILE) if (defined &custom_driver_hook);
-
-# JCL(jcl-dir)
-# We need absolute paths for TEXINPUTS here, because
-# we change the directory
-       if ($orig_cwd eq $texfilepath) {
-           &deal_with_texinputs($orig_cwd);
-       } else {
-           &deal_with_texinputs($orig_cwd, $texfilepath);
-       }
-
-       ($texfilepath, $FILE) = &get_full_path($FILE);
-       $texfilepath = '.' unless($texfilepath);
-
-       die "Cannot read $texfilepath$dd$FILE \n"
-           unless (-f "$texfilepath$dd$FILE");
-
-
-# Tell texexpand which files we *don't* want to look at.
-       $ENV{'TEXE_DONT_INCLUDE'} = $DONT_INCLUDE if $DONT_INCLUDE;
-# Tell texexpand which files we *do* want to look at, e.g.
-# home-brew style files
-       $ENV{'TEXE_DO_INCLUDE'} = $DO_INCLUDE if $DO_INCLUDE;
-
-       $FILE =~ s/\.[^\.]*$//; ## AYS
-       $DESTDIR = ''; # start at empty
-       if ($FIXEDDIR) {
-           $DESTDIR = $FIXEDDIR unless ($FIXEDDIR eq '.');
-           if (($ROOTED)&&!($texfilepath eq $orig_cwd)) {
-               $DESTDIR .= $dd . $FILE unless $NO_SUBDIR;
-           };
-       } elsif ($texfilepath eq $orig_cwd) {
-           $DESTDIR = ($NO_SUBDIR ? '.' : $FILE);
-       } else {
-           $DESTDIR = $ROOTED ? '.' : $texfilepath;
-           $DESTDIR .= $dd . $FILE unless $NO_SUBDIR;
-       }
-       $PREFIX  = "$FILE-" if $AUTO_PREFIX;
-
-       print "\nOPENING $texfilepath$dd$FILE.$EXT \n"; ## AYS
-
-       next unless (&new_dir($DESTDIR,''));
-        # establish absolute path to $DESTDIR
-       $DESTDIR = L2hos->Make_directory_absolute($DESTDIR);
-        &make_tmp_dir;
-        print "\nNote: Working directory is $DESTDIR\n";
-        print "Note: Images will be generated in $TMPDIR\n\n";
-
-# Need to clean up a bit in case there's garbage left
-# from former runs.
-       if ($DESTDIR) { chdir($DESTDIR) || die "$!\n"; }
-       if (opendir (TMP,$TMP_)) {
-           foreach (readdir TMP) {
-               L2hos->Unlink("TMP_$dd$_") unless (/^\.\.?$/);
-           }
-           closedir TMP; 
-       }
-       &cleanup(1);
-       unless(-d $TMP_) {
-           mkdir($TMP_, 0755) ||
-             die "Cannot create directory '$TMP_': $!\n";
-       }
-       chdir($orig_cwd);
-
-# RRM 14/5/98  moved this to occur earlier
-## JCL(jcl-dir)
-## We need absolute paths for TEXINPUTS here, because
-## we change the directory
-#      if ($orig_cwd eq $texfilepath) {
-#          &deal_with_texinputs($orig_cwd);
-#      } else {
-#          &deal_with_texinputs($orig_cwd, $texfilepath);
-#      }
-
-
-# This needs $DESTDIR to have been created ...
-       print " *** calling  `texexpand' ***" if ($VERBOSITY > 1);
-       local($unseg) = ($UNSEGMENT ? "-unsegment " : "");
-
-# does DOS need to check these here ?
-#      die "File $TEXEXPAND does not exist or is not executable\n"
-#          unless (-x $TEXEXPAND);
-       L2hos->syswait("$TEXEXPAND $dbg -auto_exclude $unseg"
-                . "-save_styles $DESTDIR$dd$TMP_${dd}styles "
-                . ($TEXINPUTS ? "-texinputs $TEXINPUTS " : '' )
-                . (($VERBOSITY >2) ? "-verbose " : '' )
-                . "-out $DESTDIR$dd$TMP_$dd$FILE "
-                . "$texfilepath$dd$FILE.$EXT")
-           && die " texexpand  failed: $!\n";
-       print STDOUT "\n ***  `texexpand' done ***\n" if ($VERBOSITY > 1);
-
-       chdir($DESTDIR) if $DESTDIR;
-       $SIG{'INT'} = 'handler';
-
-       &open_dbm_database;
-       &initialise_sections;
-       print STDOUT "\n ***  database open ***\n" if ($VERBOSITY > 1);
-
-       if ($IMAGES_ONLY) {
-           &make_off_line_images;
-       } else {
-           &rename_image_files;
-           &load_style_file_translations;
-           &make_language_rx;
-           &make_raw_arg_cmd_rx;
-#          &make_isolatin1_rx unless ($NO_ISOLATIN);
-           &translate_titles;
-           &make_sections_rx;
-           print "\nReading ...";
-           if ($SHORT_FILENAME) {
-               L2hos->Rename ("$TMP_$dd$FILE" ,"$TMP_$dd$SHORT_FILENAME" );
-               &slurp_input_and_partition_and_pre_process(
-                     "$TMP_$dd$SHORT_FILENAME");
-           } else {
-               &slurp_input_and_partition_and_pre_process("$TMP_$dd$FILE");
-           }
-           &add_preamble_head;
-           # Create a regular expressions
-           &set_depth_levels;
-           &make_sections_rx;
-           &make_order_sensitive_rx;
-           &add_document_info_page if ($INFO && !(/\\htmlinfo/));
-           &add_bbl_and_idx_dummy_commands;
-           &translate; # Destructive!
-       }
-       &style_sheet;
-       &close_dbm_database;
-       &cleanup();
-
-#JCL: read warnings from file to $warnings
-       local($warnings) = &get_warnings;
-       print "\n\n*********** WARNINGS ***********  \n$warnings"
-           if ($warnings || $NO_IMAGES || $IMAGES_ONLY);
-       &image_cache_message if ($NO_IMAGES || $IMAGES_ONLY);
-       &image_message if ($warnings =~ /Failed to convert/io);
-       undef $warnings;
-
-# JCL - generate directory index entry.
-# Yet, a hard link, cause Perl lacks symlink() on some systems.
-       do {
-           local($EXTN) = $EXTN;
-           $EXTN =~ s/_\w+(\.html?)/$1/ if ($frame_main_name);
-           local($from,$to) = (eval($LINKPOINT),eval($LINKNAME));
-           if (length($from) && length($to) && ($from ne $to)) {
-               #frames may have altered $EXTN
-               $from =~ s/$frame_main_name(\.html?)/$1/ if ($frame_main_name);
-               $to =~ s/$frame_main_name(\.html?)/$1/ if ($frame_main_name);
-               L2hos->Unlink($to);
-               L2hos->Link($from,$to);
-           }
-       } unless ($NO_AUTO_LINK || !($LINKPOINT) || !($LINKNAME));
-
-       &html_validate if ($HTML_VALIDATE && $HTML_VALIDATOR);
-
-# Go back to the source directory
-       chdir($orig_cwd);
-        $TEST_MODE = $DESTDIR if($TEST_MODE); # save path
-       $DESTDIR = '';
-       $OUT_NODE = 0 unless $FIXEDDIR;
-       $STYLESHEET = '' if ($STYLESHEET =~ /^\Q$FILE./);
-    }
-    print "\nUnknown commands: ". join(" ",keys %unknown_commands)
-       if %unknown_commands;
-###MEH -- math support
-    print "\nMath commands outside math: " .
-       join(" ",keys %commands_outside_math) .
-           "\n  Output may look weird or may be faulty!\n"
-               if %commands_outside_math;
-    print "\nDone.\n";
-    if($TEST_MODE) {
-      $TEST_MODE =~ s:[$dd$dd]+$::;
-      print "\nTo view the results, point your browser at:\n",
-        L2hos->path2URL(L2hos->Make_directory_absolute($TEST_MODE).$dd.
-        "index$EXTN"),"\n";
-    }
-    $end_time = time; 
-    $total_time = $end_time - $start_time;
-    print STDOUT join(' ',"Timing:",$total_time,"seconds\n")
-       if ($TIMING||$DEBUG||($VERBOSITY > 2));
-    $_;
-}
-
-sub open_dbm_database {
-    # These are DBM (unix DataBase Management) arrays which are actually
-    # stored in external files. They are used for communication between
-    # the main process and forked child processes;
-    print STDOUT "\n"; # this mysteriously prevents a core dump !
-
-    dbmopen(%verb, "$TMP_${dd}verb",0755);
-#    dbmopen(%verbatim, "$TMP_${dd}verbatim",0755);
-    dbmopen(%verb_delim, "$TMP_${dd}verb_delim",0755);
-    dbmopen(%expanded,"$TMP_${dd}expanded",0755);
-# Holds max_id, verb_counter, verbatim_counter, eqn_number
-    dbmopen(%global, "$TMP_${dd}global",0755);
-# Hold style sheet information
-    dbmopen(%env_style, "$TMP_${dd}envstyles",0755);
-    dbmopen(%txt_style, "$TMP_${dd}txtstyles",0755);
-    dbmopen(%styleID, "$TMP_${dd}styleIDs",0755);
-
-# These next two are used during off-line image conversion
-# %new_id_map maps image id's to page_numbers of the images in images.tex
-# %image_params maps image_ids to conversion parameters for that image
-    dbmopen(%new_id_map, "$TMP_${dd}ID_MAP",0755);
-    dbmopen(%img_params, "$TMP_${dd}IMG_PARAMS",0755);
-    dbmopen(%orig_name_map, "$TMP_${dd}ORIG_MAP",0755);
-
-    $global{'max_id'} = ($global{'max_id'} | 0);
-    &read_mydb(\%verbatim, "verbatim");
-    $global{'verb_counter'} = ($global{'verb_counter'} | 0);
-    $global{'verbatim_counter'} = ($global{'verbatim_counter'} | 0);
-
-    &read_mydb(\%new_command, "new_command");
-    &read_mydb(\%renew_command, "renew_command");
-    &read_mydb(\%provide_command, "provide_command");
-    &read_mydb(\%new_theorem, "new_theorem");
-    &read_mydb(\%new_environment, "new_environment");
-    &read_mydb(\%dependent, "dependent");
-#    &read_mydb(\%env_style, "env_style");
-#    &read_mydb(\%styleID, "styleID");
-    # MRO: Why should we use read_mydb instead of catfile?
-    $preamble = &catfile(&_dbname("preamble"),1) || '';
-    $prelatex = &catfile(&_dbname("prelatex"),1) || '';
-    $aux_preamble = &catfile(&_dbname("aux_preamble"),1) || '';
-    &restore_critical_variables;
-}
-
-sub close_dbm_database {
-    &save_critical_variables;
-    dbmclose(%verb); undef %verb;
-#    dbmclose(%verbatim); undef %verbatim;
-    dbmclose(%verb_delim); undef %verb_delim;
-    dbmclose(%expanded); undef %expanded;
-    dbmclose(%global); undef %global;
-    dbmclose(%env_style); undef %env_style;
-    dbmclose(%style_id); undef %style_id;
-    dbmclose(%new_id_map); undef %new_id_map;
-    dbmclose(%img_params); undef %img_params;
-    dbmclose(%orig_name_map); undef %orig_name_map;
-    dbmclose(%txt_style); undef %txt_style;
-    dbmclose(%styleID); undef %styleID;
-}
-
-sub clear_images_dbm_database {
-    # <Added calls to dbmclose dprhws>
-    # %new_id_map will be used by the off-line image conversion process
-    #
-    dbmclose(%new_id_map);
-    dbmclose(%img_params);
-    dbmclose(%orig_name_map);
-    undef %new_id_map;
-    undef %img_params;
-    undef %orig_name_map;
-    dbmopen(%new_id_map, "$TMP_${dd}ID_MAP",0755);
-    dbmopen(%img_params, "$TMP_${dd}IMG_PARAMS",0755);
-    dbmopen(%orig_name_map, "$TMP_${dd}ORIG_MAP",0755);
-}
-
-sub initialise_sections {
-    local($key);
-    foreach $key (keys %numbered_section) {
-       $global{$key} = $numbered_section{$key}}
-}
-
-sub save_critical_variables {
-    $global{'math_markup'} = $NO_MATH_MARKUP;
-    $global{'charset'} = $CHARSET;
-    $global{'charenc'} = $charset;
-    $global{'language'} = $default_language;
-    $global{'isolatin'} = $ISOLATIN_CHARS;
-    $global{'unicode'} = $UNICODE_CHARS;
-    if ($UNFINISHED_ENV) {
-       $global{'unfinished_env'} = $UNFINISHED_ENV;
-       $global{'replace_end_env'} = $REPLACE_END_ENV;
-    }
-    $global{'unfinished_comment'} = $UNFINISHED_COMMENT;
-    if (@UNMATCHED_OPENING) {
-       $global{'unmatched'} = join(',',@UNMATCHED_OPENING);
-    }
-}
-
-sub restore_critical_variables {
-    $NO_MATH_MARKUP = ($global{'math_markup'}|
-       (defined $NO_MATH_MARKUP ? $NO_MATH_MARKUP:1));
-    $CHARSET = ($global{'charset'}| $CHARSET);
-    $charset = ($global{'charenc'}| $charset);
-    $default_language = ($global{'language'}|
-       (defined $default_language ? $default_language:'english'));
-    $ISOLATIN_CHARS = ($global{'isolatin'}|
-       (defined $ISOLATIN_CHARS ? $ISOLATIN_CHARS:0));
-    $UNICODE_CHARS = ($global{'unicode'}|
-       (defined $UNICODE_CHARS ? $UNICODE_CHARS:0));
-    if ($global{'unfinished_env'}) {
-       $UNFINISHED_ENV = $global{'unfinished_env'};
-       $REPLACE_END_ENV = $global{'replace_end_env'};
-    }
-    $UNFINISHED_COMMENT = $global{'unfinished_comment'};
-    if ($global{'unmatched'}) {
-       @UNMATCHED_OPENING = split(',',$global{'unmatched'});
-    }
-
-    # undef any renewed-commands...
-    # so the new defs are read from %new_command
-    local($cmd,$key,$code);
-    foreach $key (keys %renew_command) {
-       $cmd = "do_cmd_$key";
-       $code = "undef \&$cmd"; eval($code) if (defined &$cmd);
-       if ($@) { print "\nundef \&do_cmd_$cmd failed"}
-    }
-}
-
-#JCL: The warnings should have been handled within the DBM database.
-# Unfortunately if the contents of an array are more than ~900 (system
-# dependent) chars long then dbm cannot handle it and gives error messages.
-sub write_warnings { #clean
-    my ($str) = @_;
-    $str .= "\n" unless($str =~ /\n$/);
-    print STDOUT "\n *** Warning: $str" if ($VERBOSITY > 1);
-    my $warnings = '';
-    if(-f 'WARNINGS') {
-        $warnings = &catfile('WARNINGS') || '';
-    }
-    return () if ($warnings =~ /\Q$str\E/);
-    if(open(OUT,">>WARNINGS")) {
-        print OUT $str;
-        close OUT;
-    } else {
-        print "\nError: Cannot append to 'WARNINGS': $!\n";
-    }
-}
-
-sub get_warnings {
-    return &catfile('WARNINGS',1) || '';
-}
-
-# MRO: Standardizing
-sub catfile {
-    my ($file,$ignore) = @_;
-    unless(open(CATFILE,"<$file")) {
-        print "\nError: Cannot read '$file': $!\n"
-            unless($ignore);
-        return undef;
-    }
-    local($/) = undef; # slurp in whole file
-    my $contents = <CATFILE>;
-    close(CATFILE);
-    $contents;
-}
-
-
-sub html_validate {
-    my ($extn) = $EXTN;
-    if ($EXTN !~ /^\.html?$/i) {
-       $extn =~ s/^[^\.]*(\.html?)$/$1/;
-    }
-    print "\n *** Validating ***\n";
-    my @htmls = glob("*$extn");
-    my $file;
-    foreach $file (@htmls) {
-      system("$HTML_VALIDATOR $file");
-    }
-}
-
-sub lost_argument {
-    local($cmd) = @_;
-    &write_warnings("\nincomplete argument to command: \\$cmd");
-}
-
-
-# These subroutines should have been handled within the DBM database.
-# Unfortunately if the contents of an array are more than ~900 (system
-# dependent) chars long then dbm cannot handle it and gives error messages.
-# So here we save and then read the contents explicitly.
-sub write_mydb {
-    my ($db, $key, $str) = @_;
-    &write_mydb_simple($db, "\n$mydb_mark#$key#$str");
-}
-
-# generate the DB file name from the DB name
-sub _dbname {
-    "$TMP_$dd$_[0]";
-}
-
-sub write_mydb_simple {
-    my ($db, $str) = @_;
-    my $file = &_dbname($db);
-    if(open(DB,">>$file")) {
-        print DB $str;
-        close DB;
-    } else {
-        print "\nError: Cannot append to '$file': $!\n";
-    }
-}
-
-sub clear_mydb {
-    my ($db) = @_;
-    my $file = &_dbname($db);
-    if(open(DB,">$file")) {
-        close DB;
-    } else {
-        print "\nError: Cannot clear '$file': $!\n";
-    }
-}
-
-# Assumes the existence of a DB file which contains
-# sequences of e.g. verbatim counters and verbatim contents.
-sub read_mydb {
-    my ($dbref,$name) = @_;
-    my $contents = &catfile(&_dbname($name),1);
-    return '' unless(defined $contents);
-    my @tmp = split(/\n$mydb_mark#([^#]*)#/, $contents);
-    my $i = 1; # Ignore the first element at 0
-    print "\nDBM: $name open..." if ($VERBOSITY > 2);
-    while ($i < scalar(@tmp)) {
-       my $tmp1 = $tmp[$i];
-        my $tmp2 = $tmp[++$i];
-       $$dbref{$tmp1} = defined $tmp2 ? $tmp2 : '';
-       ++$i;
-    };
-    $contents;
-}
-
-
-# Reads in a latex generated file (e.g. .bbl or .aux)
-# It returns success or failure
-# ****** and binds $_ in the caller as a side-effect ******
-sub process_ext_file {
-    local($ext) = @_;
-    local($found, $extfile,$dum,$texpath);
-    $extfile =  $EXTERNAL_FILE||$FILE;
-    local($file) = &fulltexpath("$extfile.$ext");
-    $found = 0;
-    &write_warnings(
-           "\n$extfile.$EXT is newer than $extfile.$ext: Please rerun latex" . ## AYS
-           (($ext =~ /bbl/) ? " and bibtex.\n" : ".\n"))
-       if ( ($found = (-f $file)) &&
-           &newer(&fulltexpath("$extfile.$EXT"), $file)); ## AYS
-    if ((!$found)&&($extfile =~ /\.$EXT$/)) {
-       $file = &fulltexpath("$extfile");
-       &write_warnings(
-           "\n$extfile is newer than $extfile: Please rerun latex" . ## AYS
-           (($ext =~ /bbl/) ? " and bibtex.\n" : ".\n"))
-           if ( ($found = (-f $file)) &&
-               &newer(&fulltexpath("$extfile"), $file)); ## AYS
-    }
-
-    # check in other directories on the $TEXINPUTS paths
-    if (!$found) {
-       foreach $texpath (split /$envkey/, $TEXINPUTS ) {
-           $file = "$texpath$dd$extfile.$ext";
-           last if ($found = (-f $file));
-       }
-    }
-    if ( $found ) {
-       print "\nReading $ext file: $file ...";
-       # must allow @ within control-sequence names
-       $dum = &do_cmd_makeatletter();
-       &slurp_input($file);
-       if ($ext =~ /bbl/) {
-           # remove the \newcommand{\etalchar}{...} since not needed
-           s/^\\newcommand{\\etalchar}[^\n\r]*[\n\r]+//s;
-       }
-       &pre_process;
-       &substitute_meta_cmds if (%new_command || %new_environment);
-       if ($ext eq "aux") {
-            my $latex_pathname = L2hos->path2latex($file);
-           $aux_preamble .=
-               "\\AtBeginDocument{\\makeatletter\n\\input $latex_pathname\n\\makeatother\n}\n";
-           local(@extlines) = split ("\n", $_);
-           print " translating ".(0+@extlines). " lines " if ($VERBOSITY >1);
-           local($eline,$skip_to); #$_ = '';
-           foreach $eline (@extlines) {
-               if ($skip_to) { next unless ($eline =~ s/$O$skip_to$C//) }
-               $skip_to = '';
-               # skip lines added for pdfTeX/hyperref compatibility
-               next if ($eline =~ /^\\(ifx|else|fi|global \\let|gdef|AtEndDocument|let )/);
-               # remove \index and \label commands, else invalid links may result
-               $eline =~ s/\\(index|label)\s*($O\d+$C).*\2//g;
-               if ($eline =~ /\\(old)?contentsline/) {
-                   do { local($_,$save_AUX) = ($eline,$AUX_FILE);
-                   $AUX_FILE = 0;
-                   &wrap_shorthand_environments;
-                   #footnote markers upset the numbering
-                   s/\\footnote(mark|text)?//g;
-                   $eline = &translate_environments($_);
-                   $AUX_FILE = $save_AUX;
-                   undef $_ };
-               } elsif ($eline =~ s/^\\\@input//) {
-                   &do_cmd__at_input($eline);
-                   $eline = '';
-               } elsif ($eline =~ s/^\\\@setckpt$O(\d+)$C//) {
-                   $skip_to = $1; next;
-               }
-#          $eline =~ s/$image_mark#([^#]+)#/print "\nIMAGE:",$img_params{$1},"\n";''/e;
-#              $_ .= &translate_commands(&translate_environments($eline));
-               $_ .= &translate_commands($eline) if $eline;
-           }
-           undef @extlines;
-       } elsif ($ext =~ /$caption_suffixes/) {
-           local(@extlines) = split ("\n", $_);
-           print " translating ".(0+@extlines). " lines "if ($VERBOSITY >1);
-           local($eline); $_ = '';
-           foreach $eline (@extlines) {
-               # remove \index and \label commands, else invalid links may result
-               $eline =~ s/\\(index|label)\s*($O\d+$C).*\2//gso;
-                if ($eline =~ /\\(old)?contentsline/) {
-                   do { local($_,$save_PREAMBLE) = ($eline,$PREAMBLE);
-                   $PREAMBLE = 0;
-                    &wrap_shorthand_environments;
-                    $eline = &translate_environments($_);
-                   $PREAMBLE = $save_PREAMBLE;
-                    undef $_ };
-                }
-               $_ .= &translate_commands($eline);
-           }
-           undef @extlines;
-       } else {
-           print " wrapping " if ($VERBOSITY >1);
-           &wrap_shorthand_environments;
-           $_ = &translate_commands(&translate_environments($_));
-           print " translating " if ($VERBOSITY >1);
-       }
-       print "\n processed size: ".length($_)."\n" if($VERBOSITY>1);
-       $dum = &do_cmd_makeatother();
-    } else { 
-       print "\n*** Could not find file: $file ***\n" if ($DEBUG)
-    };
-    $found;
-}
-
-sub deal_with_texinputs {
-# The dot precedes all, this let's local files override always.
-# The dirs we want are given as parameter list.
-    if(!$TEXINPUTS) { $TEXINPUTS = '.' }
-    elsif ($TEXINPUTS =~ /^$envkey/) {
-       $TEXINPUTS = '.'.$TEXINPUTS
-    };
-    if ($ROOTED) {$TEXINPUTS .= "$envkey$FIXEDDIR"}
-    $TEXINPUTS = &absolutize_path($TEXINPUTS);
-    $ENV{'TEXINPUTS'} = join($envkey,".",@_,$TEXINPUTS,$ENV{'TEXINPUTS'});
-}
-
-# provided by Fred Drake
-sub absolutize_path {
-    my ($path) = @_;
-    my $npath = '';
-    foreach $dir (split /$envkey/o, $path) {
-        $npath .= L2hos->Make_directory_absolute($dir) . $envkey;
-    }
-    $npath =~ s/$envkey$//;
-    $npath;
-}
-
-sub add_document_info_page {
-    # Uses $outermost_level
-    # Nasty race conditions if the next two are done in parallel
-    local($X) = ++$global{'max_id'};
-    local($Y) = ++$global{'max_id'};
-    ###MEH -- changed for math support: no underscores in commandnames
-    $_ = join('', $_
-             , (($MAX_SPLIT_DEPTH <= $section_commands{$outermost_level})?
-                "\n<HR>\n" : '')
-             , "\\$outermost_level", "*"
-             , "$O$X$C$O$Y$C\\infopagename$O$Y$C$O$X$C\n",
-             , " \\textohtmlinfopage");
-}
-
-
-# For each style file name in TMP_styles (generated by texexpand) look for a
-# perl file in $LATEX2HTMLDIR/styles and load it.
-sub load_style_file_translations {
-    local($_, $style, $options, $dir);
-    print "\n";
-    if ($TEXDEFS) {
-       foreach $dir (split(/$envkey/,$LATEX2HTMLSTYLES)) {
-           if (-f ($_ = "$dir${dd}texdefs.perl")) {
-               print "\nLoading $_...";
-               require ($_);
-               $styles_loaded{'texdefs'} = 1;
-               last;
-           }
-       }
-    }
-
-    # packages automatically implemented
-    local($auto_styles) = $AUTO_STYLES;
-    $auto_styles .= 'array|' if ($HTML_VERSION > 3.1);
-    $auto_styles .= 'tabularx|' if ($HTML_VERSION > 3.1);
-    $auto_styles .= 'theorem|';
-
-    # these are not packages, but can appear as if class-options
-    $auto_styles .= 'psamsfonts|';
-    $auto_styles .= 'noamsfonts|';
-
-    $auto_styles =~ s/\|$//;
-
-    if(open(STYLES, "<$TMP_${dd}styles")) {
-        while(<STYLES>) {
-            if(s/^\s*(\S+)\s*(.*)$/$style = $1; $options = $2;/eo) {
-                &do_require_package($style);
-               $_ = $DONT_INCLUDE;
-               s/:/|/g;
-               &write_warnings("No implementation found for style \`$style\'\n")
-                   unless ($styles_loaded{$style} || $style =~ /^($_)$/
-                       || $style =~ /$auto_styles/);
-
-                # MRO: Process options for packages
-                &do_package_options($style,$options) if($options);
-            }
-        }
-        close(STYLES);
-    } else {
-        print "\nError: Cannot read '$TMP_${dd}styles': $!\n";
-    }
-}
-
-################## Weird Special case ##################
-
-# The new texexpand can be told to leave in \input and \include
-# commands which contain code that the translator should simply pass
-# to latex, such as the psfig stuff.  These should still be seen by
-# TeX, so we add them to the preamble ...
-
-sub do_include_lines {
-    while (s/$include_line_rx//o) {
-       local($include_line) = &revert_to_raw_tex($&);
-       &add_to_preamble ('include', $include_line);
-    }
-}
-
-########################## Preprocessing ############################
-
-# JCL(jcl-verb)
-# The \verb declaration and the verbatim environment contain simulated
-# typed text and should not be processed. Characters such as $,\,{,and }
-# loose their special meanings and should not be considered when marking
-# brackets etc. To achieve this \verb declarations and the contents of
-# verbatim environments are replaced by markers. At the end the original
-# text is put back into the document.
-# The markers for verb and verbatim are different so that these commands
-# can be restored to what the raw input was just in case they need to
-# be passed to latex.
-
-sub pre_process {
-    # Modifies $_;
-    #JKR: We need support for some special environments.
-    # This has to be here, because  they might contain
-    # structuring commands like \section etc.
-    local(%comments);
-    &pre_pre_process if (defined &pre_pre_process);
-    s/\\\\/\\\\ /go;           # Makes it unnecessary to look for escaped cmds
-    &replace_html_special_chars;
-    # Remove fake environment which should be invisible to LaTeX2HTML.
-    s/\001//m;
-    s/[%]end\s*{latexonly}/\001/gom;
-    s/[%]begin\s*{latexonly}([^\001]*)\001/%/gos;
-    s/\001//m;
-
-    &preprocess_alltt if defined(&preprocess_alltt);
-
-    $KEEP_FILE_MARKERS = 1;
-    if ($KEEP_FILE_MARKERS) {
-#      if (s/%%% TEXEXPAND: \w+ FILE( MARKER)? (\S*).*/
-#          '<tex2html_'.($1?'':'end').'file>'.qq|#$2#|."\n"/em) {
-#          $_ = "<tex2html_file>#$2#\n". $_ };
-       #RRM: ignore \n at end of included file, else \par may result
-       if (s/(\n{1,2})?%%% TEXEXPAND: \w+ FILE( MARKER)? (\S*).*\n?/
-           ($2?$1:"\n").'<tex2html_'.($2?'':'end').'file>'.qq|#$3#|."\n"/em) {
-           $_ = "<tex2html_file>#$3#\n". $_ };
-    } else {
-       s/%%% TEXEXPAND[^\n]*\n//gm;
-    }
-
-    # Move all LaTeX comments into a local list
-    s/([ \t]*(^|\G|[^\\]))(%.*(\n[ \t]*|$))/print "%";
-       $comments{++$global{'verbatim_counter'}} = "$3";
-       &write_mydb("verbatim", $global{'verbatim_counter'}, $3);
-       "$1$comment_mark".$global{'verbatim_counter'}."\n"/mge;
-    # Remove the htmlonly-environment
-    s/\\begin\s*{htmlonly}\s*\n?//gom;
-    s/\\end\s*{htmlonly}\s*\n?//gom;
-    # Remove enviroments which should be invisible to LaTeX2HTML.
-    s/\n[^%\n]*\\end\s*{latexonly}\s*\n?/\001/gom;
-    s/((^|\n)[^%\n]*)\\begin\s*{latexonly}([^\001]*)\001/$1/gom;
-    s/\\end\s*{comment}\s*\n?/\001/gom;
-    s/\\begin\s*{comment}([^\001]*)\001//gom;
-
-    # this used to be earlier, but that can create problems with comments
-    &wrap_other_environments if (%other_environments);
-
-#    s/\\\\/\\\\ /go;          # Makes it unnecessary to look for escaped cmds
-    local($next, $esc_del);
-    &normalize_language_changes;
-    # Patches by #JKR, #EI#, #JCL(jcl-verb)
-
-    #protect \verb|\begin/end....|  parts, for LaTeX documentation
-    s/(\\verb\*?(.))\\(begin|end)/$1\003$3/g;
-
-    local(@processedV);
-    local($opt, $style_info,$before, $contents, $after, $env);
-    while (($UNFINISHED_COMMENT)||
-  (/\\begin\s*($opt_arg_rx)?\s*\{($verbatim_env_rx|$keepcomments_rx)\}/o)) {
-       ($opt, $style_info) = ($1,$2);
-       $before=$contents=$after=$env='';
-       if ($UNFINISHED_COMMENT) {
-           $UNFINISHED_COMMENT =~ s/([^:]*)::(\d+)/$env=$1;$after=$_;
-               $before = join("",$unfinished_mark,$env,$2,"#");''/e;
-           print "\nfound the lost \\end{$env}\n";
-       }
-       #RRM: can we avoid copying long strings here ?
-       #     maybe this loop can be an  s/.../../s  with (.*?)
-       #
-       ($before, $after, $env) = ($`, $', $3) unless ($env);
-       if (!($before =~ 
-     /\\begin(\s*\[[^\]]*\]\s*)?\{($verbatim_env_rx|$keepcomments_rx)\}/)) {
-           push(@processedV,$before);
-           print "'";$before = '';
-       }
-       if ($after =~ /\s*\\end{$env[*]?}/) { # Must NOT use the s///o option!!!
-           ($contents, $after) = ($`, $');
-           $contents =~ s/^\n+/\n/s;
-#          $contents =~ s/\n+$//s;
-
-           # re-insert comments
-           $contents =~ s/$comment_mark(\d+)\n?/$comments{$1}/g;
-#          $contents =~ s/$comment_mark(\d+)/$verbatim{$1}/g;
-
-           # revert '\\ ' -> '\\' only once 
-           if ($env =~ /rawhtml|$keepcomments_rx/i) {
-               $contents = &revert_to_raw_tex($contents);
-           } else {
-               $contents =~ s/([^\\](?:\\\\)*\\)([$html_escape_chars])/$1.&special($2)/geos;
-               $contents =~ s/\\\\ /\\\\/go;
-           }
-
-           if ($env =~/$keepcomments_rx/) {
-               $verbatim{++$global{'verbatim_counter'}} = "$contents";
-           } else {
-               &write_mydb("verbatim", ++$global{'verbatim_counter'}, $contents);
-           }
-#          $verbatim{$global{'verbatim_counter'}} = "$contents" if ($env =~/$keepcomments_rx/);
-#          $verbatim{$global{'verbatim_counter'}} = "$contents";
-
-           if ($env =~ /rawhtml|$keepcomments_rx/i) {
-               if ($before) {
-                   $after = join("",$verbatim_mark,$env
-                             ,$global{'verbatim_counter'},"#",$after);
-               } else {
-                   push (@processedV, join("",$verbatim_mark,$env
-                          ,$global{'verbatim_counter'},"#"));
-               }
-           } elsif ($env =~ /tex2html_code/) {
-               if ($before) {
-                   $after = join("","\\begin", $opt, "\{verbatim_code\}"
-                         , $verbatim_mark,$env
-                         , $global{'verbatim_counter'},"#"
-                         , "\\end\{verbatim_code\}",$after);
-               } else {
-                   push (@processedV
-                         , join("","\\begin", $opt, "\{verbatim_code\}"
-                                , $verbatim_mark,$env
-                                , $global{'verbatim_counter'},"#"
-                                , "\\end\{verbatim_code\}"));
-               }
-           } else {
-               if ($before) {
-                   $after = join("","\\begin", $opt, "\{tex2html_preform\}"
-                         , $verbatim_mark,$env
-                         , $global{'verbatim_counter'},"#"
-                         , "\\end\{tex2html_preform\}",$after);
-               } else {
-                   push (@processedV
-                         , join("","\\begin", $opt, "\{tex2html_preform\}"
-                                , $verbatim_mark,$env
-                                , $global{'verbatim_counter'},"#"
-                                , "\\end\{tex2html_preform\}" ));
-               }
-           }
-       } else {
-           print "Cannot find \\end{$env}\n";
-           $after =~ s/$comment_mark(\d+)\n?/$comments{$1}/g;
-#          $after =~ s/$comment_mark(\d+)/$verbatim{$1}/g;
-           if ($env =~ /rawhtml|$keepcomments_rx/i) {
-                $after = &revert_to_raw_tex($contents);
-           } else {
-               $after =~ s/([^\\](?:\\\\)*\\)([$html_escape_chars])/$1.&special($2)/geos;
-                $after =~ s/\\\\ /\\\\/go;
-           }
-           if ($env =~/$keepcomments_rx/) {
-                $verbatim{++$global{'verbatim_counter'}} = "$after";
-           } else {
-                &write_mydb("verbatim", ++$global{'verbatim_counter'}, $after );
-           }
-           $after = join("",$unfinished_mark,$env
-                         ,$global{'verbatim_counter'},"#");
-       }
-       $_ = join("",$before,$after);
-    }
-    print STDOUT "\nsensitive environments found: ".(int(0+@processedV/2))." "
-       if((@processedV)&&($VERBOSITY > 1));
-    $_ = join('',@processedV, $_); undef @processedV;
-
-    #restore \verb|\begin/end....|  parts, for LaTeX documentation
-#    $_ =~ s/(\\verb\W*?)\003(begin|end)/$1\\$2/g;
-    $_ =~ s/(\\verb(;SPM\w+;|\W*?))\003(begin|end)/$1\\$3/g;
-
-    # Now do the \verb declarations
-    # Patches by: #JKR, #EI#, #JCL(jcl-verb)
-    # Tag \verb command and legal opening delimiter with unique number.
-    # Replace tagged ones and its contents with $verb_mark & id number if the
-    # closing delimiter can be found. After no more \verb's are to tag, revert
-    # tagged one's to the original pattern.
-    local($del,$contents,$verb_rerun);
-    local($id) = $global{'verb_counter'};
-    # must tag only one alternation per loop
-    ##RRM: can this be speeded up using a list ??
-    my $vbmark = $verb_mark;
-    while (s/\\verb(\t*\*\t*)(\S)/"<verb$1".++$id.">$2"/e ||
-           s/\\verb()(\;SPM\w+\;|[^a-zA-Z*\s])/"<verb$1".++$id.">$2"/e ||
-           s/\\verb(\t\t*)([^*\s])/"<verb$1".++$id.">$2"/e) {
-
-       $del = $2;
-       #RRM: retain knowledge of whether \verb* or \verb
-       $vb_mark = ($1 =~/^\s*\*/? $verbstar_mark : $verb_mark);
-       $esc_del = &escape_rx_chars($del);
-       $esc_del = '' if (length($del) > 2);
-
-       # try to find closing delimiter and substitute the complete
-       # statement with $verb_mark or $verbstar_mark
-#      s/(<verb[^\d>]*$id>[\Q$del\E])([^$esc_del\n]*)([\Q$del\E]|$comment_mark(\d+)\n?)/
-       s/(<verb[^\d>]*$id>\Q$del\E)([^$esc_del\n]*?)(\Q$del\E|$comment_mark(\d+)\n?)/
-           $contents=$2;
-           if ($4) { $verb_rerun = 1;
-               join('', "\\verb$del", $contents, $comments{$4})
-           } else {
-               $contents =~ s|\\\\ |\\\\|g;
-               $contents =~ s|\n| |g;
-               $verb{$id}=$contents;
-               $verb_delim{$id}=$del;
-               join('',$vb_mark,$id,$verb_mark)
-           }
-       /e;
-    }
-    $global{'verb_counter'} = $id;
-    # revert changes to fake verb statements
-    s/<verb([^\d>]*)\d+>/\\verb$1/g;
-
-    #JKR: the comments include the linebreak and the following whitespace
-#   s/([^\\]|^)(%.*\n[ \t]*)+/$1/gom; # Remove Comments but not % which may be meaningful
-    s/((^|\n)$comment_mark(\d+))+//gom; # Remove comment markers on new lines, but *not* the trailing \n
-    s/(\\\w+|(\W?))($comment_mark\d*\n?)/($2)? $2.$3:($1? $1.' ':'')/egm; # Remove comment markers, not after braces
-#    s/(\W?)($comment_mark\d*\n?)/($1)? $1.$2:''/egm; # Remove comment markers, not after braces
-    # Remove comment markers, but *not* the trailing \n
-#  HWS:  Correctly remove multiple %%'s.
-#
-    s/\\%/\002/gm;
-#    s/(%.*\n[ \t]*)//gm;
-    s/(%[^\n]*\n)[ \t]*/$comment_mark\n/gm;
-
-    s/\002/\\%/gm;
-
-    local($tmp1,$tmp2);
-    s/^$unfinished_mark$keepcomments_rx(\d+)#\n?$verbatim_mark$keepcomments_rx(\d+)#/
-       $verbatim{$4}."\n\\end{$1}"/egm; # Raw TeX
-    s/$verbatim_mark$keepcomments_rx(\d+)#/
-       $tmp1 = $1;
-       $tmp2 = &protect_after_comments($verbatim{$2});
-       $tmp2 =~ s!\n$!!s;
-       join ('', "\\begin{$tmp1}"
-               , $tmp2
-               , "\n\\end{$tmp1}"
-               )/egm; # Raw TeX
-    s/$unfinished_mark$keepcomments_rx(\d+)#/$UNFINISHED_COMMENT="$1::$2";
-       "\\begin{$1}\n".$verbatim{$2}/egm; # Raw TeX
-
-    $KEEP_FILE_MARKERS = 1;
-    if ($KEEP_FILE_MARKERS) {
-       s/%%% TEXEXPAND: \w+ FILE( MARKER) (\S*).*\n/
-           '<tex2html_'.($1?'':'end').'file>'.qq|#.$2#\n|/gem;
-    } else {
-       s/%%% TEXEXPAND[^\n]*\n//gm;
-    }
-
-    &mark_string($_);
-
-
-    # attempt to remove the \html \latex and \latexhtml commands
-    s/\\latex\s*($O\d+$C)(.*)\1//gm;
-    s/\\latexhtml\s*($O\d+$C)(.*)\1\s*($O\d+$C)(.*)\3/$4/sg;
-    s/\\html\s*($O\d+$C)(.*)\1/$2/sg;
-    s/\\html\s*($O\d+$C)//gm;
-
-#    &make_unique($_);
-}
-
-# RRM:  When comments are retained, then ensure that they are benign
-# by removing \s and escaping braces, 
-# so that environments/bracing cannot become unbalanced.
-sub protect_after_comments {
-    my ($verb_text) = @_;
-#    $verb_text =~ s/\%(.*)/'%'.&protect_helper($1)/eg;
-    $verb_text =~ s/(^|[^\\])(\\\\)*\%(.*)/$1.$2.'%'.&protect_helper($3)/emg;
-    $verb_text;
-}
-
-sub protect_helper {
-    my ($text) = @_;
-    $text =~ s/\\/ /g;
-    $text =~ s/(\{|\})/\\$1/g;
-    $text;
-}
-
-sub make_comment {
-    local($type,$_) = @_;
-    $_ =~ s/\\(index|label)\s*(($O|$OP)\d+($C|$CP)).*\2//sg;
-    $_ = &revert_to_raw_tex($_);  s/^\n+//m;
-    $_ =~ s/\\(index|label)\s*\{.*\}//sg;
-    s/\-\-/- -/g; s/\-\-/- -/g; # cannot have -- inside a comment
-    $_ = join('', '<!-- ', $type , "\n ", $_ , "\n -->" );
-    $verbatim{++$global{'verbatim_counter'}} = $_;
-    &write_mydb('verbatim', $global{'verbatim_counter'}, $_ );
-    join('', $verbatim_mark, 'verbatim' , $global{'verbatim_counter'},'#')
-}
-
-sub wrap_other_environments {
-    local($key, $env, $start, $end, $opt_env, $opt_start);
-    foreach $key (keys %other_environments) {
-       # skip bogus entries
-       next unless ($env = $other_environments{$key});
-       $key =~ s/:/($start,$end)=($`,$');':'/e;
-
-       if (($end =~ /^\#$/m) && ($start =~ /^\#/m)) {
-           # catch Indica pre-processor language switches
-           $opt_start = $';
-           if ($env =~ s/\[(\w*)\]//o) {
-               $opt_env = join('','[', ($1 ? $1 : $opt_start ), ']');
-           }
-           local($next);
-           while ($_ =~ /$start\b/) {
-               push(@pre_wrapped, $`, "\\begin\{pre_$env\}", $opt_env );
-               $_=$';
-               if (/(\n*)$end/) {
-                   push(@pre_wrapped, $`.$1,"\\end\{pre_$env\}$1");
-                   $_ = $';
-                   if (!(s/^N(IL)?//o)) {$_ = '#'.$_ }
-               } else {
-                   print "\n *** unclosed $start...$end chunk ***\n";
-                   last;
-               }
-           }
-           $_ = join('', @pre_wrapped, $_);
-           undef @pre_wrapped;
-
-       } elsif (($end=~/^\n$/) && ($start =~ /^\#/)) {
-           # catch ITRANS pre-processor language info;  $env = 'nowrap';
-           local($ilang) = $start; $ilang =~ s/^\#//m;
-           s/$start\s*\=([^<\n%]*)\s*($comment_mark\d*|\n|%)/\\begin\{tex2html_$env\}\\ITRANSinfo\{$ilang\}\{$1\}\n\\end\{tex2html_$env\}$2/g;
-
-       } elsif (!$end &&($start =~ /^\#/m)) {
-           # catch Indica pre-processor input-mode switches
-           s/$start(.*)\n/\\begin\{tex2html_$env\}$&\\end\{tex2html_$env\}\n/g;
-
-       } elsif (($start eq $end)&&(length($start) == 1)) {
-           $start =~ s/(\W)/\\$1/; $end = $start;
-           s/([^$end])$start([^$end]+)$end/$1\\begin\{pre_$env\}$2\\end\{pre_$env\}/mg;
-       } elsif ($start eq $end) {
-           if (!($start =~ /\#\#/)) {
-               $start =~ s/(\W)/\\$1/g; $end = $start; }
-           local (@pre_wrapped);
-           local($opt); $opt = '[indian]' if ($start =~ /^\#\#$/m);
-           while ($_ =~ /$start/s) {
-               push(@pre_wrapped, $` , "\\begin\{pre_$env\}$opt");
-               $_=$';
-               if (/$end/s) {
-                   push(@pre_wrapped, $`, "\\end\{pre_$env\}");
-                   $_ = $';
-               } else {
-                   print "\n *** unclosed $start...$end chunk ***\n";
-                   last;
-               }
-           }
-           $_ = join('', @pre_wrapped, $_);
-           undef @pre_wrapped;
-       } elsif ($start && ($env =~ /itrans/)) {
-           # ITRANS is of this form
-           local($indic); if($start =~ /\#(\w+)$/m) {$indic = $1}
-           #include the language-name as an optional parameter
-           s/$start\b/\\begin\{pre_$env\}\[$indic\]/sg;
-           s/$end\b/\\end\{pre_$env\}/sg;
-       } elsif (($start)&&($end)) {
-           s/$start\b/\\begin\{pre_$env\}/sg;
-           s/$end\b/\\end\{pre_$env\}/sg;
-       }
-    }
-    $_;
-}
-
-#################### Marking Matching Brackets ######################
-
-# Reads the entire input file and performs pre_processing operations
-# on it before returning it as a single string. The pre_processing is
-# done on separate chunks of the input file by separate Unix processes
-# as determined by LaTeX \input commands, in order to reduce the memory
-# requirements of LaTeX2HTML.
-sub slurp_input_and_partition_and_pre_process {
-    local($file) = @_;
-    local(%string, @files, $pos);
-    local ($count) =  1;
-
-    unless(open(SINPUT,"<$file")) {
-        die "\nError: Cannot read '$file': $!\n";
-    }
-    local(@file_string);
-    print STDOUT "$file" if ($VERBOSITY >1);
-    while (<SINPUT>) {
-       if (/TEXEXPAND: INCLUDED FILE MARKER (\S*)/) {
-           # Forking seems to screw up the rest of the input stream
-           # We save the current position ...
-           $pos = tell SINPUT;
-           print STDOUT " fork at offset $pos " if ($VERBOSITY >1);
-            $string{'STRING'} = join('',@file_string); @file_string = ();
-           &write_string_out($count);
-           delete $string{'STRING'};
-           # ... so that we can return to it
-           seek(SINPUT, $pos, 0);
-           print STDOUT "\nDoing $1 ";
-           ++$count}
-       else {
-#          $string{'STRING'} .= $_
-           push(@file_string,$_);
-       }
-    }
-    $string{'STRING'} = join('',@file_string); @file_string = ();
-    &write_string_out($count);
-    delete $string{'STRING'};
-    close SINPUT;
-    @files = ();
-    if(opendir(DIR, $TMP_)) {
-        @files = sort grep(/^\Q$PARTITION_PREFIX\E\d+/, readdir(DIR));
-        closedir(DIR);
-    }
-
-    unless(@files) {
-        die "\nFailed to read in document parts.\n".
-            "Look up section Globbing in the troubleshooting manual.\n";
-    }
-
-    $count = 0;
-    foreach $file (@files) {
-       print STDOUT "\nappending file: $TMP_$dd$file " if ($VERBOSITY > 1);
-        $_ .= (&catfile("$TMP_$dd$file") || '');
-       print STDOUT "\ntotal length: ".length($_)." characters\n" if ($VERBOSITY > 1);
-    }
-    die "\nFailed to read in document parts (out of memory?).\n"
-       unless length($_);
-    print STDOUT "\ntotal length: ".length($_)." characters\n" if ($VERBOSITY > 1);
-}
-
-sub write_string_out {
-    local($count) = @_;
-    if ($count < 10) {$count = '00'.$count}
-    elsif ($count < 100) {$count = '0'.$count}
-    local($pid);
-    # All open unflushed streams are inherited by the child. If this is
-    # not set then the parent will *not* wait
-    $| = 1;
-    # fork returns 0 to the child and PID to the parent
-    &write_mydb_simple("prelatex", $prelatex);
-    &close_dbm_database;
-    unless ($CAN_FORK) {
-       &do_write_string_out;
-    } else {
-       unless ($pid = fork) {
-           &do_write_string_out;
-           exit 0;
-       };
-       waitpid($pid,0);
-    }
-    &open_dbm_database;
-}
-
-sub do_write_string_out {
-    local($_);
-    close (SINPUT) if($CAN_FORK);
-    &open_dbm_database;
-    $_ = delete $string{'STRING'};
-    # locate blank-lines, for paragraphs.
-    # Replace verbatim environments etc.
-    &pre_process;
-    # locate the blank lines for \par s
-    &substitute_pars;
-    # Handle newcommand, newenvironment, newcounter ...
-    &substitute_meta_cmds;
-    &wrap_shorthand_environments;
-    print STDOUT "\n *** End-of-partition ***" if ($VERBOSITY > 1);
-    if(open(OUT, ">$TMP_$dd$PARTITION_PREFIX$count")) {
-        print OUT $_;
-        close(OUT);
-    } else {
-        print "\nError: Cannot write '$TMP_$dd$PARTITION_PREFIX$count': $!\n";
-    }
-    print STDOUT $_ if ($VERBOSITY > 9);
-    $preamble = join("\n",$preamble,@preamble); # undef @preamble;
-    &write_mydb_simple("preamble", $preamble);
-    # this was done earlier; it should not be repeated
-    #&write_mydb_simple("prelatex", $prelatex);
-    &write_mydb_simple("aux_preamble", $aux_preamble);
-    &close_dbm_database;
-}
-
-# Reads the entire input file into a
-# single string.
-sub slurp_input  {
-    local($file) = @_;
-    local(%string);
-    if(open(INPUT,"<$file")) {
-        local(@file_string);
-        while (<INPUT>) {
-           push(@file_string, $_ );
-        }
-        $string{'STRING'} = join('',@file_string);
-        close INPUT;
-        undef @file_string;
-    } else {
-        print "\nError: Cannot read '$file': $!\n";
-    }
-    $_ = delete $string{'STRING'}; # Blow it away and return the result
-}
-
-# MRO: make them more efficient
-sub special {
-    $html_specials{$_[0]} || $_[0];
-}
-
-sub special_inv {
-    $html_specials_inv{$_[0]} || $_[0];
-}
-
-sub special_html {
-    $html_special_entities{$_[0]} || $_[0];
-}
-
-sub special_html_inv {
-    $html_spec_entities_inv{$_[0]} || $_[0];
-}
-
-# Mark each matching opening and closing bracket with a unique id.
-sub mark_string {
-    # local (*_) = @_; # Modifies $_ in the caller;
-    # -> MRO: changed to $_[0] (same effect)
-    # MRO: removed deprecated $*, replaced by option /m
-    $_[0] =~ s/(^|[^\\])\\{/$1tex2html_escaped_opening_bracket/gom;
-    $_[0] =~ s/(^|[^\\])\\{/$1tex2html_escaped_opening_bracket/gom; # repeat this
-    $_[0] =~ s/(^|[^\\])\\}/$1tex2html_escaped_closing_bracket/gom;
-    $_[0] =~ s/(^|[^\\])\\}/$1tex2html_escaped_closing_bracket/gom; # repeat this
-    my $id = $global{'max_id'};
-    my $prev_id = $id;
-    # mark all balanced braces
-    # MRO: This should in fact mark all of them as the hierarchy is
-    # processed inside-out.
-    1 while($_[0] =~ s/{([^{}]*)}/join("",$O,++$id,$C,$1,$O,$id,$C)/geo);
-    # What follows seems esoteric...
-    my @processedB = ();
-    # Take one opening brace at a time
-    while ($_[0] =~ /\{/) { 
-       my ($before,$after) = ($`,$');
-        my $change = 0;
-       while (@UNMATCHED_OPENING && $before =~ /\}/) {
-            my $this = pop(@UNMATCHED_OPENING);
-            print "\n *** matching brace \#$this found ***\n";
-            $before =~ s/\}/join("",$O,$this,$C)/eo;
-            $change = 1;
-        }
-        $_[0] = join('',$before,"\{",$after) if($change);
-        # MRO: mark one opening brace
-       if($_[0] =~ s/^([^{]*){/push(@processedB,$1);join('',$O,++$id,$C)/eos) {
-           $before=''; $after=$';
-        }
-        if ($after =~ /\}/) { 
-           $after =~ s/\}/join("",$O,$id,$C)/eo;
-           $_[0] = join('',$before,$O,$id,$C,$after);
-       } else {
-           print "\n *** opening brace \#$id  is unmatched ***\n";
-           $after =~ /^(.+\n)(.+\n)?/;
-           print " preceding: $after \n";
-           push (@UNMATCHED_OPENING,$id);
-       }
-    }
-    $_[0] = join('',@processedB,$_[0]); undef(@processedB);
-    print STDOUT "\nInfo: bracketings found: ", $id - $prev_id,"\n"
-        if ($VERBOSITY > 1);
-    # process remaining closing braces
-    while (@UNMATCHED_OPENING && $_[0] =~ /\}/) {
-        my $this = pop(@UNMATCHED_OPENING);
-        print "\n *** matching brace \#$this found ***\n";
-       $_[0] =~ s/\}/join("",$O,$this,$C)/eo;
-    }
-
-    while ($_[0] =~ /\}/) {
-        print "\n *** there was an unmatched closing \} ";
-        my ($beforeline,$prevline,$afterline) = ($`, $`.$& , $');
-        $prevline =~ /\n([^\n]+)\}$/m;
-        if ($1) {
-           print "at the end of:\n" . $1 . "\}\n\n";
-        } else {
-           $afterline =~ /^([^\n]+)\n/m;
-           if ($1) {
-               print "at the start of:\n\}" . $1 ."\n\n";
-           } else {
-               $prevline =~ /\n([^\n]+)\n\}$/m;
-               print "on a line by itself after:\n" . $1 . "\n\}\n\n";
-           }
-        }
-        $_[0] =  $beforeline . $afterline;
-    }
-    $global{'max_id'} = $id;
-
-    # restore escaped braces
-    $_[0] =~ s/tex2html_escaped_opening_bracket/\\{/go;
-    $_[0] =~ s/tex2html_escaped_closing_bracket/\\}/go;
-}
-
-sub replace_html_special_chars {
-    # Replaces html special characters with markers unless preceded by "\"
-    s/([^\\])(<|>|&|\"|``|'')/&special($1).&special($2)/geom;
-    # MUST DO IT AGAIN JUST IN CASE THERE ARE CONSECUTIVE HTML SPECIALS
-    s/([^\\])(<|>|&|\"|``|'')/&special($1).&special($2)/geom;
-    s/^(<|>|&|\"|``|'')/&special($1)/geom;
-}
-
-#  used in \verbatiminput only:   $html_escape_chars = '<>&';
-sub replace_all_html_special_chars { s/([$html_escape_chars])/&special($1)/geom; }
-
-# The bibliography and the index should be treated as separate sections
-# in their own HTML files. The \bibliography{} command acts as a sectioning command
-# that has the desired effect. But when the bibliography is constructed
-# manually using the thebibliography environment, or when using the
-# theindex environment it is not possible to use the normal sectioning
-# mechanism. This subroutine inserts a \bibliography{} or a dummy
-# \textohtmlindex command just before the appropriate environments
-# to force sectioning.
-sub add_bbl_and_idx_dummy_commands {
-    local($id) = $global{'max_id'};
-
-    s/([\\]begin\s*$O\d+$C\s*thebibliography)/$bbl_cnt++; $1/eg;
-    ## if ($bbl_cnt == 1) {
-       s/([\\]begin\s*$O\d+$C\s*thebibliography)/$id++; "\\bibliography$O$id$C$O$id$C $1"/geo;
-    #}
-    $global{'max_id'} = $id;
-    s/([\\]begin\s*$O\d+$C\s*theindex)/\\textohtmlindex $1/o;
-    s/[\\]printindex/\\textohtmlindex /o;
-    &lib_add_bbl_and_idx_dummy_commands() if defined(&lib_add_bbl_and_idx_dummy_commands);
-}
-
-
-# Uses and modifies $default_language
-# This would be straight-forward except when there are
-#  \MakeUppercase, \MakeLowercase  or \uppercase , \lowercase commands
-# present in the source. The cases have to be adjusted before the
-# ISO-character code is set; e.g. with "z --> "Z  in  german.perl
-#
-sub convert_iso_latin_chars {
-    local($_) = @_;
-    local($next_language, $pattern);
-    local($xafter, $before, $after, $funct, $level, $delim);
-    local(@case_processed);
-    while (/$case_change_rx/) {
-       $xafter = $2;
-#      $before .= $`;
-       push(@case_processed, $`);
-       $funct = $3;
-       $after = '';
-       $_ = $';
-       if ($xafter =~ /noexpand/) { $before .= "\\$funct"; next; }
-
-       s/^[\s%]*(.)/$delim=$1;''/eo;
-       if ($delim =~ /{/ ) {
-            # brackets not yet numbered...
-#          $before .= $funct . $delim;
-           push(@case_processed, $funct . $delim);
-           $level = 1;
-           $after = $delim;
-           while (($level)&&($_)&&(/[\{\}]/)) {
-               $after .= $` . $&;
-               $_ = $';
-               if ( "$&" eq "\{" ) {$level++}
-               elsif ( "$&" eq "\}" ) { $level-- }
-               else { print $_ }
-               print "$level";
-           } 
-#          $before .= $after;
-           push(@case_processed, $after);
-       } elsif ($delim eq "<") {
-            # brackets numbered, but maybe not processed...
-           s/((<|#)(\d+)(>|#)>).*\1//;
-           $after .= $delim . $&;
-           $_ = $';
-           print STDOUT "\n<$2$funct$4>" if ($VERBOSITY > 2);
-           $funct =~ s/^\\//o;
-           local($cmd) = "do_cmd_$funct";
-           $after = &$cmd($after);
-#          $before .= $after;
-           push(@case_processed, $after);
-       } elsif (($xafter)&&($delim eq "\\")) {
-           # preceded by \expandafter ...
-           # ...so expand the following macro first
-           $funct =~ s/^\\//o;
-           local($case_change) = $funct;
-           s/^(\w+|\W)/$funct=$1;''/eo;
-           local($cmd) = $funct;
-           local($thiscmd) = "do_cmd_$funct";
-           if (defined &$thiscmd) { $_ = &$thiscmd($_) }
-           elsif ($new_command{$funct}) { 
-               local($argn, $body, $opt) = split(/:!:/, $new_command{$funct});
-               do { ### local($_) = $body;
-                    &make_unique($body);
-               } if ($body =~ /$O/);
-               if ($argn) {
-                   do { 
-                       local($before) = '';
-                       local($after) = "\\$funct ".$_;
-                       $after = &substitute_newcmd;   # may change $after
-                       $after =~ s/\\\@#\@\@/\\/o ;
-                   }
-               } else { $_ = $body . $_; }
-           } else { print "\nUNKNOWN COMMAND: $cmd "; }
-
-           $cmd = $case_change;
-           $case_change = "do_cmd_$cmd";
-           if (defined &$case_change) { $_ = &$case_change($_) }
-       } else {
-            # this should not happen, but just in case...
-           $funct =~ s/^\\//o;
-           local($cmd) = "do_cmd_$funct";
-           print STDOUT "\n\n<$delim$funct>" if ($VERBOSITY > 2);
-           $_ = join('', $delim , $_ );
-           if (defined &$cmd) { $_ = &$cmd($_) }
-       }
-    }
-#   $_ = join('', $before, $_) if ($before);
-    $_ = join('', @case_processed, $_) if (@case_processed);
-
-    # ...now do the conversions
-    ($before, $after, $funct) = ('','','');
-    @case_processed = ();
-    if (/$language_rx/o) {
-       ($next_language, $pattern, $before, $after) = (($2||$1), $&, $`, $');
-       $before = &convert_iso_latin_chars($before) if ($before);
-#      push(@case_processed, $pattern, $before);
-       local($br_id) = ++$global{'max_id'};
-       $pattern = join('' , '\selectlanguage', $O.$br_id.$C
-           , (($pattern =~ /original/) ? $TITLES_LANGUAGE : $next_language )
-           , $O.$br_id.$C );
-       push(@case_processed, $before, $pattern);
-       push(@language_stack, $default_language);
-       $default_language = $next_language;
-       $_ = &convert_iso_latin_chars($after);
-       $default_language = pop @language_stack;
-    } else {
-       $funct = $language_translations{$default_language};
-       (defined(&$funct) ? $_ = &$funct($_) :
-        do {   &write_warnings(
-               "\nCould not find translation function for $default_language.\n\n")
-           }
-       );
-       if ($USE_UTF ||(!$NO_UTF &&(defined %unicode_table)&&length(%unicode_table)>2)) {
-           &convert_to_unicode($_)};
-    }
-    $_ = join('', @case_processed, $_); undef(@case_processed);
-    $_;
-}
-
-# May need to add something here later
-sub english_translation { $_[0] }
-
-# This replaces \setlanguage{\language} with \languageTeX
-# This makes the identification of language chunks easier.
-sub normalize_language_changes {
-    s/$setlanguage_rx/\\$2TeX/gs;
-}
-
-sub get_current_language {
-    return () if ($default_language eq $TITLES_LANGUAGE);
-    local($lang,$lstyle) = ' LANG="';
-    $lang_code = $iso_languages{$default_language};
-    if (%styled_languages) {
-       $lstyle = $styled_languages{$default_language};
-       $lstyle = '" CLASS="'.$lstyle  if $lstyle;
-    }
-    ($lang_code ? $lang.$lang_code.$lstyle.'"' : '');
-}
-
-%styled_languages = ();
-
-sub do_cmd_htmllanguagestyle {
-    local($_) = @_;
-    local($class) = &get_next_optional_argument;
-    local($lang) = &missing_braces unless (
-       (s/$next_pair_pr_rx/$lang=$2;''/e)
-       ||(s/$next_pair_rx/$lang=$2;''/e));
-    return ($_) unless $lang;
-    local($class) = $iso_languages{$lang} unless $class;
-    if ($USING_STYLES && $class) {
-       print "\nStyling language: $lang = \"$class\" ";
-       $styled_languages{"$lang"} = $class;
-    }
-    $_;
-}
-
-# General translation mechanism:
-#
-#
-# The main program latex2html calls texexpand with the document name
-# in order to expand some of its \input and \include statements, here
-# also called 'merging', and to write a list of sensitized style, class,
-# input, or include file names.
-# When texexpand has finished, all is contained in one file, TMP_foo.
-# (assumed foo.tex is the name of the document to translate).
-#
-# In this version, texexpand cares for following environments
-# that may span include files / section boundaries:
-# (For a more technical description, see texexpand.)
-#  a) \begin{comment}
-#  b) %begin{comment}
-#  c) \begin{any}  introduced with \excludecomment
-#  d) %begin{any}
-#  e) \begin{verbatim}
-#  f) \begin{latexonly}
-#  g) %begin{latexonly}
-# 
-# a)-d) cause texexpand to drop its contents, it will not show up in the
-# output file. You can use this to 'comment out' a bunch of files, say.
-# 
-# e)-g) prevent texexpand from expanding input files, but the environment
-# content goes fully into the output file.
-# 
-# Together with each merging of \input etc. there are so-called %%%texexpand
-# markers accompanying the boundary.
-#
-# When latex2html reads in the output file, it uses these markers to write
-# each part to a separate file, and process them further.
-#
-#
-# If you have, for example:
-#
-# a) preample
-# b) \begin{document}
-# c) text
-# d) \input{chapter}
-# e) more text
-# f) \end{document}
-#
-# you end up in two parts, part 1 is a)-c), part 2 is the rest.
-# Regardless of environments spanning input files or sections.
-#
-#
-# What now starts is meta command substitution:
-# Therefore, latex2html forks a child process on the first part and waits
-# until it finished, then forks another on the next part and so forth
-# (see also &slurp_input_and_partition_and_preprocess).
-#
-# Here's what each child is doing:
-# Each child process reads the new commands translated so far by the previous
-# child from the TMP_global DBM database.
-# After &pre_processing, it substitutes the meta commands (\newcommand, \def,
-# and the like) it finds, and adds the freshly retrieved new commands to the
-# list so far.
-# This is done *only on its part* of the document; this saves upwards of memory.
-# Finally, it writes its list of new commands (synopsis and bodies) to the
-# DBM database, and exits.
-# After the last child finished, latex2html reads in all parts and
-# concatenates them.
-#
-#
-# So, at this point in time (start of &translate), it again has the complete
-# document, but now preprocessed and with new commands substituted.
-# This has several disadvantages: an amount of commands is substituted (in
-# TeX lingo, expanded) earlier than the rest.
-# This causes trouble if commands really must get expanded at the point
-# in time they show up.
-#
-#
-# Then, still in &translate, latex2html uses the list of section commands to
-# split the complete document into chunks.
-# The chunks are not written to files yet. They are retained in the @sections
-# list, but each chunk is handled separately.
-# latex2html puts the current chunk to $_ and processes it with
-# &translate_environments etc., then fetches the next chunk, and so on.
-# This prevents environments that span section boundaries from getting
-# translated, because \begin and \end cannot find one another, to say it this
-# way.
-#
-#
-# After the chunk is translated to HTML, it is written to a file.
-# When all chunks are done, latex2html rereads each file to get cross
-# references right, replace image markers with the image file names, and
-# writes index and bibliography.
-#
-#
-sub translate {
-    &normalize_sections;       # Deal with the *-form of sectioning commands
-
-    # Split the input into sections, keeping the preamble together
-    # Due to the regular expression, each split will create 5 more entries.
-    # Entry 1 and 2: non-letter/letter sectioning command,
-    # entry 4: the delimiter (may be empty)
-    # entry 5: the text.
-    local($pre_section, @sections);
-    if (/\\(startdocument|begin\s*($O\d+$C)\s*document\s*\2)/) {
-       $pre_section = $`.$&; $_ = $';
-    }
-    @sections = split(/$sections_rx/, $_);
-    $sections[0] = $pre_section.$sections[0] if ($pre_section);
-    undef $pre_section;
-    local($sections) = int(scalar(@sections) / 5);
-
-    # Initialises $curr_sec_id to a list of 0's equal to
-    # the number of sectioning commands.
-    local(@curr_sec_id) = split(' ', &make_first_key);
-    local(@segment_sec_id) = @curr_sec_id;
-    local($i, $j, $current_depth) = (0,0,0);
-    local($curr_sec) = $SHORT_FILENAME||$FILE;
-    local($top_sec) = ($SEGMENT ? '' : 'top of ');
-#    local(%section_info, %toc_section_info, $CURRENT_FILE, %cite_info, %ref_files);
-    local($CURRENT_FILE);
-    # These filenames may be set when translating the corresponding commands.
-    local($tocfile, $loffile, $lotfile, $footfile, $citefile, $idxfile,
-         $figure_captions, $table_captions, $footnotes, $citations, %font_size, %index,
-         %done, $t_title, $t_author, $t_date, $t_address, $t_affil, $changed);
-    local(@authors,@affils,@addresses,@emails,@authorURLs);
-    local(%index_labels, %index_segment, $preindex, %footnotes, %citefiles);
-    local($segment_table_captions, $segment_figure_captions);
-    local($dir,$nosave) = ('','');
-    local($del,$close_all,$open_all,$toc_sec_title,$multiple_toc);
-    local($open_tags_R) = [];
-    local(@save_open_tags)= ();
-    local(@language_stack) = ();
-    push (@language_stack, $default_language);
-
-#    $LATEX_FONT_SIZE = '10pt' unless ($LATEX_FONT_SIZE);
-    &process_aux_file 
-       if $SHOW_SECTION_NUMBERS || /\\(caption|(html|hyper)?((eq)?ref|cite))/;
-
-    require ("${PREFIX}internals.pl") if (-f "${PREFIX}internals.pl");
-#JCL(jcl-del)
-    &make_single_cmd_rx;
-#
-    $tocfile = $EXTERNAL_CONTENTS;
-    $idxfile = $EXTERNAL_INDEX;
-    $citefile = $EXTERNAL_BIBLIO; $citefile =~ s/#.*$//;
-    $citefiles{1} = $citefile if ($citefile);
-    print "\nTranslating ...";
-
-    while ($i <= @sections) {
-        undef $_;
-       $_ = $sections[$i];
-       s/^[\s]*//;             # Remove initial blank lines
-
-       # The section command was removed when splitting ...
-       s/^/\\$curr_sec$del/  if ($i > 0); # ... so put it back
-       if ($current_depth < $MAX_SPLIT_DEPTH)  {
-           if (($footnotes)&&($NO_FOOTNODE)&&( $current_depth < $MAX_SPLIT_DEPTH)) {
-               local($thesenotes) = &make_footnotes ;
-               print OUTPUT $thesenotes;
-           }
-           $CURRENT_FILE = &make_name($curr_sec, join('_',@curr_sec_id));
-           
-           open(OUTPUT, ">$CURRENT_FILE")
-               || die "Cannot write '$CURRENT_FILE': $!\n";
-           if ($XBIT_HACK) { # use Apache's XBit hack
-               chmod 0744, $CURRENT_FILE;
-               &check_htaccess;
-           } else {
-               chmod 0644, $CURRENT_FILE;
-           }
-
-           if ($MULTIPLE_FILES && $ROOTED) {
-               if ($DESTDIR =~ /^\Q$FIXEDDIR\E[$dd$dd]?([^$dd$dd]+)/)
-                   { $CURRENT_FILE = "$1$dd$CURRENT_FILE" };
-           }
-       }
-       &remove_document_env;
-#        &wrap_shorthand_environments;    #RRM  Is this needed ?
-       print STDOUT "\n" if ($VERBOSITY);
-       print STDOUT "\n" if ($VERBOSITY > 2);
-       print $i/5,"/$sections";
-       print ":$top_sec$curr_sec:" if ($VERBOSITY);
-
-       # Must do this early ... It also sets $TITLE
-       &process_command($sections_rx, $_) if (/^$sections_rx/);
-       # reset tags saved from the previous section
-       $open_tags_R = [ @save_open_tags ];
-       @save_open_tags = ();
-
-       local($curr_sec_tex);
-       if ((! $TITLE) || ($TITLE eq $default_title)) {
-           eval '$TITLE = '.$default_title;
-           $TITLE = $default_title if $@;
-           $curr_sec_tex = ($top_sec ? '' :
-                 join('', '"', &revert_to_raw_tex($curr_sec), '"'));
-           print STDOUT "$curr_sec_tex for $CURRENT_FILE\n" if ($VERBOSITY);
-       } else { 
-           local($tmp) = &purify($TITLE,1);
-           $tmp = &revert_to_raw_tex($tmp);
-           print STDOUT "\"$tmp\" for $CURRENT_FILE\n" if ($VERBOSITY); 
-       }
-
-       if (/\\(latextohtmlditchpreceding|startdocument)/m) {
-           local($after) = $';
-           local($before) = $`.$&;
-           $SEGMENT = 1 if ($1 =~ /startdocument/);
-           print STDOUT "\n *** translating preamble ***\n" if ($VERBOSITY);
-           $_ = &translate_preamble($before);
-           s/\n\n//g; s/<BR>//g;       # remove redundant blank lines and breaks
-#
-#          &process_aux_file  if $AUX_FILE_NEEDED;
-#
-           print STDOUT "\n *** preamble done ***\n" if ($VERBOSITY);
-           $PREAMBLE = 0;
-           $NESTING_LEVEL=0;
-           &do_AtBeginDocument;
-           $after =~ s/^\s*//m;
-           print STDOUT (($VERBOSITY >2)? "\n*** Translating environments ***" : ";");
-           $after = &translate_environments($after);
-           print STDOUT (($VERBOSITY >2)? "\n*** Translating commands ***" : ";");
-           $_ .= &translate_commands($after);
-#            $_ = &translate_commands($after);
-       } else {
-           &do_AtBeginDocument;
-           $PREAMBLE = 0;
-           $NESTING_LEVEL=0;
-           print STDOUT (($VERBOSITY >2)? "\n*** Translating environments ***" : ";");
-           $_ = &translate_environments($_);
-           print STDOUT (($VERBOSITY >2)? "\n*** Translating commands ***" : ";");
-           $_ = &translate_commands($_);
-       }
-
-       # close any tags that remain open
-       if (@$open_tags_R) {
-           ($close_all,$open_all) = &preserve_open_tags();
-           $_ .= $close_all; 
-           @save_open_tags = @$open_tags_R; $open_tags_R = [];
-       } else { ($close_all,$open_all) = ('','') }
-
-       print STDOUT (($VERBOSITY >2)? "\n*** Translations done ***" : "\n");
-#      if (($footnotes)&&($NO_FOOTNODE)&&( $current_depth < $MAX_SPLIT_DEPTH)) {
-#          $_ .= &make_footnotes
-#      }
-       print OUTPUT $_;
-
-       # Associate each id with the depth, the filename and the title
-       ###MEH -- starred sections don't show up in TOC ...
-       # RRM:  ...unless $TOC_STARS is set
-#      $toc_sec_title = &simplify($toc_sec_title);
-       $toc_sec_title = &purify($toc_sec_title);# if $SEGMENT;
-       $toc_sec_title = &purify($TITLE) unless ($toc_sec_title);       
-
-       if ($TOC_STARS) {
-           $toc_section_info{join(' ',@curr_sec_id)} =
-               "$current_depth$delim$CURRENT_FILE$delim$toc_sec_title"
-#                  if ($current_depth <= $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH);
-                   if ($current_depth <= $TOC_DEPTH);
-       } else {
-           $toc_section_info{join(' ',@curr_sec_id)} =
-               "$current_depth$delim$CURRENT_FILE$delim$toc_sec_title"
-               . ($curr_sec =~ /star$/ ? "$delim<tex2html_star_mark>" : "")
-#                  if ($current_depth <= $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH);
-                   if ($current_depth <= $TOC_DEPTH);
-       }
-
-       # include $BODYTEXT in the section_info, when starting a new page
-       $section_info{join(' ',@curr_sec_id)} =
-           "$current_depth$delim$CURRENT_FILE$delim$TITLE$delim"
-               . (($current_depth < $MAX_SPLIT_DEPTH)? $BODYTEXT: "");
-
-       # Get type of section (see also the split above)
-       $curr_sec = $sections[$i+1].$sections[$i+2];
-       $del = $sections[$i+4];
-
-       # Get the depth of the current section;
-#      $curr_sec = $outermost_level unless $curr_sec;
-       $current_depth = $section_commands{$curr_sec};
-       if ($after_segment) {
-           $current_depth = $after_segment;
-            $curr_sec_id[$after_segment] += $after_seg_num;
-            ($after_segment,$after_seg_num) = ('','');
-           for($j=1+$current_depth; $j <= $#curr_sec_id; $j++) {
-               $curr_sec_id[$j] = 0;
-           }
-       }
-       if ($SEGMENT||$SEGMENTED) {
-           for($j=1; $j <= $#curr_sec_id; $j++) {
-               $curr_sec_id[$j] += $segment_sec_id[$j];
-               $segment_sec_id[$j] = 0;
-           }
-       }; 
-
-
-       # this may alter the section-keys
-       $multiple_toc = 1 if ($MULTIPLE_FILES && $ROOTED && (/$toc_mark/));
-
-
-       #RRM : Should this be done here, or in \stepcounter ?
-       @curr_sec_id = &new_level($current_depth, @curr_sec_id);
-
-       $toc_sec_title = $TITLE = $top_sec = '';
-       $i+=5; #skip to next text section
-    }
-    $open_tags_R = [];
-    $open_all = '';
-
-    $_ = undef;
-    $_ = &make_footnotes if ($footnotes);
-    $CURRENT_FILE = '';
-    print OUTPUT;
-    close OUTPUT;
-    
-
-#    # this may alter the section-keys
-#    &adjust_root_keys if $multiple_toc;
-
-    if ($PREPROCESS_IMAGES) { &preprocess_images }
-    else { &make_image_file }
-    print STDOUT "\n *** making images ***" if ($VERBOSITY > 1);
-    &make_images;
-
-    # Link sections, add head/body/address do cross-refs etc
-    print STDOUT "\n *** post-process ***" if ($VERBOSITY > 1);
-    &post_process;
-
-    if (defined &document_post_post_process) {
-       #BRM: extra document-wide post-processing
-       print STDOUT "\n *** post-processing Document ***" if ($VERBOSITY > 1);
-       &document_post_post_process();
-    }
-
-    print STDOUT "\n *** post-processed ***" if ($VERBOSITY > 1);
-    &copy_icons if $LOCAL_ICONS;
-    if ($SEGMENT || $DEBUG || $SEGMENTED) {
-       &save_captions_in_file("figure",  $figure_captions) if $figure_captions;
-       &save_captions_in_file("table",  $table_captions) if $table_captions;
-#      &save_array_in_file ("captions", "figure_captions", 0, %figure_captions) if %figure_captions;
-#      &save_array_in_file ("captions", "table_captions", 0, %table_captions) if %table_captions;
-       &save_array_in_file ("index", "index", 0, %index);
-       &save_array_in_file ("sections", "section_info", 0, %section_info);
-       &save_array_in_file ("contents", "toc_section_info", 0,%toc_section_info);
-       &save_array_in_file ("index", "sub_index", 1, %sub_index) if %sub_index;
-       &save_array_in_file ("index", "index_labels", 1, %index_labels) if %index_labels;
-       &save_array_in_file ("index", "index_segment", 1, %index_segment) if %index_segment;
-       &save_array_in_file ("index", "printable_key", 1, %printable_key) 
-           if (%printable_key || %index_segment);
-    }
-    elsif ($MULTIPLE_FILES && $ROOTED) {
-       &save_array_in_file ("sections", "section_info", 0, %section_info);
-       &save_array_in_file ("contents", "toc_section_info", 0, %toc_section_info);
-    }
-    &save_array_in_file ("internals", "ref_files", 0, %ref_files) if $changed;
-    &save_array_in_file ("labels", "external_labels", 0, %ref_files);
-    &save_array_in_file ("labels", "external_latex_labels", 1, %latex_labels);
-    &save_array_in_file ("images", "cached_env_img", 0, %cached_env_img);
-}
-
-# RRM:
-sub translate_preamble {
-    local($_) = @_;
-    $PREAMBLE = 1;
-    $NESTING_LEVEL=0;   #counter for TeX group nesting level
-    # remove some artificially inserted constructions
-    s/\n${tex2html_deferred_rx}\\par\s*${tex2html_deferred_rx2}\n/\n/gm;
-    s/\\newedcommand(<<\d+>>)([A-Za-z]+|[^A-Za-z])\1(\[\d+\])?(\[[^]]*\])?(<<\d+>>)[\w\W\n]*\5($comment_mark\d*)?//gm;
-    s/\n{2,}/\n/ogm;
-
-    if (/\\htmlhead/) {
-        print STDOUT "\nPREAMBLE: discarding...\n$`" if ($VERBOSITY > 4);
-        local($after) = $&.$';
-       # translate segment preamble preceding  \htmlhead
-       &translate_commands(&translate_environments($`));
-       # translate \htmlhead  and rest of preamble
-       $_=&translate_commands(&translate_environments($after));
-        print STDOUT "\nPREAMBLE: retaining...\n$_" if ($VERBOSITY > 4);
-    } else {
-       # translate only preamble here (metacommands etc.)
-       # there should be no textual results, if so, discard them
-       &translate_commands(&translate_environments($_));
-        print STDOUT "\nPREAMBLE: discarding...\n$_" if ($VERBOSITY > 4);
-       $_="";
-    };
-    $_ = &do_AtBeginDocument($_);
-    if (! $SEGMENT) { $_ = ''} # segmented documents have a heading already
-    $_;
-}
-
-############################ Processing Environments ##########################
-
-sub wrap_shorthand_environments {
-    # This wraps a dummy environment around environments that do not use
-    # the begin-end convention. The wrapper will force them to be
-    # evaluated by Latex rather than them being translated.
-    # Wrap a dummy environment around matching TMPs.
-    # s/^\$\$|([^\\])\$\$/{$1.&next_wrapper('tex2html_double_dollar')}/ge;
-    # Wrap a dummy environment around matching $s.
-    # s/^\$|([^\\])\$/{$1.&next_wrapper('$')}/ge;
-    # s/tex2html_double_dollar/\$\$/go;
-    # Do \(s and \[s
-    #
-    local($wrapper) = "tex2html_wrap_inline";  # \ensuremath wrapper
-    print STDOUT "\n *** wrapping environments ***\n" if ($VERBOSITY > 3);
-
-    # MRO: replaced $* with /m
-    print STDOUT "\\(" if ($VERBOSITY > 3);
-    s/(^\\[(])|([^\\])(\\[(])/{$2.&make_any_wrapper(1,'',$wrapper).$1.$3}/geom;
-    print STDOUT "\\)" if ($VERBOSITY > 3);
-    s/(^\\[)]|[^\\]\\[)])/{$1.&make_any_wrapper(0,'',$wrapper)}/geom;
-
-    print STDOUT "\\[" if ($VERBOSITY > 3);
-    s/(^\\[[])|([^\\])(\\[[])/{$2.&make_any_wrapper(1,1,"displaymath")}/geom;
-    print STDOUT "\\]" if ($VERBOSITY > 3);
-    s/(^\\[\]])|([^\\])(\\[\]])/{$2.&make_any_wrapper(0,1,"displaymath")}/geom;
-
-    print STDOUT "\$" if ($VERBOSITY > 3);
-    s/$enspair/print "\$";
-       {&make_any_wrapper(1,'',$wrapper).$&.&make_any_wrapper(0,'',$wrapper)}/geom;
-
-    $double_dol_rx = '(^|[^\\\\])\\$\\$';
-    $single_dol_rx = '(^|[^\\\\])\\$';
-    print STDOUT "\$" if ($VERBOSITY > 3);
-
-    local($dollars_remain) = 0;
-    $_ = &wrap_math_environment;
-    $_ = &wrap_raw_arg_cmds;
-}
-
-sub wrap_math_environment {
-
-    # This wraps math-type environments
-    # The trick here is that the opening brace is the same as the close,
-    # but they *can* still nest, in cases like this:
-    #
-    # $ outer stuff ... \hbox{ ... $ inner stuff $ ... } ... $
-    #
-    # Note that the inner pair of $'s is nested within a group.  So, to
-    # handle these cases correctly, we need to make sure that the outer
-    # brace-level is the same as the inner. --- rst
-    #tex2html_wrap
-    # And yet another problem:  there is a scungy local idiom to do
-    # this:  $\_$ for a boldfaced underscore.  xmosaic can't display the
-    # resulting itty-bitty bitmap, for some reason; even if it could, it
-    # would probably come out as an overbar because of the floating-
-    # baseline problem.  So, we have to special case this.  --- rst again.
-
-    local ($processed_text, @processed_text, $before, $end_rx, $delim, $ifclosed);
-    local ($underscore_match_rx) = "^\\s*\\\\\\_\\s*\\\$";
-    local ($wrapper);
-    print STDOUT "\nwrap math:" if ($VERBOSITY > 3);
-
-    #find braced dollars, in tabular-specs
-    while (/((($O|$OP)\d+($C|$CP))\s*)\$(\s*\2)/) {
-        push (@processed_text, $`, $1.$dol_mark.$5);
-        $_ = $';
-    }
-    $_ = join('',@processed_text, $_) if (@processed_text);
-    undef @processed_text;
-
-    $dollars_remain = 0;
-    while (/$single_dol_rx/) {
-       $processed_text .= $`.$1;
-       $_ = $';
-       $wrapper = "tex2html_wrap_inline";
-       $end_rx = $single_dol_rx; # Default, unless we begin with $$.
-       $delim = "\$";
-
-        if (/^\$/ && (! $`)) {
-           s/^\$//;
-           $end_rx = $double_dol_rx;
-           $delim = "";        # Cannot say "\$\$" inside displaymath
-           $wrapper = "displaymath";
-
-        } elsif (/$underscore_match_rx/ && (! $`)) {
-
-            # Special case for $\_$ ...
-
-            s/$underscore_match_rx//;
-            $processed_text .= '\\_';
-            next;
-        }
-
-        # Have an opening $ or $$.  Find matching close, at same bracket level
-#      $processed_text .= &make_any_wrapper(1,'',$wrapper).$delim;
-
-       print STDOUT "\$" if ($VERBOSITY > 3);
-       $ifclosed = 0;
-       local($thismath);
-        while (/$end_rx/) {
-           # Forget the $$ if we are going to replace it with "displaymath"
-            $before = $` . (($wrapper eq "displaymath")? "$1" : $&);
-           last if ($before =~ /\\(sub)*(item|section|chapter|part|paragraph)(star)?\b/);
-           $thismath .= $before;
-            $_ = $';
-           s/^( [^\n])/\\space$1/s;  #make sure a trailing space doesn't get lost.
-
-            # Found dollar sign inside open subgroup ... now see if it's
-            # at the same brace-level ...
-
-            local ($losing, $br_rx) = (0, '');
-           print STDOUT "\$" if ($VERBOSITY > 3);
-            while ($before =~ /$begin_cmd_rx/) {
-                $br_rx = &make_end_cmd_rx($1);  $before = $';
-
-                if ($before =~ /$br_rx/) { $before = $'; }
-                else { $losing = 1; last; }
-            }
-            do { $ifclosed = 1; last } unless $losing;
-
-            # It wasn't ... find the matching close brace farther on; then
-            # keep going.
-
-            /$br_rx/;
-
-            $thismath .= $`.$&;
-
-           #RRM: may now contain unprocessed $s e.g. $\mbox{...$...$...}$
-           # the &do_cmd_mbox uses this specially to force an image
-           # ...but there may be other situations; e.g. \hbox
-           # so set a flag:
-           $dollars_remain = 1;
-
-            $_ = $';
-        }
-
-        # Got to the end.  Whew!
-       if ($ifclosed) {
-           # also process any nested math
-           while (($dollars_remain)&&($delim eq "\$")) {
-               local($saved) = $_;
-                $thismath =~ s/\$$//;
-                $_ = $thismath;
-               $thismath =  &wrap_math_environment;
-               $thismath .= "\$";
-               $_ = $saved;
-           }
-           $processed_text .= &make_any_wrapper(1,'',$wrapper) . $delim 
-               . $thismath . &make_any_wrapper(0,'',$wrapper);
-       } else {
-           print STDERR "\n\n *** Error: unclosed math or extra `\$', before:\n$thismath\n\n";
-#          # remove a $ to try to recover as much as possible.
-#          $thismath =~ s/([^\\]\\\\|[^\\])\$/$1\%\%/;
-#          $_ = $thismath . $_; $thismath = "";
-       print "\n$thismath\n\n\n$_\n\n\n"; die;
-           
-       }
-    }
-    $processed_text . $_;
-}
-
-sub translate_environments {
-    local ($_) = @_;
-    local($tmp, $capenv);
-#   print "\nTranslating environments ...";
-    local($after, @processedE);
-    local ($contents, $before, $br_id, $env, $pattern);
-    for (;;) {
-#      last unless (/$begin_env_rx/o);
-       last unless (/$begin_env_rx|$begin_cmd_rx|\\(selectlanguage)/o);
-#      local ($contents, $before, $br_id, $env, $pattern);
-       local($this_env, $opt_arg, $style_info);
-       $contents = '';
-       # $1,$2 : optional argument/text --- stylesheet info
-       # $3 : br_id (at the beginning of an environment name)
-       # $4 : environment name
-       # $5 : br_id of open-brace, when $3 == $4 == '';
-       # $6 : \selectlanguage{...}
-       if ($7) {
-           push(@processedE,$`);
-           $_ = $';
-           if (defined &do_cmd_selectlanguage) {
-               $_ = &do_cmd_selectlanguage($_);
-           } else {
-               local($cmd) = $7;
-               $pattern = &missing_braces unless (
-                   s/$next_pair_rx/$pattern = $2;''/e);
-               local($trans) = $pattern.'_translation';
-               if (defined &$trans) {
-                   &set_default_language($pattern,$_);
-               }
-               undef $cmd; undef $trans;
-           }
-           next;
-       } elsif ($4) {
-           ($before, $opt_arg, $style_info, $br_id
-                , $env, $after, $pattern) = ($`, $2, $3, $4, $5, $', $&);
-           if (($before)&& (!($before =~ /$begin_env_rx|$begin_cmd_rx/))) {
-               push(@processedE,$before);
-               $_ = $pattern . $after; $before = '';
-           }
-       } else {
-           ($before, $br_id, $env, $after, $pattern) = ($`, $6, 'group', $', $&);
-           if (($before)&& (!($before =~ /$begin_env_rx|$begin_cmd_rx/))) {
-               push(@processedE,$before);
-               $_ = $pattern . $after; $before = '';
-           }
-           local($end_cmd_rx) = &make_end_cmd_rx($br_id);
-           if ($after =~ /$end_cmd_rx/) {
-               # ... find the the matching closing one
-               $NESTING_LEVEL++;
-               ($contents, $after) = ($`, $');
-               $contents = &process_group_env($contents);
-               print STDOUT "\nOUT: {$br_id} ".length($contents) if ($VERBOSITY > 3);
-               print STDOUT "\n:$contents\n" if ($VERBOSITY > 7);
-               # THIS MARKS THE OPEN-CLOSE DELIMITERS AS PROCESSED
-               $_ = join("", $before,"$OP$br_id$CP", $contents,"$OP$br_id$CP", $after);
-               $NESTING_LEVEL--;
-           } else {
-               $pattern = &escape_rx_chars($pattern);
-               s/$pattern//;
-               print "\nCannot find matching bracket for $br_id";
-               $_ = join("", $before,"$OP$br_id$CP", $after);
-           }
-           next;
-       }
-       $contents = undef;
-       local($defenv) = $env =~ /deferred/;
-#      local($color_env);
-       local($color_env)
-           unless ($env =~ /tabular|longtable|in(line|display)|math/);
-       local($closures,$reopens);
-       local(@save_open_tags) = @$open_tags_R unless ($defenv);
-       local($open_tags_R) = [ @save_open_tags ] unless ($defenv);
-       local(@saved_tags) if ($env =~ /tabular|longtable/);
-       if ($env =~ /tabular|longtable|makeimage|in(line|display)/) {
-           @save_open_tags = @$open_tags_R;
-           $open_tags_R = [ @save_open_tags ];
-           # check for color
-           local($color_test) = join(',',@$open_tags_R);
-           if ($color_test =~ /(color{[^}]*})/g ) {
-               $color_env = $1;
-           } # else { $color_env = '' }
-
-           if ($env =~ /tabular|longtable|makeimage/) {
-               # close to the surrounding block-type tag
-               ($closures,$reopens,@saved_tags) = &preserve_open_block_tags();
-               @save_open_tags = @$open_tags_R;
-               $open_tags_R = [ @save_open_tags ];
-               if ($color_env) {
-                   $color_test = join(',',@saved_tags);
-                   if ($color_test =~ /(color{[^}]*})/g ) {
-                       $color_env = $1;
-                   }
-               }
-           } elsif ($env =~ /in(line|display)/) {
-               $closures = &close_all_tags() if ((&defined_env($env))
-                   &&!($defenv)&&!($env=~/inline/)&&(!$declarations{$env}));
-               if ($color_env) {
-                   $color_test = $declarations{$color_env};
-                   $color_test =~ s/<\/.*$//;
-                   $closures .= "\n$color_test";
-                   push (@$open_tags_R , $color_env);          
-               }
-           }
-       } elsif ($env =~ /alltt|tex2html_wrap/) {
-           # alltt is constructed as paragraphs, not with <PRE>
-           #  tex2html_wrap  creates an image, which is at text-level
-       } else {
-           $closures = &close_all_tags() if ((&defined_env($env))
-               &&!($defenv)&&(!$declarations{$env}) );
-       }
-       # Sets $contents and modifies $after
-       if (&find_end_env($env,$contents,$after)) {
-           print STDOUT "\nIN-A {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
-           &process_command($counters_rx, $before)
-               if ($before =~ /$counters_rx/);
-           # This may modify $before and $after
-           # Modifies $contents
-#RRM: the do_env_... subroutines handle when to translate sub-environments
-#          $contents = &translate_environments($contents) if
-##             ((!$defenv) && (&defined_env($env)) && (! $raw_arg_cmds{$env})
-##             && (!$declarations{$env})
-#              ((&defined_env($env)) && (! $raw_arg_cmds{$env})
-#              && (!($env =~ /latexonly|enumerate|figure|table|makeimage|wrap_inline/))
-#              && ((! $NO_SIMPLE_MATH)||(!($env =~ /wrap/)))
-#              && (!($env =~ /(math|wrap|equation|eqnarray|makeimage|minipage|tabular)/) )
-#              );
-           if ($opt_arg) { 
-               &process_environment(1, $env, $br_id, $style_info); # alters $contents
-           } else {
-               &process_environment(0, $env, $br_id, '');
-           }
-           undef $_;
-           print STDOUT "\nOUT-A {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
-           #JCL(jcl-env) - insert the $O$br_id$C stuff to handle environment grouping
-           if (!($contents eq '')) {
-               $after =~ s/^\n//o if ($defenv);
-               $this_env = join("", $before, $closures
-                         , $contents
-                         , ($defenv ? '': &balance_tags())
-                         , $reopens ); $_ = $after;
-           } else { 
-               $this_env = join("", $before , $closures
-                         , ($defenv ? '': &balance_tags())
-                         , $reopens ); $_ = $after;
-           };
-       ### Evan Welsh <welsh@epcc.ed.ac.uk> added the next 24 lines ##
-       } elsif (&defined_env($env)) {
-           print STDOUT "\nIN-B {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
-           # If I specify a function for the environment then it
-           # calls it with the contents truncated at the next section.
-           # It assumes I know what I'm doing and doesn't give a
-           # deferred warning.
-           $contents = $after;
-           if ($opt_arg) { 
-               $contents = &process_environment(1, $env, $br_id, $style_info);
-           } else {
-               $contents = &process_environment(0, $env, $br_id, '');
-           }
-           print STDOUT "\nOUT-B {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
-           $this_env = join("", $before, $closures ,$contents, $reopens);
-
-           # there should not be anything left over 
-#          $_ = $after;
-           $_ = '';
-       } elsif ($ignore{$env}) {
-           print STDOUT "\nIGNORED {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
-           # If I specify that the environment should be ignored then
-           # it is but I get a deferred warning.
-           $this_env = join("", $before , $closures , &balance_tags()
-                     , $contents, $reopens );
-           $_ = $after;
-           &write_warnings("\n\\end{$env} not found (ignored).\n");
-       } elsif ($raw_arg_cmds{$env}) {
-           print "\nIN-C {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
-           # If I specify that the environment should be passed to tex
-           # then it is with the environment truncated at the next
-           # section and I get a deferred warning.
-
-           $contents = $after;
-           if ($opt_arg) { 
-               $contents = &process_environment(1, $env, $br_id, $style_info);
-           } else {
-               $contents = &process_environment(0, $env, $br_id, '');
-           }
-           print STDOUT "\nOUT-C {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
-           $this_env = join("", $before, $closures
-                            , $contents, &balance_tags(), $reopens );
-           $_='';
-           &write_warnings(
-               "\n\\end{$env $br_id} not found (truncated at next section boundary).\n");
-       } else {
-           $pattern = &escape_rx_chars($pattern);
-           s/$pattern/$closures/;
-           print "\nCannot find \\end{$env $br_id}\n";
-           $_ .= join('', &balance_tags(), $reopens) unless ($defenv);
-       }
-       if ($this_env =~ /$begin_env_rx|$begin_cmd_rx/) {
-           $_ = $this_env . $_;
-       } else { push (@processedE, $this_env) }
-    }
-    $_ = join('',@processedE) . $_;
-    $tmp = $_; undef $_;
-    &process_command($counters_rx, $tmp) if ($tmp =~ /$counters_rx/);
-    $_ = $tmp; undef $tmp;
-    $_
-}
-
-sub find_end_env {
-    # MRO: find_end_env($env,$contents,$rest)
-    #local ($env, *ref_contents, *rest) = @_;
-    my $env = $_[0];
-    my $be_rx = &make_begin_end_env_rx($env);
-    my $count = 1;
-
-    while ($_[2] =~ /($be_rx)(\n?)/s) { # $rest
-       $_[1] .= $`; # $contents
-
-       if ($2 eq "begin") { ++$count }
-       else { --$count };
-
-       #include any final \n at an {end} only
-       $_[2] = (($2 eq 'end')? $5 : '') . $'; # $rest
-       last if $count == 0;
-
-       $_[1] .= $1; # $contents
-    }
-
-    if ($count != 0) {
-       $_[2] = join('', $_[1], $_[2]); # $rest = join('', $contents, $rest);
-       $_[1] = ''; # $contents
-       return(0)
-    } else { return(1) }
-}
-
-
-sub process_group_env {
-    local($contents) = @_;
-    local(@save_open_tags) = @$open_tags_R;
-    local($open_tags_R) = [ @save_open_tags ];
-    print STDOUT "\nIN::{group $br_id}" if ($VERBOSITY > 4);
-    print STDOUT "\n:$contents\n" if ($VERBOSITY > 6);
-
-    # need to catch explicit local font-changes
-    local(%font_size) = %font_size if (/\\font\b/);
-
-    # record class/id info for a style-sheet entry
-    local($env_id, $tmp, $etmp);
-    if (($USING_STYLES) && !$PREAMBLE ) { $env_id = $br_id; }
-#      $env_id = "grp$br_id";
-#      $styleID{$env_id} = " ";
-#        $env_id = " ID=\"$env_id\"";
-#    }
-
-    undef $_;
-    $contents =~ s/^\s*$par_rx\s*//s; # don't start with a \par 
-    if ($contents =~ /^\s*\\($image_switch_rx)\b\s*/s) {
-       # catch TeX-like environments: {\fontcmd ... }
-       local($image_style) = $1;
-       if ($USING_STYLES) {
-           $env_style{$image_style} = " " unless ($env_style{$image_style});
-       }
-       local($switch_cmd) = "do_cmd_${image_style}";
-       if (defined &$switch_cmd ) {
-           eval "\$contents = \&${switch_cmd}(\$')";
-           print "\n*** &$switch_cmd didn't work: $@\n$contents\n\n" if ($@);
-       } elsif ($contents =~ /$par_rx/) {
-           # split into separate image for each paragraph
-           local($par_style,$this_par_img) = '';
-           local(@par_pieces) = split($par_rx, $contents);
-           local($this_par,$par_style,$par_comment);
-           $contents = '';
-           while (@par_pieces) {
-               $this_par = shift @par_pieces;
-               if ($this_par =~ /^\s*\\($image_switch_rx)\b/s) {
-                   $image_style = $1;
-                   $par_style = 'P.'.$1;
-                   $env_style{$par_style} = " " unless ($env_style{$par_style});
-               }
-#      no comment: source is usually too highly encoded to be meaningful
-#      $par_comment = &make_comment($image_style,$this_par);
-               $this_par_img = &process_in_latex("\{".$this_par."\}");
-               $contents .=  join(''  #,"\n", $par_comment
-                       , "\n<P"
-                       , (($USING_STYLES && $image_style)? " CLASS=\"$image_style\"" :'')
-                       ,">", $this_par_img
-                       , "</P>\n");
-               if (@par_pieces) {
-                   # discard the pieces from matching  $par_rx
-                   $dum = shift @par_pieces;
-                   $dum = shift @par_pieces;
-                   $dum = shift @par_pieces;
-                   $dum = shift @par_pieces;
-                   $dum = shift @par_pieces;
-                   $dum = shift @par_pieces;
-#                  $contents .= "\n</P>\n<P>";
-               }
-           }
-       } else {
-           $contents = &process_undefined_environment("tex2html_accent_inline"
-               , ++$global{'max_id'},"\{".$contents."\}");
-        }
-    } elsif ($contents =~ /^\s*\\(html)?url\b($O\d+$C)[^<]*\2\s*/) {
-       # do nothing
-       $contents = &translate_environments($contents);
-       $contents = &translate_commands($contents);
-    } elsif (($env_switch_rx)&&($contents =~ s/^(\s*)\\($env_switch_rx)\b//s)) {
-       # write directly into images.tex, protected by \begingroup...\endgroup
-       local($prespace, $cmd, $tmp) = ($1,$2,"do_cmd_$2");
-       $latex_body .= "\n\\begingroup ";
-       if (defined &$tmp) {
-           eval("\$contents = &do_cmd_$cmd(\$contents)");
-       }
-       $contents = &translate_environments($contents);
-       $contents = &translate_commands($contents);
-       undef $tmp; undef $cmd;
-       $contents .= "\n\\endgroup ";
-    } elsif ($contents =~ /^\s*\\([a-zA-Z]+)\b/s) { 
-       local($after_cmd) = $';
-       local($cmd) = $1; $tmp = "do_cmd_$cmd"; $etmp = "do_env_$cmd";
-       if (($cmd =~/^(rm(family)?|normalsize)$/)
-               ||($declarations{$cmd}&&(defined &$tmp))) {
-           do{
-               local(@save_open_tags) = @$open_tags_R;
-               eval "\$contents = \&$tmp(\$after_cmd);";
-               print "\n*** eval &$tmp failed: $@\n$contents\n\n" if ($@);
-               $contents .= &balance_tags();
-           };
-       } elsif ($declarations{$cmd}&&(defined &$etmp)) {
-           eval "\$contents = \&$etmp(\$after_cmd);";
-       } else {
-           $contents = &translate_environments($contents);
-           $contents = &translate_commands($contents)
-               if ($contents =~ /$match_br_rx/o);
-           # Modifies $contents
-           &process_command($single_cmd_rx,$contents) if ($contents =~ /\\/o);
-       }
-       undef $cmd; undef $tmp; undef $etmp;
-    } else { 
-       $contents = &translate_environments($contents);
-       $contents = &translate_commands($contents)
-           if ($contents =~ /$match_br_rx/o);
-        # Modifies $contents
-       &process_command($single_cmd_rx,$contents)
-           if ($contents =~ /\\/o);
-    }
-    $contents . &balance_tags();
-}
-
-# MODIFIES $contents
-sub process_environment {
-    local($opt, $env, $id, $styles) = @_;
-
-    local($envS) = $env; $envS =~ s/\*\s*$/star/;
-    local($env_sub,$border,$attribs,$env_id) = ("do_env_$envS",'','','');
-    local($original) = $contents;
-
-    if ($env =~ /tex2html_deferred/ ) {
-       $contents = &do_env_tex2html_deferred($contents);
-       return ($contents);
-    }
-    $env_id = &read_style_info($opt, $env, $id, $styles) 
-       if (($USING_STYLES)&&($opt));
-
-    if (&defined_env($env)) {
-       print STDOUT ",";
-       print STDOUT "{$env $id}" if ($VERBOSITY > 1);
-#      $env_sub =~ s/\*$/star/;
-       $contents = &$env_sub($contents);
-
-    } elsif ($env =~ /tex2html_nowrap/) {
-       #pass it on directly for LaTeX, via images.tex
-       $contents = &process_undefined_environment($env, $id, $contents);
-       return ($contents);
-
-#    elsif (&special_env) {    # &special_env modifies $contents
-    } else {
-       local($no_special_chars) = 0;
-       local($failed) = 0;
-       local($has_special_chars) = 0;
-       &special_env; #  modifies $contents
-       print STDOUT "\n<MATH $env$id $contents>" if ($VERBOSITY > 3);
-       if ($failed || $has_special_chars) {
-           $contents = $original;
-           $failed = 1;
-           print STDOUT " !failed!\n" if ($VERBOSITY > 3);
-        }
-    }
-    if (($contents) && ($contents eq $original)) {
-        if ($ignore{$env}) {  return(''); }
-        # Generate picture
-       if ($contents =~ s/$htmlborder_rx//o) {
-           $attribs = $2; $border = (($4)? "$4" : 1)
-       } elsif ($contents =~ s/$htmlborder_pr_rx//o) { 
-           $attribs = $2; $border = (($4)? "$4" : 1)
-       }
-       $contents = &process_undefined_environment($env, $id, $contents);
-       $env_sub = "post_latex_$env_sub"; # i.e. post_latex_do_env_ENV
-        if ( defined &$env_sub) {
-           $contents = &$env_sub($contents);
-       } elsif (($border||($attributes))&&($HTML_VERSION > 2.1)) {
-           $contents = &make_table($border,$attribs,'','','',$contents);
-       } else {
-           $contents = join('',"<BR>\n",$contents,"\n<BR>")
-               unless (!($contents)||($inner_math)||($env =~
-                     /^(tex2html_wrap|tex2html_nowrap|\w*math|eq\w*n)/o ));
-       }
-    }
-    $contents;
-}
-
-
-#RRM: This reads the style information contained in the optional argument
-#   to the \begin command. It is stored to be recovered later as an entry
-#   within the automatically-generated style-sheet, if $USING_STYLES is set.
-# Syntax for this info is:
-#   <style names> ; <extra style-info> 
-
-sub read_style_info {
-    local($opt, $envS, $id, $styles) = @_;
-    return() unless (($opt)&&($USING_STYLES));
-    # allow macro-expansion within the style-info
-    $opt = &translate_commands($opt) if ($opt =~ /\\/);
-
-    # record class/id info for a style-sheet entry
-    local($style_names, $style_extra, $env_id)=(''," ",'');
-    if ($opt) {
-       # if there is a `;'  then <names> ; <extra>
-       if ($styles =~ /^\s*([^\|]*)\|\s*(.*)$/) {
-           $style_names = $1; $style_extra = $2;
-           if ($style_names =~ /[=:;]/) {
-               # cannot be <names>, so is <extra>
-               $style_extra = $style_names.$style_extra;
-               $style_names = '';
-           }
-       } elsif ($styles =~ /[\=\:]/) {
-           # cannot be <names>, so is <extras>
-           $style_extra = $styles;
-       } else { $style_names = $styles }
-       $style_extra =~ s/\s*[=:]\s*/ : /go;
-       $style_extra =~ s/([\w,\-]+)\s+([\w,\-]+)/$1 ; $2/go;
-       $style_extra =~ s/\s*,\s*/ /go;
-
-       if ($style_names) {
-           local($sname);
-           local(@names) = split ( /\s+/ , $style_names );
-           # ensure a style-sheet entry for each new name
-           foreach $sname (@names) {
-               $env_style{$sname} = " "
-                   unless (($env_style{$sname})||($sname =~ /^\s*$/));         
-           }
-       }
-    }
-    # remove uninformative part of internally-defined env names
-    $envS =~ s/tex2html_(\w+_)?(\w+)/$2/; $envS =~ s/preform/pre/;
-    $env_id = $envS.$id;
-    $styleID{$env_id} = $style_extra unless ($PREAMBLE);
-    
-    if ($style_names) { $envS = "$style_names" }
-    elsif (($envS =~ /^pre$/)&&
-       (/^\\begin.*preform($O|$OP)\d+($C|$CP)$verbatim_mark(\w*[vV]erbatim)(\*?)/))
-           { $envS = $3.($4 ? 'star' : '') };
-    $env_style{$envS} = " " unless (($style_names)||($env_style{$envS}));
-    $env_id = " ID=\"$env_id\"".(($envS) ? " CLASS=\"$envS\"" : '');
-    return($env_id);
-}
-
-# RRM: This provides the mechanism to save style information in %env_style
-#      using LaTeX macros  \htmlsetstyle  and  \htmladdtostyle
-#
-sub process_htmlstyles {
-    local($mode, $_) = @_;
-    local($pre_tags) = &get_next_optional_argument;
-    local($class) = &missing_braces unless (
-        (s/$next_pair_pr_rx/$class = $2;''/e)
-        ||(s/$next_pair_rx/$class = $2;''/e));
-    local($sinfo) = &missing_braces unless (
-        (s/$next_pair_pr_rx/$sinfo = $2;''/e)
-        ||(s/$next_pair_rx/$sinfo = $2;''/e));
-    return ($_) unless ($class||$pre_tags);
-
-    $class = $pre_tags.($class ?'.':'').$class;
-    $sinfo =~ s/\s*[:=]\s*/ : /g;
-    $sinfo =~ s/\s*,\s*/ /g;
-    if ($mode =~ /add/) {
-       $sinfo = '; '.$sinfo if ($env_style{$class}); 
-       $env_style{$class} .= $sinfo;
-    } else { $env_style{$class} = $sinfo }
-    $_;
-}
-sub do_cmd_htmlsetstyle   { &process_htmlstyles('set',@_) }
-sub do_cmd_htmladdtostyle { &process_htmlstyles('add',@_) }
-
-
-# The $<$, $>$, $|$ and $=>$, etc strings are replaced with their textual
-# equivalents instead of passing them on to latex for processing in math-mode.
-# This will not be necessary when the mechanism for passing environments
-# to Latex is improved.
-# RETURNS SUCCESS OR FAILURE
-sub special_env {
-    # Modifies $contents in its caller
-    local($next)='';
-    local ($allow) = $HTML_VERSION ge '3.0' ?
-        "[^#\$%&~\\\\{}]|\\limits" : "[^^#\$%&~_\\\\{}]";
-    #JKR: Use italics instead of bold #HWS: Generalize to include more symbols.
-#    $contents =~ s/^\$(\s*($html_specials_inv_rx|$allow)*\s*)\$(.)?/
-#      $next=$3;&simple_math_env($1).(($next =~ m|\w|)? " ":'').$next/ige;
-    $contents =~ s/^\$(\s*($html_specials_inv_rx|$allow)*\s*)\$$/
-       &simple_math_env($1)." "/ige;
-    if ($contents =~ /\&\w*;/) { $has_math_chars=1 }
-    if ($contents =~ /;SPM([a-zA-Z]+);/) { $has_special_chars=1 };
-}
-
-# Translate simple math environments into italic.
-# Only letters should become italic; symbols should stay non-italic.
-sub simple_math_env {
-    local($mathcontents) = @_;
-    if ($mathcontents eq '') { return("$mathcontents"); }
-    elsif ($NO_SIMPLE_MATH) {  # always make an image
-       $failed = 1; return($mathcontents);
-    } elsif ($mathcontents =~ /\\/) { # any macro kills "simple-math"
-       local($save_math) = $mathcontents;
-       local(@text_only) = ();
-       while ((!$failed)&&($mathcontents =~
-               /\\((boldsymbol|bm)|(math|text)(bf|rm|it|tt)|times|[{}@#^_])(\b|[^A-Za-z]|$)/)) {
-           # ...except when only simple styles
-           push (@text_only, $`, ("$2$4" ? "\\simplemath".($4 ? $4 :"bf") :"\\$1") );
-           $mathcontents = $5.$';
-           $failed = 1 if ($` =~ /\\/);
-       }
-       $failed = 1 if ($mathcontents =~ /\\/);
-       return($save_math) if $failed;
-       $mathcontents = join('',@text_only,$mathcontents);
-    }
-    # Is there a problem here, with nested super/subscripts ?
-    # Yes, so do each pattern-match for bracketings within a while-loop
-    while ($mathcontents =~ s/\^$any_next_pair_rx/<SUP>$2<\/SUP>/go){};
-    while ($mathcontents =~ s/\^$any_next_pair_pr_rx/<SUP>$2<\/SUP>/go){};
-    while ($mathcontents =~ s/_$any_next_pair_rx/<SUB>$2<\/SUB>/g){};
-    while ($mathcontents =~ s/_$any_next_pair_pr_rx/<SUB>$2<\/SUB>/g){};
-
-    $mathcontents =~ s/\^(\\[a-zA-Z]+|.)/<SUP>$1<\/SUP>/g;
-    $mathcontents =~ s/_(\\[a-zA-Z]+|.)/<SUB>$1<\/SUB>/g;
-    $mathcontents =~ s/(^|\s|[,;:'\?\.\[\]\(\)\+\-\=\!>]|[^\\<]\/|\d)(<(I|TT|B)>)?([a-zA-Z]([a-zA-Z ]*[a-zA-Z])?)(<\/\3>)?/
-       $1.(($2)? $2 :'<I>').$4.(($6)? $6 : '<\/I>')/eig;
-
-    $mathcontents =~ s/\\times($|\b|[^A-Za-z])/ x $1/g;
-    $mathcontents =~ s/\\times($|\b|[^A-Za-z])/ x $1/g;
-    $mathcontents =~ s/\\\\/<BR>\n/g;
-    $mathcontents =~ s/\\\\/<BR>\n/g;
-    $mathcontents =~ s/\\([,;])/ /g;
-    $mathcontents =~ s/\\(\W)/$1/g;
-    $mathcontents =~ s/ {2,}/ /g;
-
-    # any simple style changes remove enclosed <I> tags
-    $mathcontents = &translate_commands($mathcontents)
-       if ($mathcontents =~ /\\/);
-
-    $mathcontents =~ s/<I><\/(SUB|SUP)>/<\/$1><I>/g;
-    $mathcontents =~ s/<(SUB|SUP)><\/I>/<\/I><$1>/g;
-    $mathcontents =~ s/;<I>SPM([a-zA-Z]+)<\/I>;/;SPM$1;/go;
-    $mathcontents =~ s/<(\/?)<I>(SUB|SUP|I|B|TT)<\/I>>/<$1$2>/g;
-    $mathcontents =~ s/<\/(B|I|TT)><\1>//g;
-    $mathcontents;
-}
-
-sub do_cmd_simplemathrm { 
-    local ($_) = @_;
-    local($text);
-    $text = &missing_braces unless (
-        (s/$next_pair_pr_rx/$text = $2;''/e)
-        ||(s/$next_pair_rx/$text = $2;''/e));
-    $text =~ s/<\/?I>//g;
-    join('', $text, $_)
-}
-sub do_cmd_simplemathbf { 
-    local ($_) = @_;
-    local($text);
-    $text = &missing_braces unless (
-        (s/$next_pair_pr_rx/$text = $2;''/e)
-        ||(s/$next_pair_rx/$text = $2;''/e));
-    $text =~ s/<\/?I>//g;
-    join('','<B>', $text, '</B>', $_)
-}
-sub do_cmd_simplemathtt {
-    local ($_) = @_;
-    local($text);
-    $text = &missing_braces unless (
-        (s/$next_pair_pr_rx/$text = $2;''/e)
-        ||(s/$next_pair_rx/$text = $2;''/e));
-    $text =~ s/<\/?I>//g;
-    join('','<TT>', $text, '</TT>', $_)
-}
-
-sub process_math_in_latex {
-    local($mode,$style,$level,$math) = @_;
-    local(@anchors);
-    if ($level) {
-       $style = (($level > 1) ? "script" : "") . "script";
-    } elsif (! $style) { 
-       $style = (($mode =~/display|equation/)? "display" : "")
-    }
-    $style = "\\${style}style" if ($style);
-
-    #  &process_undefined_environment  changes $_ , so save it.
-    local($after) = $_;
-
-    # the 'unless' catches nested AMS-aligned environments
-    $mode = "tex2html_wrap_" .
-       (($mode =~/display|equation|eqnarray/) ? 'indisplay' : 'inline')
-           unless ($mode =~ /^equationstar/ && $outer_math =~ /^equationstar/);
-
-    $global{'max_id'}++;
-    $math =~ s/\\(\n|$)/\\ $1/g;       # catch \ at end of line or string
-    $math =~ s/^\s*((\\!|;SPMnegsp;)\s*)*//g;          # remove neg-space at start of string
-    if ($mode =~ /tex2html_wrap_/ ) {
-       $math = &process_undefined_environment( $mode
-           , $global{'max_id'}, join('', "\$$style ", $math, "\$"));
-    } else {
-       # some AMS environments must be within {equation} not {displaymath}
-       $math =~ s/displaymath/equation*/
-               if ($math =~ /\\begin\{(x+|fl)*align/);
-       $math = &process_undefined_environment($mode, $global{'max_id'}, $math);
-    }
-    $math .= "\n" if ($math =~ /$comment_mark\s*\d+$/s);
-    $_ = $after;
-    # the delimiter \001 inhibits an unwanted \n at image-replacement
-    $math . ($math =~ /$image_mark/? "\001" : '');
-}
-     
-#RRM: Explicit font switches need images. Use the image_switch mechanism.
-sub do_cmd_font {
-    local($_) = @_;
-    local($fontinfo,$fontname,$size) = ('','','10pt');
-    s/\s*\\(\w+)\s*=?\s*(.*)(\n|$)/$fontname=$1;$fontinfo=$2;''/eo;
-    $image_switch_rx .= "|$fontname";
-
-    if ($fontinfo =~ /([.\d]+\s*(true)?(pt|mm|cm))/ ) { $size = $1 }
-    elsif ( $fontinfo =~ /[a-zA-Z]+(\d+)\b/ ) { $size = $1.'pt' }
-    if  ( $fontinfo =~ /(scaled|at)\s*\\?(.+)/) { $size .= " scaled $1" }
-    $font_size{$fontname} = $size;
-    $_;
-}
-sub wrap_cmd_font {
-    local($cmd, $_) = @_;
-    local ($args, $dummy, $pat) = "";
-    if (/\n/) { $args .= $`.$& ; $_ = $' } else {$args = $_; $_ = ''};
-    (&make_deferred_wrapper(1).$cmd.$padding.$args.&make_deferred_wrapper(0),$_)
-}
-
-sub do_cmd_newfont {
-    local($_) = @_;
-    local($fontinfo,$fontname,$size) = ('','','10pt');
-    $fontname = &missing_braces unless (
-       (s/$next_pair_pr_rx/$fontname=$2;''/eo)
-       ||(s/$next_pair_rx/$fontname=$2;''/eo));
-    $fontname=~ s/^\s*\\|\s*$//g;
-    $image_switch_rx .= "|$fontname";
-
-    $fontinfo = &missing_braces unless (
-       (s/$next_pair_pr_rx/$fontinfo=$2;''/eo)
-       ||(s/$next_pair_rx/$fontinfo=$2;''/eo));
-    if ($fontinfo =~ /([.\d]+\s*(true)?(pt|mm|cm))/ ) { $size = $1 }
-    elsif ( $fontinfo =~ /[a-zA-Z]+(\d+)\b/ ) { $size = $1.'pt' }
-    if  ( $fontinfo =~ /(scaled|at)\s*\\?(.+)/) { $size .= " scaled $1" }
-    $font_size{$fontname} = $size;
-    $_;
-}
-
-sub defined_env {
-    local($env) = @_;
-    $env =~ s/\*$/star/;
-    local($env_sub) = ("do_env_$env");
-    # The test using declarations should not be necessary but 'defined'
-    # doesn't seem to recognise subroutines generated dynamically using 'eval'.
-    # Remember that each entry in $declarations generates a dynamic prodedure ...
-    ((defined &$env_sub) || ($declarations{$env}));
-}
-
-# RRM: utility to add style information to stored image-parameters
-#      currently only (math) scaling info is included;
-#      current color, etc.  could also be added here.
-sub addto_encoding {
-    local($env, $contents) = @_;
-#    $contents =~ s/(\\(begin|end)\s*)?<<\d*>>|\n//g;  # RRM: remove env delimiters
-    $contents =~ s/(\\(begin|end)\s*(<<\d*>>))|\n//g;  # RRM: remove env delimiters
-    # append scaling information for environments using it
-    if (($MATH_SCALE_FACTOR)
-       &&(($contents =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/)
-          ||($env =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/))
-       ) { $contents .= ";MSF=$MATH_SCALE_FACTOR" }
-
-    if ($LATEX_FONT_SIZE =~ /([\d\.]+)pt/) {
-       local($fsize) = $1;
-       $contents .= ";LFS=$fsize" unless ($fsize ==10);
-    }
-
-    if (($EXTRA_IMAGE_SCALE)
-       &&(($contents =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/)
-          ||($env =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/))
-       ) { $contents .= ";EIS=$EXTRA_IMAGE_SCALE" }
-
-    if (($DISP_SCALE_FACTOR)
-       &&(($contents =~ /indisplay|displaymath|eqnarray|equation/)
-          ||($env =~ /indisplay|displaymath|eqnarray|equation/))
-       &&!(($contents =~ /makeimage/)||($env =~ /makeimage/))
-       ) { $contents .= ";DSF=$DISP_SCALE_FACTOR" }
-
-    if (($EQN_TAGS)
-       &&(($env =~ /eqnarray($|[^_\*])|equation/)
-          ||($contents =~ /eqnarray($|[^_\*])|equation/))
-       &&!(($contents =~ /makeimage/)||($env =~ /makeimage/))
-       ) { $contents .= ";TAGS=$EQN_TAGS" }
-
-    if (($FIGURE_SCALE_FACTOR)
-       &&!(($contents =~ /makeimage/)||($env =~ /makeimage/))
-       &&(($contents =~ /figure/)||($env =~ /figure/))
-       ) { $contents .= ";FSF=$FIGURE_SCALE_FACTOR"}
-
-    if (($ANTI_ALIAS)
-       &&(($contents =~ /figure/)||($env =~ /figure/))
-       &&!(($contents =~ /makeimage/)||($env =~ /makeimage/))
-       ) { $contents .= ";AAF" }
-    elsif ($ANTI_ALIAS_TEXT) { $contents .= ";AAT" }
-    if (!$TRANSPARENT_FIGURES) { $contents .= ";NTR" }
-
-    $contents;
-}
-
-sub process_undefined_environment {
-    local($env, $id, $contents) = @_;
-    if ($env =~ s/\*{2,}/*/) { print "\n*** $_[0] has too many \*s ***"};
-
-    local($name,$cached,$raw_contents,$uucontents) = ("$env$id");
-    $name =~ s/\*/star/;
-    local($oldimg,$size,$fullcontents,$imgID);
-    return if ($AUX_FILE);
-
-    # catch \footnotemark within an image, especially if in math
-    local(@foot_anchors,$foot_anchor);
-    local($im_footnote,$im_mpfootnote) = ($global{'footnote'},$global{'mpfootnote'});
-    @foot_anchors = &process_image_footnote($contents)
-       if ($contents =~ /\\footnote(mark)?\b/s);
-    if ((@foot_anchors)&&($eqno)) {
-       # append the markers to the equation-numbers
-       $eqno .= join(' ', ' ', @foot_anchors);
-       @foot_anchors = ();
-    }
-    
-    print STDOUT "\nUNDEF-IN {$env $id}:\n$contents\n" if ($VERBOSITY > 4);
-    #RRM - LaTeX commands wrapped with this environment go directly into images.tex.
-    if ($env =~ /tex2html_nowrap|^lrbox$/){ # leave off the wrapper, do not cache
-       # totally ignore if in preamble...
-       # ...since it will be put into  images.tex  anyway!!
-       if (!($PREAMBLE)) {
-           $contents =~ s/^\n+|\n+$/\n/g;
-           local($lcontents) = join('', "\\begin{$env}", $contents , "\\end{$env}" );
-           $lcontents =~ s/\\(index|label)\s*(($O|$OP)\d+($C|$CP)).*\2//sg;
-           print STDOUT "pre-LATEX {$env}:\n$lcontents\n" if ($VERBOSITY > 3);
-           $raw_contents = &revert_to_raw_tex($lcontents);
-           print STDOUT "LATEX {$env}:\n$raw_contents\n" if ($VERBOSITY > 3);
-           $latex_body .= "\n$raw_contents"."%\n\n" ;
-       }
-       return("") if ($env =~ /^lrbox/);
-       # ignore enclosed environments; e.g. in  \settolength  commands
-#      $contents = &translate_environments($contents); # ignore environments
-#      $contents = &translate_commands($contents);
-       # ...but apply any Perl settings that may be defined
-       $contents = &process_command($single_cmd_rx,$contents);
-       print STDOUT "\nOUT {$env $id}:\n$contents\n" if ($VERBOSITY > 4);
-       return("");
-    }
-    # catch pre-processor environments
-    if ($PREPROCESS_IMAGES) {
-       local($pre_env,$which, $done, $indic);
-       while ($contents =~ /$pre_processor_env_rx/) {
-           $done .= $`; $pre_env = $5; $which =$1; $contents = $';
-           if (($which =~ /begin/)&&($pre_env =~ /indica/)) {
-               if ($contents =~ s/^\[(\w+)]//o) { $done .= '#'.$1 }
-           } elsif (($which =~ /end/)&&($pre_env =~ /indica/)) {
-               $done .= '#NIL';
-           } elsif (($which =~ /begin/)&&($pre_env =~ /itrans/)) {
-               if ($contents =~ s/^\[(\w+)]/$indic=$1;''/e)
-                   { $done .= "\#$indic" }
-           } elsif (($which =~ /end/)&&($pre_env =~ /itrans/)) {
-               $done .= "\#end$indic";
-           } elsif ($which =~ /begin/) {
-               $done .= (($which =~ /end/)? $end_preprocessor{$pre_env}
-                         : $begin_preprocessor{$pre_env} )
-           }
-       }
-       $contents = $done . $contents;
-    }
-    $fullcontents =  $contents; # save for later \label search.
-    # MRO: replaced $* with /m
-    $contents =~ s/\n?$labels_rx(\%([^\n]+$|$EOL))?/\n/gm;
-
-    local($tmp) = $contents;
-    $tmp =~ s/^((\\par|\%)?\s*\n)+$//g;
-    return( &do_labels($fullcontents, "\&nbsp;") ) unless $tmp;
-
-    # just a comment as the contents of a cell in a math-display
-    if ($tmp =~ /\$\\(display|text|(script)+)style\s*$comment_mark\d+\s*\$$/)
-       { return ( &do_labels($fullcontents, "\&nbsp;") ) };
-
-    $contents = "\n% latex2html id marker $id\n$contents" if
-       (!$PREAMBLE &&($contents =~ /$order_sensitive_rx/)
-               &&(!($env =~ /makeimage/)));
-
-    $env =~ s/displaymath/equation*/
-       if ($contents =~ /\\begin\{(x+|fl)*align/);
-    #RRM: include the inline-color, when applicable
-    $contents = join(''
-           , (($inner_math =~ /in(display|line)/) ? '$' : '')
-           , "\\begin{$env}"
-           , ($color_env ? "\\bgroup\\$color_env" : '')
-           , $contents , ($color_env ? "\\egroup" : '')
-           , "\\end{$env}"
-           , (($inner_math =~ /in(display|line)/) ? '$' : '')
-       ) if ($contents);
-
-    # append to the name of special environments found within math
-    if ($inner_math) {
-       local($ext) = $inner_math;
-       if ($inner_math =~ /(display|line)/){ $ext = 'in'.$1;};
-       $name =~ s/(\d+)$/_$ext$1/;
-    }
-
-    if (!($latex_body{$name} = $contents)) {
-       print "\n *** code for $name is too long ***\n"}
-    if ($contents =~ /$htmlimage_rx/) {
-       $uucontents = &special_encoding($env,$2,$contents);
-    } elsif ($contents =~ /$htmlimage_pr_rx/) {
-       $uucontents = &special_encoding($env,$2,$contents);
-    } else {
-       $uucontents = &encode(&addto_encoding($env,$contents));
-    }
-    $cached = $cached_env_img{$uucontents};
-    print STDOUT "\nCACHED: $uucontents:\n$cached\n" if ($VERBOSITY > 4);
-    if ($NOLATEX) { 
-       $id_map{$name} = "[$name]";
-    } elsif (defined ($_ = $cached)) { # Is it in our cache?
-       # Have we already used it?
-       if (($oldimg) = /SRC="$PREFIX$img_rx\.$IMAGE_TYPE"/o) {
-           # No, check its size
-           local($eis) = 1;
-           # Does it have extra scaling ?
-           if ($uucontents =~ /EIS=(.*);/) { $eis = $1 }
-           ($size, $imgID) = &get_image_size("$PREFIX$oldimg.old", $eis);      
-           # Does it have extra scaling ?
-#          if ($uucontents =~ /EIS=(.*);/) {
-#              local($eis) = $1; local($w,$h);
-#              # quotes will not be there with HTML 2.0
-#              $size =~ s/(WIDTH=\")(\d*)(\".*HEIGHT=\")(\d*)\"/
-#                  $w = int($2\/$eis + .5); $h=int($4\/$eis + .5);
-#                  "$1$w$3$h\""/e ; # insert the re-scaled size
-#          }
-           # quotes will not be there with HTML 2.0
-           $size =~ s/\"//g if ($HTML_VERSION < 2.2);
-           if ($size && /\s$size\s/) {
-               # Size is OK; recycle it!
-               ++$global_page_num;
-               $_ = $cached ;    # ...perhaps restoring the desired size.
-               s/(${PREFIX}T?img)\d+\.($IMAGE_TYPE|html)/
-                       &rename_html($&,"$1$global_page_num.$2")/geo;
-           } else {
-               if ($env =~ /equation/) { &extract_eqno($name,$cached) }
-               $_ = "";                                # The old Image has wrong size!
-               undef($cached);                 #  (or it doesn't exist)
-           }
-       }
-       s/(IMG\n)/$1$imgID/ if $imgID;
-
-       s/$PREFIX$img_rx\.new/$PREFIX$1.$IMAGE_TYPE/go; # Point to the actual image file(s)
-       $id_map{$name} = $_;
-       s/$PREFIX$img_rx\.$IMAGE_TYPE/$PREFIX$1.new/go; # But remember them as used.
-       $cached_env_img{$uucontents} = $_;
-    }
-
-    if (! defined($cached)) {                          # Must generate it anew.
-       &clear_images_dbm_database
-           unless ($new_page_num ||($NO_SUBDIR && $FIXEDDIR));
-       $new_id_map{$name} = $id_map{$name} = ++$global_page_num . "#" .
-           ++$new_page_num;
-       $orig_name_map{$id_map{$name}} = $name;
-       $cached_env_img{$uucontents} = $id_map{$name} if ($REUSE == 2);
-
-       #RRM: this (old) code frequently crashes NDBM, so do it in 2 steps
-#      $img_params{$name} = join('#', &extract_parameters($contents));
-       local(@params) = &extract_parameters($contents);
-       $img_params{$name} = join('#',@params); undef $params;
-       print "\nIMAGE_PARAMS $name: ".$img_params{$name} if ($VERBOSITY > 3);
-
-       $contents =~ s/\\(index|label)\s*(($O|$OP)\d+($C|$CP)).*\2//sg;
-       print STDOUT "\nLATEX {$env}:\n$contents" if ($VERBOSITY > 3);
-       $raw_contents = &revert_to_raw_tex($contents) unless ($contents =~ /^\s*$/) ;
-       $raw_contents =~ s/\\pagebreak|\\newpage|\\clearpage/\\\\/go;
-       print STDOUT "\nLATEX {$env}:\n$raw_contents\n" if ($VERBOSITY > 3);
-       local($box_type) = '';
-       if ($raw_contents =~ /\\special\s*\{/) { 
-           $tex_specials{$name} = "1";
-           &write_warnings("\nenvironment $name contains \\special commands");
-           print STDOUT "\n *** environment $name contains \\special commands ***\n"
-               if ($VERBOSITY);
-       } elsif (($env =~ /$inline_env_rx/)||($inner_math =~ /in(line|display)/)) {
-           # crop to the marks only... or shave a bit off the bottom
-           if (($env =~ /tex2html_[^w]/)||$inner_math) {
-               # e.g. accents, indic  but not wrap
-               $crop{$name} = "bl";
-               $box_type = "i";                
-           } else {
-           # ...or shave a bit off the bottom as well
-               $crop{$name} = "bls";
-               $box_type = "h";
-           }
-       } elsif (($env =~ /(eqnarray|equation)(\*|star)/)||($inner_math)) {
-           # crop to minimum size...
-           $crop{$name} = "blrl";
-           $box_type = "v";
-       } elsif ($env =~ /(picture|tex2html_wrap)(\*|star)?/) {
-           # crop hbox to minimum size...
-           $crop{$name} = "";
-           $box_type = "p";
-       } elsif ($env =~ /$display_env_rx/) {
-           # crop vbox to minimum size...
-           $crop{$name} = "blrl" ;
-           if ($env =~ /(equation|eqnarray)((s)?$|\d)/) {
-               # ... unless equation numbers are included ...
-               if ($3) { #  AMS {subequations}
-                   $global{'eqn_number'}=$prev_eqn_number if $prev_eqn_number;
-                   --$global{'eqn_number'};
-               }
-               $raw_contents = join('' ,
-                   (($eqno{$name}||$global{'eqn_number'})?
-                     &set_equation_counter($eqno{$name}) : '')
-                   , $raw_contents);
-               $crop{$name} = "bl" ;
-           } elsif ($HTML_VERSION < 2.2) {
-               # ... HTML 2.0 cannot align images, so keep the full typeset width
-               $crop{$name} = "bl" ;           
-           }
-           $box_type = "v";
-       }
-       
-       #RRM: include the TeX-code for the appropriate type of box.
-       eval "\$raw_contents = \&make_$box_type"."box($name, \$raw_contents);";
-
-       # JCL(jcl-pag) - remember html text if debug is set.
-       local($_);
-       if ($DEBUG) {
-           $_ = $contents;
-           s/\n/ /g;
-           $_ = &revert_to_raw_tex($_);
-           # incomplete or long commented code can break pre-processors
-           if ($PREPROCESS_IMAGES) {
-               $_ = ((/^(\\\w+)?\{[^\\\}\<]*\}?/)? $& : '').'...' ;
-               $_ = '{ ... }' if ( length($_) > 100);
-           } elsif ( length($_) > 200) {
-                   $_ = join('',substr($_,0,200),"...\}");
-           }
-           s/\\(begin|end)/$1/g; s/[\000-\020]//g;
-           $_ = join('',"% contents=",$_,"\n");
-       }
-       $raw_contents = '\setcounter{equation}{'.$prev_eqn_number."}\n".$raw_contents
-           if ($env =~ /subequations/);
-
-# JCL(jcl-pag) - build the page entries for images.tex:  Each page is embraced to
-# let most statements have only local effect. Each page must compile into a
-# single dvi page to get proper image translation. Hence the invisible glue to
-# get *at least* one page (raw_contents alone might not wield glue), and
-# sufficing page length to get *exactly* one page.
-#
-       $latex_body .= "{\\newpage\\clearpage\n$_" .
-#          "$raw_contents\\hfill\\vglue1pt\\vfill}\n\n";
-#          "$raw_contents\\hfill\\vss}\n\n" if ($raw_contents);
-#          "$raw_contents\\hfill\\lthtmlcheckvsize\\clearpage}\n\n" if ($raw_contents);
-           "$raw_contents\\lthtmlcheckvsize\\clearpage}\n\n" if ($raw_contents);
-    }
-    print STDOUT "\nIMAGE_CODE:{$env $id}:\n$raw_contents\n" if ($VERBOSITY > 4);
-
-    # Anchor the labels and put a marker in the text;
-    local($img) = &do_labels($fullcontents,"$image_mark#$name#");
-    print STDOUT "\nUNDEF_OUT {$env $id}:\n$img\n" if ($VERBOSITY > 4);
-    return($img) unless (@foot_anchors);
-
-    # use the image as source to the 1st footnote, unless it is already an anchor.
-    if ($img =~ /<\/?A>/) {
-       join(' ', $img, @foot_anchors);         
-    } elsif ($#foot_anchors ==0) {
-       $foot_anchor = shift @foot_anchors;
-       $foot_anchor =~ s/<SUP>.*<\/SUP>/$img/;
-#      join(' ', $foot_anchor, @foot_anchors);         
-       $foot_anchor;
-    } else {
-       join(' ', $img, @foot_anchors);         
-    }
-}
-
-sub special_encoding { # locally sets $EXTRA_IMAGE_SCALE
-    local($env,$_,$contents) = @_; 
-    local($exscale) = /extrascale=([\.\d]*)/;
-    local($EXTRA_IMAGE_SCALE) = $exscale if ($exscale);
-    &encode(&addto_encoding($env,$contents));
-}
-
-
-sub extract_eqno{
-    local($name,$contents) = @_;
-    if ($contents =~ /<P ALIGN="\w+">\(([^<>])\)<\/P>$/) {
-       if (($eqno{$name})&&!($eqno{$name} eq $1)) {
-           &write_warnings("\nequation number for $name may be wrong.")};
-       $eqno{$name}="$1";
-    }
-}
-sub set_equation_counter{
-    if ( $global{'eqn_number'}) {
-       "\\setcounter{equation}{". $global{'eqn_number'} ."}\n"
-    } else { "\\setcounter{equation}{0}\n" }
-}
-
-# RRM: 3 different types of boxing, for image environments.
-
-#      general environments --- crops to width & height
-sub make_box {
-    local($id,$contents) = @_;
-    "\\lthtmlfigureA{". $id ."}%\n". $contents ."%\n\\lthtmlfigureZ\n";
-}
-
-#      inline math --- horizontal mode, captures height/depth + \mathsurround
-sub make_hbox {
-    local($id,$contents) = @_;
-    if ($id =~ /indisplay/) {
-       "\\lthtmlinlinemathA{". $id ."}%\n". $contents ."%\n\\lthtmlindisplaymathZ\n";
-    } else {
-       "\\lthtmlinlinemathA{". $id ."}%\n". $contents ."%\n\\lthtmlinlinemathZ\n";
-    }
-}
-
-#      inline text-image (e.g. accents) --- horizontal mode, captures height/depth
-sub make_ibox {
-    local($id,$contents) = @_;
-    "\\lthtmlinlineA{". $id ."}%\n". $contents ."%\n\\lthtmlinlineZ\n";
-}
-
-#      centered images (e.g. picture environments) --- horizontal mode
-sub make_pbox {
-    local($id,$contents) = @_;
-    "\\lthtmlpictureA{". $id ."}%\n". $contents ."%\n\\lthtmlpictureZ\n";
-}
-
-#      displayed math --- vertical mode, captures height/depth + page-width
-sub make_vbox {
-    local($id,$contents) = @_;
-    if (($HTML_VERSION >=3.2)&&($id =~/(equation|eqnarray)($|\d)/) &&! $failed ) {
-       if ($contents =~ s/^\\setcounter\{equation\}\{\d+\}/$&%\n\\lthtmldisplayB\{$id\}%/)
-           { $contents ."%\n\\lthtmldisplayZ\n" }
-       else { "\\lthtmldisplayB{$id}%\n". $contents ."%\n\\lthtmldisplayZ\n" }
-    } else { "\\lthtmldisplayA{$id}%\n". $contents ."%\n\\lthtmldisplayZ\n"}
-}
-
-sub preprocess_images {
-    do {
-       print "\nWriting image.pre file ...\n";
-       open(ENV,">.$dd${PREFIX}images.pre")
-            || die "\nCannot write '${PREFIX}images.pre': $!\n";
-       print ENV &make_latex($latex_body);
-       print ENV "\n";
-       close ENV;
-       &copy_file($FILE, "bbl");
-       &copy_file($FILE, "aux");
-       local($num_cmds, $cnt, $this, @cmds);
-       @cmds = (split ('\n', $preprocessor_cmds));
-       $this_cmd = $num_cmds = 1+$#cmds;
-       $cnt = $num_cmds; $preprocessor_cmds = '';
-       while (@cmds) {
-           $this_cmd = shift @cmds; last unless ($this_cmd);
-           $this_cmd =~ s/.pre /.tex$cnt / if(($cnt)&&($cnt < $num_cmds));
-           $cnt--; $this_cmd .= $cnt if ($cnt);
-           $preprocessor_cmds .= $this_cmd."\n";
-           L2hos->syswait($this_cmd);
-       }
-       # save pre-processor commands in a file:  preproc
-       open(CMDS,">.$dd${PREFIX}preproc")
-            || die "\nCannot write '${PREFIX}preproc': $!\n";
-       print CMDS $preprocessor_cmds ;
-       close CMDS;
-
-    } if ((%latex_body) && ($latex_body =~ /newpage/));
-}
-sub make_image_file {
-    do {
-       print "\nWriting image file ...\n";
-       open(ENV,">.$dd${PREFIX}images.tex")
-            || die "\nCannot write '${PREFIX}images.tex': $!\n";
-       print ENV &make_latex($latex_body);
-       print ENV "\n";
-       close ENV;
-       &copy_file($FILE, "bbl");
-       &copy_file($FILE, "aux");
-    } if ((%latex_body) && ($latex_body =~ /newpage/));
-}
-
-sub make_latex_images{
-    &close_dbm_database if $DJGPP;
-    local($dd) = $dd; $dd = '/' if ($dd eq "\\"); 
-    local($latex_call) = "$LATEX .$dd${PREFIX}images.tex";
-    print "$latex_call\n" if (($DEBUG)||($VERBOSITY > 1));
-    L2hos->syswait($latex_call);
-    &open_dbm_database if $DJGPP;
-}
-
-sub make_off_line_images {
-    local($name, $page_num);
-    if (!$NOLATEX && -f ".${dd}${PREFIX}images.tex") {
-       &make_tmp_dir;  # sets  $TMPDIR  and  $DESTDIR
-       $IMAGE_PREFIX =~ s/^_//o if ($TMPDIR);
-
-       &make_latex_images();
-
-       print "\nGenerating postscript images using dvips ...\n";
-       &process_log_file(".$dd${PREFIX}images.log"); # Get eqn size info
-       unless ($LaTeXERROR) {
-           local($dvips_call) = 
-               "$DVIPS -S1 -i $DVIPSOPT -o$TMPDIR$dd${IMAGE_PREFIX} .${dd}${PREFIX}images.dvi";
-           print "$dvips_call\n" if (($DEBUG)||($VERBOSITY > 1));
-
-           &close_dbm_database if $DJGPP;
-           L2hos->syswait($dvips_call) && print "Error: $!\n";
-           undef $dvips_call;
-           &open_dbm_database if $DJGPP;
-
-           # add suffix .ps to the file-names for each image
-           if(opendir(DIR, $TMPDIR || '.')) {
-                #  use list-context instead; thanks De-Wei Yin <yin@asc.on.ca>
-               my (@ALL_IMAGE_FILES) = grep /^$IMAGE_PREFIX\d+$/o, readdir(DIR);
-               foreach (@ALL_IMAGE_FILES) {
-                       L2hos->Rename("$TMPDIR$dd$_", "$TMPDIR$dd$_.ps");
-               }
-               closedir(DIR);
-            } else {
-                print "\nError: Cannot read dir '$TMPDIR': $!\n";
-            }
-       }
-    }
-    if ($LaTeXERROR) {
-        print "\n\n*** LaTeXERROR\n"; return();
-    }
-
-    while ( ($name, $page_num) = each %new_id_map) {
-       # Extract the page, convert and save it
-       &extract_image($page_num,$orig_name_map{$page_num});
-    }
-}
-
-# Generate images for unknown environments, equations etc, and replace
-# the markers in the main text with them.
-# - $cached_env_img maps encoded contents to image URL's
-# - $id_map maps $env$id to page numbers in the generated latex file and after
-# the images are generated, maps page numbers to image URL's
-# - $page_map maps page_numbers to image URL's (temporary map);
-# Uses global variables $id_map and $cached_env_img,
-# $new_page_num and $latex_body
-
-
-sub make_images {
-    local($name, $contents, $raw_contents, $uucontents, $page_num,
-         $uucontents, %page_map, $img);
-    # It is necessary to run LaTeX this early because we need the log file
-    # which contains information used to determine equation alignment
-    if ( $latex_body =~ /newpage/) {
-       print "\n";
-       if ($LATEX_DUMP) {
-           # dump a pre-compiled format
-           if (!(-f "${PREFIX}images.fmt")) {
-               print "$INILATEX ./${PREFIX}images.tex\n" 
-                   if (($DEBUG)||($VERBOSITY > 1));
-               print "dumping ${PREFIX}images.fmt\n"
-                   unless ( L2hos->syswait("$INILATEX ./${PREFIX}images.tex"));
-           }
-           local ($img_fmt) = (-f "${PREFIX}images.fmt");
-           if ($img_fmt) {
-                # use the pre-compiled format
-               print "$TEX \"&./${PREFIX}images\" ./${PREFIX}images.tex\n"
-                   if (($DEBUG)||($VERBOSITY > 1));
-               L2hos->syswait("$TEX \"&./${PREFIX}images\" ./${PREFIX}images.tex");
-           } elsif (-f "${PREFIX}images.dvi") {
-               print "${PREFIX}images.fmt failed, proceeding anyway\n";
-           } else {
-               print "${PREFIX}images.fmt failed, trying without it\n";
-               print "$LATEX ./${PREFIX}images.tex\n"
-                   if (($DEBUG)||($VERBOSITY > 1));
-               L2hos->syswait("$LATEX ./${PREFIX}images.tex");
-           }
-       } else { &make_latex_images() }
-#          local($latex_call) = "$LATEX .$dd${PREFIX}images.tex";
-#          print "$latex_call\n" if (($DEBUG)||($VERBOSITY > 1));
-#          L2hos->syswait("$latex_call");
-##         print "$LATEX ./${PREFIX}images.tex\n" if (($DEBUG)||($VERBOSITY > 1));
-##         L2hos->syswait("$LATEX ./${PREFIX}images.tex");
-##        }
-       $LaTeXERROR = 0;
-       &process_log_file("./${PREFIX}images.log"); # Get image size info
-    }
-    if ($NO_IMAGES) {
-        my $img = "image.$IMAGE_TYPE";
-       my $img_path = "$LATEX2HTMLDIR${dd}icons$dd$img";
-       L2hos->Copy($img_path, ".$dd$img")
-            if(-e $img_path && !-e $img);
-    }
-    elsif ((!$NOLATEX) && ($latex_body =~ /newpage/) && !($LaTeXERROR)) {
-       print "\nGenerating postscript images using dvips ...\n";
-        &make_tmp_dir;  # sets  $TMPDIR  and  $DESTDIR
-       $IMAGE_PREFIX =~ s/^_//o if ($TMPDIR);
-
-       local($dvips_call) = 
-               "$DVIPS -S1 -i $DVIPSOPT -o$TMPDIR$dd$IMAGE_PREFIX .${dd}${PREFIX}images.dvi\n";
-       print $dvips_call if (($DEBUG)||($VERBOSITY > 1));
-       
-       if ((($PREFIX=~/\./)||($TMPDIR=~/\./)) && not($DVIPS_SAFE)) {
-           print " *** There is a '.' in $TMPDIR or $PREFIX filename;\n"
-               . "  dvips  will fail, so image-generation is aborted ***\n";
-       } else {
-           &close_dbm_database if $DJGPP;
-           L2hos->syswait($dvips_call) && print "Error: $!\n";
-           &open_dbm_database if $DJGPP;
-       }
-
-       # append .ps suffix to the filenames
-       if(opendir(DIR, $TMPDIR || '.')) {
-            # use list-context instead; thanks De-Wei Yin <yin@asc.on.ca>
-           my @ALL_IMAGE_FILES = grep /^$IMAGE_PREFIX\d+$/o, readdir(DIR);
-           foreach (@ALL_IMAGE_FILES) {
-               L2hos->Rename("$TMPDIR$dd$_", "$TMPDIR$dd$_.ps");
-           }
-           closedir(DIR);
-        } else {
-            print "\nError: Cannot read dir '$TMPDIR': $!\n";
-        }
-    }
-    do {print "\n\n*** LaTeXERROR"; return()} if ($LaTeXERROR);
-    return() if ($LaTeXERROR); # empty .dvi file
-    L2hos->Unlink(".$dd${PREFIX}images.dvi") unless $DEBUG;
-
-    print "\n *** updating image cache\n" if ($VERBOSITY > 1);
-    while ( ($uucontents, $_) = each %cached_env_img) {
-       delete $cached_env_img{$uucontents}
-           if ((/$PREFIX$img_rx\.$IMAGE_TYPE/o)&&!($DESTDIR&&$NO_SUBDIR));
-       $cached_env_img{$uucontents} = $_
-           if (s/$PREFIX$img_rx\.new/$PREFIX$1.$IMAGE_TYPE/go);
-    }
-    print "\n *** removing unnecessary images ***\n" if ($VERBOSITY > 1);
-    while ( ($name, $page_num) = each %id_map) {
-       $contents = $latex_body{$name};
-       if ($page_num =~ /^\d+\#\d+$/) { # If it is a page number
-           do {                # Extract the page, convert and save it
-               $img = &extract_image($page_num,$orig_name_map{$page_num});
-               if ($contents =~ /$htmlimage_rx/) {
-                   $uucontents = &special_encoding($env,$2,$contents);
-               } elsif ($contents =~ /$htmlimage_pr_rx/) {
-                   $uucontents = &special_encoding($env,$2,$contents);
-               } else {
-                   $uucontents = &encode(&addto_encoding($contents,$contents));
-               }
-               if (($HTML_VERSION >=3.2)||!($contents=~/$order_sensitive_rx/)){
-                   $cached_env_img{$uucontents} = $img;
-               } else {
-                    # Blow it away so it is not saved for next time
-                   delete $cached_env_img{$uucontents};
-                   print "\nimage $name not recycled, contents may change (e.g. numbering)";
-               }
-               $page_map{$page_num} = $img;
-           } unless ($img = $page_map{$page_num}); # unless we've just done it
-           $id_map{$name} = $img;
-       } else {
-           $img = $page_num;   # it is already available from previous runs
-       }
-       print STDOUT " *** image done ***\n" if ($VERBOSITY > 2);
-    }
-    &write_warnings(
-                   "\nOne of the images is more than one page long.\n".
-                   "This may cause the rest of the images to get out of sync.\n\n")
-       if (-f sprintf("%s%.3d%s", $IMAGE_PREFIX, ++$new_page_num, ".ps"));
-    print "\n *** no more images ***\n"  if ($VERBOSITY > 1);
-    # MRO: The following cleanup seems to be incorrect: The DBM is
-    # still open at this stage, this causes a lot of unlink errors
-    #
-    #do { &cleanup; print "\n *** clean ***\n"  if ($VERBOSITY > 1);}
-    #  unless $DJGPP;
-}
-
-# MRO: This copies the navigation icons from the distribution directory
-# or an alternative specified in $ALTERNATIVE_ICONS
-# to the document directory.
-
-sub copy_icons {
-    local($icon,$_);
-    print "\nCopying navigation icons ...";
-    foreach (keys %used_icons) {
-       # each entry ends in gif or png
-       if ($ALTERNATIVE_ICONS) {
-           L2hos->Copy("$ALTERNATIVE_ICONS$dd$_", ".$dd$_")
-               if (-e "$ALTERNATIVE_ICONS$dd$_" && !-e $_);
-       } elsif (/(gif|png)$/) {
-           L2hos->Copy("$LATEX2HTMLDIR${dd}icons$dd$_", ".$dd$_")
-               if (-e "$LATEX2HTMLDIR${dd}icons$dd$_" && !-e $_);
-       }
-    }
-}
-
-sub process_log_file {
-    local($logfile) = @_;
-    local($name,$before,$lengthsfound);
-    local($TeXpt)= 72/72.27;
-    local($image_counter);
-    open(LOG, "<$logfile") || die "\nCannot read logfile '$logfile': $!\n";
-    while (<LOG>) {
-        if (/Overfull/) { $before .= $_ }
-        elsif (/latex2htmlLength ([a-zA-Z]+)=(\-?[\d\.]+)pt/) {
-           ${$1} = 0.0+$2; $lengthsfound = 1;
-       } elsif (/latex2htmlSize|l2hSize/) {
-           /:([^:]*):/;
-           $name = $1; $name =~ s/\*//g;
-           ++$image_counter;
-           s/:([0-9.]*)pt/$height{$name} = $1*$TeXpt;''/e;
-           s/::([0-9.]*)pt/$depth{$name} = $1*$TeXpt;''/e;
-           s/::([0-9.]*)pt/$width{$name} = $1*$TeXpt;''/e;
-           s/\((.*)\)/$eqno{$name} = 1+$1;''/e;
-           if ($before) {
-               local($tmp);
-               if ($before =~ /hbox\s*\((\d+\.?\d*)pt/) {
-                   $width{$name} = $width{$name}+$1*$TeXpt;
-               }
-               if ($before =~ /vbox\s*\((\d+\.?\d*)pt/) {
-                   $height{$name} = $height{$name}+$1*$TeXpt;
-               }
-               $before = '';
-           }
-       }
-    $LaTeXERROR = 1 if (/^No pages of output./);
-    }
-
-    if ($LaTeXERROR) {
-       print STDERR "\n\n *** LaTeX produced no output ***\n"
-           . " *** no new images can be created\n"
-           . " *** Examine the  images.log  file.\n\n";
-       return;
-    }
-    print STDOUT "\n *** processing $image_counter images ***\n";
-    print STDOUT "\n *** LATEX LOG OK. ***\n" if ($VERBOSITY > 1);
-
-    if ($lengthsfound) {
-       $ODD_HMARGIN  = $hoffset + $oddsidemargin;
-       $EVEN_HMARGIN = $hoffset + $evensidemargin;
-       $VMARGIN = $voffset + $topmargin + $headheight + $headsep;
-        if ($dvi_mag >0 && $dvi_mag != 1000) {
-           $ODD_HMARGIN = int($dvi_mag /1000 * $ODD_HMARGIN);
-           $EVEN_HMARGIN = int($dvi_mag /1000 * $EVEN_HMARGIN);
-           $VMARGIN = int($dvi_mag /1000 * $VMARGIN);
-       }
-    } else {
-       $ODD_HMARGIN = 0;
-       $EVEN_HMARGIN = 0;
-       $VMARGIN = 0;
-    }
-    $ODD_HMARGIN  = int($ODD_HMARGIN*$TeXpt  + 72.5);
-    $EVEN_HMARGIN = int($EVEN_HMARGIN*$TeXpt + 72.5);
-    $VMARGIN = int($VMARGIN*$TeXpt + 72.5);
-    close(LOG);
-}
-
-sub extract_image { # clean
-    my ($page_num,$name) = @_;
-
-    # The followin come out of %img_params
-    my ($scale, $external, $thumbnail, $map, $psimage, $align, $usemap,
-         $flip, $aalias, $trans, $exscale, $alt, $exstr);
-
-    my ($lwidth, $val) = (0, '');
-    my ($custom_size,$color_depth,$height,$width,$croparg);
-
-    print STDOUT "\nextracting $name as $page_num\n" if ($VERBOSITY > 1);
-    # $global_num identifies this image in the original source file
-    # $new_num identifies this image in images.tex
-    my ($global_num, $new_num) = split(/#/, $page_num);
-    $name =~ s/\*/star/;
-    my ($env,$basename,$img) = ($name,"img$global_num",'');
-    $env =~ s/\d+$//;
-    $psname = sprintf("%s%.3d", "$TMPDIR$dd$IMAGE_PREFIX", $new_num);
-    if ( $EXTERNAL_IMAGES && $PS_IMAGES ) {
-       $img =  "$basename.ps";
-       L2hos->Copy("$psname.ps", "${PREFIX}$img");
-    } else {
-       $img = "$basename.$IMAGE_TYPE";
-       ($scale, $external, $thumbnail, $map, $psimage, $align, $usemap, 
-           $flip, $aalias, $trans, $exscale, $alt, $exstr) =
-            split('#', $img_params{$name});
-       $lwidth = ($align =~ s/nojustify/middle/) ? 0 : $LINE_WIDTH;
-       $alt = "ALT=\"$name\"" unless $alt;
-       $exscale = $EXTRA_IMAGE_SCALE unless($exscale);
-       if ($NO_IMAGES) {
-           L2hos->Symlink("image.$IMAGE_TYPE", "${PREFIX}$img");
-           if ($thumbnail) {
-               L2hos->Symlink("image.$IMAGE_TYPE", "${PREFIX}T$img");
-               $thumbnail = "${PREFIX}T$img";
-           }
-       } else {
-           # RRM: deal with size data
-           if ($width{$name} < 0) {
-               if ($exscale && $PK_GENERATION) {
-                   $height = int(                              
-                       $exscale*$height{$name}+        
-                       $exscale*$depth{$name} +.5);
-                   $width = int($exscale*$width{$name}-.5);
-               } else {
-                   $height = int($height{$name}+$depth{$name}+.5);
-                   $width = int($width{$name}-.5);
-               }
-               $custom_size = "${width}x$height";
-           } elsif ($width{$name}) {
-               if ($exscale && $PK_GENERATION) {
-                   $height = int( $height{$name} * $exscale +
-                       $depth{$name} * $exscale +.5);
-                   $width = int($width{$name} * $exscale +.5);
-               } else {
-                   $height = int($height{$name}+$depth{$name}+.5);
-                   $width = int($width{$name}+.5);
-               }
-               $custom_size = "${width}x$height";
-            } else {
-               $custom_size = '';
-           }
-            # MRO: add first overall crop
-           $croparg = '-crop a' . ($crop{$name} || '') . ' ';
-           $page_num  =~ s/^\d+#//o;
-           $custom_size .= " -margins "
-               . (($page_num % 2) ? $ODD_HMARGIN:$EVEN_HMARGIN)
-               . ",$VMARGIN" if ($custom_size);
-
-           #RRM: \special commands may place ink outside the expected bounds:
-           $custom_size = '' if ($tex_specials{$name});
-
-           # MRO: Patches for image conversion with pstoimg
-           # RRM: ...with modifications and fixes
-           L2hos->Unlink("${PREFIX}$img");
-           &close_dbm_database if $DJGPP;
-            print "Converting image #$new_num\n";
-
-           if ( ($name =~ /figure/) || $psimage || $scale || $thumbnail) {
-               $scale = $FIGURE_SCALE_FACTOR unless ($scale);
-               print "\nFIGURE: $name scaled $scale  $aalias\n" if ($VERBOSITY > 2);
-               (L2hos->syswait( "$PSTOIMG -type $IMAGE_TYPE "
-               . ($DEBUG ? '-debug ' : '-quiet ' )
-               . ($TMPDIR ? "-tmp $TMPDIR " : '' )
-               . (($DISCARD_PS && !$thumbnail && !$psimage)? "-discard " :'')
-               . (($INTERLACE) ? "-interlace " : '' )
-               . (((($ANTI_ALIAS)||($aalias))&&($aalias !~ /no|text/))? "-antialias ":'')
-               . (($ANTI_ALIAS_TEXT||(($aalias =~/text/)&&($aalias !~/no/)))?
-                       "-aaliastext ":'') 
-               . (($custom_size) ? "-geometry $custom_size ": '' )
-               . $croparg
-               . ($color_depth || '')
-               . (($flip) ? "-flip $flip " : '' )
-               . (($scale > 0) ? "-scale $scale " : '' )
-               . (((($TRANSPARENT_FIGURES && ($env =~ /figure/o))||($trans))
-                    &&(!($trans =~ /no/))) ? "-transparent " : '')
-               . (($WHITE_BACKGROUND) ? "-white " : '' )
-               . "-out ${PREFIX}$img $psname.ps"
-               ) ) # ||!(print "\nWriting image: ${PREFIX}$img"))
-                   && print "\nError while converting image: $!\n";
-
-               if ($thumbnail) { # $thumbnail contains the reduction factor
-                   L2hos->Unlink("${PREFIX}T$img");
-                   print "\nIMAGE thumbnail: $name" if ($VERBOSITY > 2);
-                   (L2hos->syswait( "$PSTOIMG -type $IMAGE_TYPE "
-                   . ($DEBUG ? '-debug ' : '-quiet ' )
-                   . ($TMPDIR ? "-tmp $TMPDIR " : '' )
-                   . (($DISCARD_PS && !$psimage) ? "-discard " : '' )
-                   . (($INTERLACE) ? "-interlace " : '' )
-                   . ((($ANTI_ALIAS||($aalias))&&(!($aalias =~/no/)))? "-antialias " :'')
-                   . (($ANTI_ALIAS_TEXT||(($aalias =~/text/)&&($aalias !~/no/)))?
-                       "-aaliastext ":'') 
-                   . (($custom_size) ? "-geometry $custom_size " : '' )
-                   . ($color_depth || '')
-                   . (($flip) ? "-flip $flip " : '' )
-                   . (($thumbnail > 0) ? "-scale $thumbnail " : '' )
-                   . ((($trans)&&(!($trans =~ /no/))) ? "-transparent " : '')
-                   . (($WHITE_BACKGROUND) ? "-white " : '' )
-                   . "-out ${PREFIX}T$img $psname.ps"
-                   ) ) # ||!(print "\nWriting image: ${PREFIX}T$img"))
-                       && print "\nError while converting thumbnail: $!\n";
-                   $thumbnail = "${PREFIX}T$img";
-               }
-           } elsif (($exscale &&(!$PK_GENERATION))&&($width{$name})) {
-               my $under = '';
-               my $mathscale = ($MATH_SCALE_FACTOR > 0) ? $MATH_SCALE_FACTOR : 1;
-               if (($DISP_SCALE_FACTOR > 0) &&
-                   ( $name =~ /equation|eqnarray|display/))
-                       { $mathscale *= $DISP_SCALE_FACTOR; };
-               if ($scale) {
-                   $scale *= $exscale if ($name =~ /makeimage|tab/);
-               } else {
-                   $scale = $mathscale*$exscale;
-                   $under = "d" if (($name =~/inline|indisplay/)&&($depth{$name}));
-               }
-               print "\nIMAGE: $name  scaled by $scale \n" if ($VERBOSITY > 2);
-               (L2hos->syswait( "$PSTOIMG -type $IMAGE_TYPE "
-               . ($DEBUG ? '-debug ' : '-quiet ' )
-               . ($TMPDIR ? "-tmp $TMPDIR " : '' )
-               . (($DISCARD_PS)? "-discard " : '' )
-               . (($INTERLACE)? "-interlace " : '' )
-               . ((($ANTI_ALIAS_TEXT||($aalias))&&($aalias !=~/no/))? 
-                   "-antialias -depth 1 " :'')
-               . (($custom_size)? "-geometry $custom_size " : '' )
-                . $croparg
-               . (($scale != 1)? "-scale $scale " : '' )
-               . ((($exscale)&&($exscale != 1)&&
-                   !($ANTI_ALIAS_TEXT &&($LATEX_COLOR)))? 
-                       "-shoreup $exscale$under " :'')
-               . ((($TRANSPARENT_FIGURES ||($trans))
-                    &&(!($trans =~ /no/)))? "-transparent " : '')
-               . (($WHITE_BACKGROUND && !$TRANSPARENT_FIGURES) ? "-white " : '' )
-               . "-out ${PREFIX}$img $psname.ps"
-               ) ) # ||!(print "\nWriting image: ${PREFIX}$img"))
-                   && print "\nError while converting image: $!\n";
-           } else {
-               print "\nIMAGE: $name\n" if ($VERBOSITY > 2);
-               my $under = '';
-               my $mathscale = ($MATH_SCALE_FACTOR > 0) ? $MATH_SCALE_FACTOR : 1;
-               if (($DISP_SCALE_FACTOR > 0) &&
-                   ( $name =~ /equation|eqnarray|display/))
-                       { $mathscale *= $DISP_SCALE_FACTOR; };
-               if (($scale)&&($exscale)) {
-                   $scale *= $exscale if ($name =~ /makeimage|tab/);
-               } elsif ($scale) {
-               } elsif (($mathscale)&&($exscale)) {
-                   $scale = $mathscale*$exscale;
-                   $under = "d" if (($name =~/inline|indisplay/)&&($depth{$name}));
-               } elsif ($mathscale) { $scale = $mathscale; }
-
-               (L2hos->syswait("$PSTOIMG -type $IMAGE_TYPE "
-               . ($DEBUG ? '-debug ' : '-quiet ' )
-               . ($TMPDIR ? "-tmp $TMPDIR " : '' )
-               . (($DISCARD_PS) ? "-discard " : '' )
-               . (($INTERLACE) ? "-interlace " : '' )
-               . ((($ANTI_ALIAS_TEXT||($aalias))&&(!($aalias =~ /no/)))?
-                   "-antialias -depth 1 " :'')
-               . ((($exscale)&&($exscale != 1)&&
-                   !($ANTI_ALIAS_TEXT &&($LATEX_COLOR)))? 
-                       "-shoreup $exscale " :'')
-               . (($scale ne 1) ? "-scale $scale " : '' )
-               . (($custom_size) ? "-geometry $custom_size " : '' )
-                . $croparg
-#              .  (($name =~ /(equation|eqnarray)/) ? "-rightjustify $lwidth " : '')
-#              .  (($name =~ /displaymath/) ? "-center $lwidth " : '')
-               . (($name =~ /inline|indisplay/ && (!($custom_size))&&$depth{$name}!= 0) ?
-                   do {$val=($height{$name}-$depth{$name})/($height{$name}+$depth{$name});
-                       "-topjustify x$val "} : '')
-               . ((($TRANSPARENT_FIGURES||($trans))
-                   &&(!($trans =~ /no/))) ? "-transparent " : '')
-               . (($WHITE_BACKGROUND && !$TRANSPARENT_FIGURES) ? "-white " : '' )
-               . "-out ${PREFIX}$img $psname.ps")
-               ) #|| !(print "\nWriting image: ${PREFIX}$img"))
-                   && print "\nError while converting image\n";
-           }
-           if (! -r "${PREFIX}$img") {
-               &write_warnings("\nFailed to convert image $psname.ps")
-           } else { } #L2hos->Unlink("$psname.ps") unless $DEBUG }
-           &open_dbm_database if $DJGPP;
-       }
-    }
-    print "\nextracted $name as $page_num\n" if ($VERBOSITY > 1);
-    &embed_image("${PREFIX}$img", $name, $external, $alt, $thumbnail, $map,
-        $align, $usemap, $exscale, $exstr);
-}
-
-sub extract_parameters {
-    local($contents) = @_;
-    local($_, $scale, $external, $thumbnail, $map, $psimage, $align,
-         $usemap, $flip, $aalias, $trans, $pagecolor, $alt, $exscale,
-         $cdepth, $htmlparams);
-
-    #remove the \htmlimage commands and arguments before...
-    $contents =~ s/$htmlimage_rx/$_ = $2;''/ego;
-    $contents =~ s/$htmlimage_pr_rx/$_ .= $2;''/ego;
-
-    # code adapted from original idea by Stephen Gildea:
-    # If the document specifies the ALT tag explicitly
-    # with \htmlimage{alt=some text} then use it.
-    s!alt=([^,]+)!$alt = $1;
-        $alt =~ s/^\s+|\s+$//g; $alt =~ s/"//g;
-        $alt="ALT=\"$alt\"";
-    ''!ie;
-
-  if (!$alt) {
-    #...catching all the code for the ALT text.
-    local($keep_gt)=1;
-    $alt = &flatten_math($contents); undef $keep_gt;
-    #RRM: too long strings upset the DBM. Truncate to <= 165 chars.
-    if ( length($alt) > 163 ) {
-       local($start,$end);
-       $start = substr($alt,0,80);
-       $end = substr($alt,length($alt)-80,80);
-       $alt = join('',$start,"...\n ...",$end);
-    }
-    s/ALT\s*=\"([\w\W]*)\"/$alt=$1;''/ie;
-    if ($alt) {
-       if ($alt =~ /\#/) {
-           $alt =~ s/^(\\vbox\{)?\#[A-Za-z]*\s*//;
-           $alt =~ s/\n?\#[A-Za-z]*\s*\}?$//s;
-           if ($alt =~ /\#/) { $alt = $` . " ... " };
-       }
-       $alt =~ s/\`\`/\\lq\\lq /g; $alt =~ s/\`/\\lq /g;
-       $alt =~ s/(^\s*|\s*$)//mg;
-       $alt = "ALT=\"$alt\"" if ($alt);
-    } else { $alt = 'ALT="image"' }
-  }
-
-    $psimage++ if ($contents =~ /\.ps/);
-#    $contents =~ s/\s//g;     # Remove spaces   Why ?
-    s/extrascale=([\.\d]*)/$exscale=$1;''/ie;
-    s/\bscale=([\.\d]*)/$scale=$1;''/ie;
-    s/(^|,\s*)external/$external=1;''/ie;
-    s/(^|,\s*)((no)?_?anti)alias(_?(text))?/$aalias = $2.$4;''/ie;
-    s/(^|,\s*)((no)?_?trans)parent/$trans = $2;''/ie;
-    s/thumbnail=([\.\d]*)/$thumbnail=$1;''/ie;
-    s/usemap=([^\s,]+)/$usemap=$1;''/ie;
-    s/map=([^\s,]+)/;$map=$1;''/ie;
-    s/align=([^\s,]+)/$align=$1;''/ie;
-    s/flip=([^\s,]+)/$flip=$1;''/ie;
-    s/color_?(depth)?=([^\s,]+)/$cdepth=$2;''/ie;
-    ($scale,$external,$thumbnail,$map,$psimage,$align
-     ,$usemap,$flip,$aalias,$trans,$exscale,$alt,$_);
-}
-
-
-# RRM: Put the raw \TeX code into the ALT tag
-# replacing artificial environments and awkward characters
-sub flatten_math {
-    local ($_) = @_;
-    $_ = &revert_to_raw_tex($_);
-    s/[ \t]+/ /g;
-    # MRO: replaced $* with /m
-    s/$tex2html_wrap_rx//gm;
-    s/(\\begin\s*\{[^\}]*\})(\s*(\[[^]]*\]))?[ \t]*/$1$3/gm;
-    s/(\\end\{[^\}]*\})\n?/$1/gm;
-    s/>(\w)?/($1)?"\\gt $1":"\\gt"/eg unless ($keep_gt); # replace > by \gt
-    s/\\\|(\w)?/($1)?"\\Vert $1":"\\Vert"/eg;  # replace \| by \Vert
-    s/\|(\w)?/($1)?"\\vert $1":"\\vert"/eg;    # replace | by \vert
-    s/\\\\/\\\\ /g;    # insert space after \\ 
-    s/\\"/\\uml /g;    # screen umlaut accents...
-    s/"/\'\'/g;                # replace " by ''
-    s/\\\#/\\char93 /g;        # replace \# by \char93 else caching fails
-#    s/"(\w)?/($1)?"\\rq\\rq $1":"\'\'"/eg;    # replace " by \rq\rq
-#    s/\&\\uml /\\\"/g;        # ...reinstate umlauts
-    $_;
-}
-
-sub scaled_image_size {
-    local($exscale,$_) = @_;
-    local($width,$height) = ('','');
-    /WIDTH=\"?(\d*)\"?\s*HEIGHT=\"?(\d*)\"?$/o;
-    $width=int($1/$exscale + .5);
-    $height=int($2/$exscale + .5);
-    "WIDTH=\"$width\" HEIGHT=\"$height\""
-}
-
-sub process_in_latex {
-    # This is just a wrapper for process_undefined_environment.
-    # @[0] = contents
-    $global{'max_id'}++;
-    &process_undefined_environment('tex2html_wrap',$global{'max_id'},$_[0]);
-}
-
-# MRO: cp deprecated, replaced by L2hos->Copy
-
-# Marcus Hennecke  6/3/96
-# MRO: test for existance
-sub copy_file {
-    local($file, $ext) = @_;
-    $file =  &fulltexpath("$FILE.$ext");
-    if(-r $file) {
-        print "\nNote: Copying '$file' for image generation\n"
-            if($VERBOSITY > 2);
-        L2hos->Copy($file, ".$dd${PREFIX}images.$ext");
-    }
-}
-
-sub rename_image_files {
-    local($_, $old_name, $prefix);
-    if ($PREFIX) {
-       foreach (<${PREFIX}*img*.$IMAGE_TYPE>) {
-           $old_name = $_;
-           s/\.$IMAGE_TYPE$/\.old/o;
-           L2hos->Rename($old_name, $_);
-           }
-       }
-    else {
-       foreach (<img*.$IMAGE_TYPE>) {
-           $old_name = $_;
-           s/\.$IMAGE_TYPE$/\.old/o;
-           L2hos->Rename($old_name, $_);
-       }
-       foreach (<Timg*.$IMAGE_TYPE>) {
-           $old_name = $_;
-           s/\.$IMAGE_TYPE$/\.old/o;
-           L2hos->Rename($old_name, $_);
-       }
-    }
-}
-
-
-############################ Processing Commands ##########################
-
-sub ignore_translate_commands {
-    local ($_) = @_;
-#   print "\nTranslating commands ...";
-
-    local(@processedC);
-    &replace_strange_accents;
-    local($before, $contents, $br_id, $after, $pattern, $end_cmd_rx);
-    s/$begin_cmd_rx/&replace_macro_expansion($`, $1, $&, $')/eg;
-}
-
-sub replace_macro_expansion {
-    push(@processedC,$_[1]);
-    $end_cmd_rx = &make_end_cmd_rx($_[2]);
-    $pattern = $_[3];
-    $_ = join('',$_[3],$_[4]);
-    $after = $_[4];
-    if (($before)&&(!($before =~ /$begin_cmd_rx/))) {
-       push(@processedC,$before);
-           $_ = join('',$pattern,$after); $before = '';
-       }
-       local($end_cmd_rx) = &make_end_cmd_rx($br_id);
-    
-}
-
-sub translate_aux_commands {
-    s/^(.*)$/&translate_commands($1)/s;
-}
-
-sub translate_commands {
-    local ($_) = @_;
-#   print "\nTranslating commands ...";
-
-    local(@processedC);
-    &replace_strange_accents;
-    for (;;) {                 # For each opening bracket ...
-       last unless ($_ =~ /$begin_cmd_rx/);
-       local($before, $contents, $br_id, $after, $pattern);
-       ($before, $br_id, $after, $pattern) = ($`, $1, $', $&);
-       if (($before)&&(!($before =~ /$begin_cmd_rx/))) {
-           push(@processedC,$before);
-           $_ = join('',$pattern,$after); $before = '';
-       }
-       local($end_cmd_rx) = &make_end_cmd_rx($br_id);
-       if ($after =~ /$end_cmd_rx/) { # ... find the the matching closing one
-           $NESTING_LEVEL++;
-           ($contents, $after) = ($`, $');
-           do {
-               local(@save_open_tags) = @$open_tags_R;
-               local($open_tags_R) = [ @save_open_tags ];
-               print STDOUT "\nIN::{$br_id}" if ($VERBOSITY > 4);
-               print STDOUT "\n:$contents\n" if ($VERBOSITY > 7);
-               undef $_;
-               $contents = &translate_commands($contents)
-                   if ($contents =~ /$match_br_rx/o);
-                # Modifies $contents
-               &process_command($single_cmd_rx,$contents)
-                   if ($contents =~ /\\/o);
-
-               $contents .= &balance_tags();
-           };
-
-           print STDOUT "\nOUT: {$br_id}" if ($VERBOSITY > 4);
-           print STDOUT "\n:$contents\n" if ($VERBOSITY > 7);
-           # THIS MARKS THE OPEN-CLOSE DELIMITERS AS PROCESSED
-           $_ = join("", $before,"$OP$br_id$CP", $contents,"$OP$br_id$CP", $after);
-           $NESTING_LEVEL--;
-       }
-       else {
-           $pattern = &escape_rx_chars($pattern);
-           s/$pattern//;
-           print "\nCannot find matching bracket for $br_id" unless $AUX_FILE;
-       }
-       last unless ($_ =~ /$begin_cmd_rx/o);
-    }
-    $_ = join('',@processedC) . $_;
-    # Now do any top level commands that are not inside any brackets
-    # MODIFIES $_
-    print $_ if ($VERBOSITY > 8);
-    &process_command($single_cmd_rx,$_);
-}
-
-#RRM: based on earlier work of Marcus Hennecke
-# makes sure the $open_tags_R at the end of an environment
-# is the same as @save_open_tags from the start,
-# ensuring that the HTML page indeed has balanced tags
-sub balance_tags {
-    local($tag_cmd, $tags, $save_tags, $open_tags, @reopen_tags);
-    $save_tags = join(',',@save_open_tags) if (@save_open_tags);
-    $open_tags = join(',',@$open_tags_R) if (@$open_tags_R);
-    if ($open_tags eq $save_tags) { return(); }
-    if ($save_tags =~ s/^$open_tags//) {
-       @reopen_tags = split (',',$');
-    } else {
-       @reopen_tags = @save_open_tags;
-       while (@$open_tags_R) {
-           $tag_cmd = pop (@$open_tags_R);
-           print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2;
-           $declarations{$tag_cmd} =~ m|</.*$|;
-           $tags .= $& unless ($` =~ /^<>$/);
-           $open_tags = join(',',@$open_tags_R) if (@$open_tags_R);
-           last if ( $save_tags =~ s/^$open_tags/
-                    @reopen_tags = split (',',$');''/e);
-       }
-    }
-    while (@reopen_tags) {
-       $tag_cmd = shift @reopen_tags;
-       if ($tag_cmd) {
-           push (@$open_tags_R, $tag_cmd) if ($tag_cmd);
-           print STDOUT "\n<$tag_cmd>" if $VERBOSITY > 2;
-           $declarations{$tag_cmd} =~ m|</.*$|;
-           $tags .= $` unless ($` =~ /^<>$/);
-       }
-    }
-    $tags;
-}
-
-sub close_all_tags {
-    return() if (!@$open_tags_R);
-    local($tags,$tag_cmd);
-    while (@$open_tags_R) {
-       $tag_cmd = pop (@$open_tags_R);
-       print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2;
-       $declarations{$tag_cmd} =~ m|</.*$|;
-       $tags .= $& unless ($` =~ /^<>$/);
-    }
-    $tags;
-}
-
-sub preserve_open_tags {
-    local(@save_open_tags) = @$open_tags_R;
-    local($open_tags_R) = [ @save_open_tags ];
-    # provides the markup to close and reopen the current tags
-    (&close_all_tags(), &balance_tags());
-}
-
-sub preserve_open_block_tags {
-    local($tag_cmd,$tags_open,$tags_close,$pre,$post,@tags);
-    while (@$open_tags_R) {
-       $tag_cmd = pop (@$open_tags_R);
-       print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2;
-       $declarations{$tag_cmd} =~ m|</.*$|;
-       ($pre,$post) = ($`,$&);
-       if ($post =~ /$block_close_rx/) {
-           # put it back and exit
-           push(@$open_tags_R,$tag_cmd);
-           last;
-       } else {
-           # leave it closed, collecting tags for it
-           $tags_close .= $post;
-           $tags_open = $pre . $tags_open;
-           unshift(@tags,$tag_cmd);
-       }
-    }
-    ($tags_close , $tags_open, @tags);  
-}
-
-sub minimize_open_tags {
-    local($this_tag, $close_only) = @_;
-    local($pre,$post,$decl);
-    $decl = $declarations{$this_tag};
-    if ($decl) {
-    # if it is a declaration, get the corresponding tags...
-       $decl =~ m|</.*$|;
-       ($pre,$post) = ($`,$&) unless ($` =~ /^<>$/);
-       if (!@$open_tags_R) { # when nothing else is open...
-            # pushing the style, when appropriate
-           push (@$open_tags_R, $this_tag)
-               unless ($close_only ||($post =~ /$block_close_rx/));
-           print STDOUT "\n<$this_tag>" if $VERBOSITY > 2;
-            # and return the tags
-           return($pre,$post) unless ($USING_STYLES);
-           local($env_id) = '' if ($env_id =~/^\w+$/);
-           $pre =~ s/>$/ $env_id>/ if ($env_id);
-           return($pre,$post);
-       }
-    } else { # ...else record the argument as $pre
-       $pre = $this_tag unless $close_only;
-    }
-    local($env_id) = '' if ($env_id =~/^\w+$/);
-    $pre =~ s/>$/ ID="$env_id">/ if ($USING_STYLES &&($env_id));
-
-    # return the tags, if nothing is already open
-    if (!@$open_tags_R) { 
-       return($pre,$post);
-    }
-#    elsif ($close_only) { push (@$open_tags_R, $this_tag) }
-
-    local($tags,$tag_cmd,$tag_open);
-    local($closures,$reopens,@tags);
-    local($tag_close,$tag_open);
-    local($size_cmd,$size_open);
-    local($font_cmd,$font_open);
-    local($fontwt_cmd,$fontwt_open);
-    local($color_cmd,$color_open);
-     if ($decl) {
-       if ($this_tag =~ /$sizechange_rx/) { 
-           $size_cmd = $this_tag;
-       } else {
-           if ($this_tag =~ /$fontchange_rx/) { 
-               $font_cmd = $this_tag }
-           if ($this_tag =~ /$fontweight_rx/) { 
-               $fontwt_cmd = $this_tag }
-       }
-    }
-    while (@$open_tags_R) {
-       ($tag_close,$tag_open) = ('','');
-       $tag_cmd = pop (@$open_tags_R);
-       print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2;
-       $declarations{$tag_cmd} =~ m|</.*$|;
-       ($tag_close,$tag_open) = ($&,$`) unless ($` =~ /<>/);
-       $closures .= $tag_close;
-
-       if ((!$size_cmd)&&($tag_cmd =~ /$sizechange_rx/)) {
-           $size_cmd = $tag_cmd;
-           $size_open = $tag_open;
-       }
-       elsif ((!$font_cmd)&&($tag_cmd =~ /$fontchange_rx/)) {
-           $font_cmd = $tag_cmd;
-           $font_open = $tag_open;
-       }
-       elsif ((!$fontwt_cmd)&&($tag_cmd =~ /$fontweight_rx/)) {
-           $fontwt_cmd = $tag_cmd;
-           $fontwt_open = $tag_open;
-       }
-       elsif ((!$color_cmd)&&($tag_cmd =~ /$colorchange_rx/)) {
-           $color_cmd = $tag_cmd;
-           $color_open = $tag_open;
-       } 
-       elsif ($tag_cmd =~ 
-            /$sizechange_rx|$fontchange_rx|$fontweight_rx|$colorchange_rx/) {
-       } else {
-           unshift (@tags, $tag_cmd);
-           print STDOUT "\n<<$tag_cmd>" if $VERBOSITY > 2;
-           $reopens = $tag_open . $reopens;
-       }
-    }
-    if ($USING_STYLES) {
-       local($TAG) = "DIV";
-       if ($pre =~ /^<(DIV|SPAN|PRE)/) { $TAG = $1 };
-       if (($pre =~ /^<$TAG/)&&($env_id =~ /^\s+(CLASS|ID)/)) {
-           $pre =~ s/<$TAG/<$TAG$env_id/;
-       } elsif ($pre =~ /<P>/) {
-           $TAG = 'P';
-       } else {
-       }
-#      $post .= "</$TAG>";
-    }
-    push (@$open_tags_R, @tags);
-    $tags .= $pre if ($pre && $post =~ /$block_close_rx/);
-    if ($font_cmd && !($font_cmd eq $this_tag)) {
-       push (@$open_tags_R,$font_cmd);
-       print STDOUT "\n<$font_cmd>" if $VERBOSITY > 2;
-       $tags .= $font_open;
-    }
-    if ($fontwt_cmd && !($fontwt_cmd eq $this_tag)) {
-       push (@$open_tags_R,$fontwt_cmd);
-       print STDOUT "\n<$fontwt_cmd>" if $VERBOSITY > 2;
-       $tags .= $fontwt_open;
-    }
-    if ($size_cmd && !($size_cmd eq $this_tag)) {
-       push (@$open_tags_R,$size_cmd);
-       print STDOUT "\n<$size_cmd>" if $VERBOSITY > 2;
-       $tags .= $size_open;
-    }
-    if ($color_cmd && !($color_cmd eq $this_tag)) {
-       push (@$open_tags_R,$color_cmd);
-       print STDOUT "\n<$color_cmd>" if $VERBOSITY > 2;
-       $tags .= $color_open;
-    }
-    $tags .= $pre unless ($pre && $post =~ /$block_close_rx/);
-    push (@$open_tags_R, $this_tag)
-       if ($decl &&!($post =~ /$block_close_rx|$all_close_rx/));
-    print STDOUT "\n<$this_tag>" if $VERBOSITY > 2;
-    ($closures.$reopens.$tags , $post );
-}
-
-
-sub declared_env {
-    local($decl, $_, $deferred) = @_;
-    local($after_cell,$pre,$post);
-    local($decls) = $declarations{$decl};
-    $decls =~ m|</.*$|;
-    ($pre,$post) = ($`,$&);
-    if ($USING_STYLES) {
-       $env_style{$decl} = " " unless ($env_style{$decl});
-       $pre =~ s/>$/$env_id>/ if ($env_id);
-    }
-    local($closing_tag) = 1 if ($pre =~ /^<>$/);
-    $pre = $post = '' if $closing_tag;
-    local($closures,$reopens);
-
-    local(@save_open_tags) = @$open_tags_R
-       unless ($closing_tag || $deferred);
-    local($open_tags_R) = [ @save_open_tags ]
-       unless ($closing_tag || $deferred );
-
-    if ($post =~ /$block_close_rx/) {
-       local($last_tag) = pop (@$open_tags_R);
-       local($ldecl) = $declarations{$last_tag};
-       if ($ldecl =~ m|</.*$|) { $ldecl = $& }
-       if (($last_tag)&&!($ldecl =~ /$block_close_rx/)) {
-           # need to close tags, for re-opening inside
-           push (@$open_tags_R, $last_tag);
-           ($closures,$reopens) = &preserve_open_tags();
-           $pre = join('', $closures, "\n", $pre, $reopens);
-           $post = join('', $closures, $post, $reopens);
-       } elsif ($last_tag) {
-           $pre = "\n".$pre;
-           push (@$open_tags_R, $last_tag);
-           undef $ldecl;
-       } else {
-       }
-
-       if ($deferred) {
-           if (defined $ldecl) {
-               print STDOUT "\n<<$decl>" if $VERBOSITY > 2;
-               unshift(@$open_tags_R, $decl);
-           } else {
-               print STDOUT "\n<$decl>" if $VERBOSITY > 2;
-               push(@$open_tags_R, $decl);
-           }
-           return ( $pre . $_ );
-       } else {
-           if (defined $ldecl) {
-               print STDOUT "\n<<$decl>" if $VERBOSITY > 2;
-               unshift(@$open_tags_R, $decl);
-           } else {
-               print STDOUT "\n<$decl>" if $VERBOSITY > 2;
-               push(@$open_tags_R, $decl);
-           }
-       }
-    } elsif ($post =~/$all_close_rx/) {
-       ($closures,$reopens) = &preserve_open_tags();
-       ($pre,$post) = &minimize_open_tags($decl,1);
-       $pre = join('', $closures, $pre);
-    } elsif ($closing_tag) {
-       $prev_open = $pre;
-       ($pre,$post) = &minimize_open_tags($decl,1);
-       $pre =~ s/<\/?>//g; $post =~ s/<\/?>//;
-    } else {
-       ($pre,$post) = &minimize_open_tags($decl); 
-    }
-    $_ =~ s/^\s+//s; #RRM:28/4/99 remove spaces at the beginning
-    $_ = &translate_environments($_);
-    $_ = &translate_commands($_) if (/\\/);
-    if ($post =~ /$block_close_rx/) {
-       s/^\n?/\n/o; 
-       if (defined $ldecl) {
-           $post = &close_all_tags();
-       } else {
-           $post = "\n";
-       }
-    } elsif ($post =~/$all_close_rx/) {
-    } else { $post = '' };
-
-    join('', $pre, $_, $post
-          , ($closing_tag ? '' : &balance_tags()) );
-}
-
-sub do_cmd_centering{&declared_env('center',$_[0],$tex2html_deferred)}
-sub do_cmd_raggedright{&declared_env('flushleft',$_[0],$tex2html_deferred)}
-sub do_cmd_raggedleft{&declared_env('flushright',$_[0],$tex2html_deferred)}
-
-sub do_env_verse { &declared_env('verse',@_) }
-sub do_env_quote { &declared_env('quote', @_) }
-sub do_env_quotation { &declared_env('quote', @_) }
-sub do_env_tex2html_preform { &declared_env('preform', @_) }
-sub do_env_tex2html_ord { &declared_env('ord', @_) }
-sub do_env_tex2html_unord { &declared_env('unord', @_) }
-sub do_env_tex2html_desc { &declared_env('desc', @_) }
-
-
-# Modifies $contents
-sub process_command {
-    # MRO: modified to use $_[1]
-    # local ($cmd_rx, *ref_contents) = @_;
-    local ($cmd_rx) = @_;
-    local($ref_before, $cmd , $pc_after);
-    local($cmd_sub, $cmd_msub, $cmd_trans, $mathentity);
-    local (@open_font_tags,@open_size_tags);
-    $_[1] = &convert_iso_latin_chars($_[1])
-       unless (($cmd =~ /(Make)?([Uu]pp|[Ll]ow)ercase/)||
-           ((!$cmd)&&($_[1] =~ /^\\(Make)?([Uu]pp|[Ll]ow)ercase/s)));
-
-    local(@ref_processed);
-    for (;;) {                 # Do NOT use the o option
-       last unless ($_[1] =~ /$cmd_rx/ );
-       print ".";
-       #JCL(jcl-del) - use new regexp form which handles white space
-       ($ref_before, $cmd, $pc_after) = ($`, $1.$2, $4.$');
-       push(@ref_processed,$ref_before);
-#print "\nAFTER:$1.$2:".$4."\n" if ($cmd_rx eq $single_cmd_rx);
-       print STDOUT "$cmd" if ($VERBOSITY > 2);
-       print STDOUT "\nIN: $_[1]\n" if ($VERBOSITY > 6);
-       #
-       if ( $cmd = &normalize($cmd,$pc_after) ) {
-           ($cmd_sub, $cmd_msub, $cmd_trans, $mathentity) =
-               ("do_cmd_$cmd", "do_math_cmd_$cmd"
-               , $declarations{$cmd}, $mathentities{$cmd});
-           if ($new_command{$cmd}||$renew_command{$cmd}) { 
-                # e.g. some \the$counter 
-               local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd});
-               &make_unique($body) if ($body =~ /$O/);
-               if ($argn) {
-                   do { 
-                       local($before) = '';
-                       local($_) = "\\$cmd ".$pc_after;
-                       # &substitute_newcmd  may need what comes after the $cmd
-                       # from the value of $after 
-                       #RRM: maybe best to pass it as a parameter ?
-                       my $keep_after = $after;
-                       $after = $pc_after;
-                       $pc_after = &substitute_newcmd;   # may change $after
-                       $pc_after =~ s/\\\@#\@\@/\\/o ;
-                       $pc_after .= $after;
-                       $after = $keep_after;
-                   }
-               } else {
-                   $pc_after = $body . $pc_after;
-               }
-           } elsif (defined &$cmd_sub) {
-               # $ref_before may also be modified ...
-               if ($cmd =~ /$sizechange_rx/o) {
-                   $pc_after = &$cmd_sub($pc_after, $open_tags_R);
-               } else {
-                   $pc_after = &$cmd_sub($pc_after, $open_tags_R);
-               };
-           } elsif ((defined &$cmd_msub)&&!$NO_SIMPLE_MATH) {
-#print "\nMCMD:$cmd_msub :  ";
-               # $ref_before may also be modified ...
-               $pc_after = &$cmd_msub($pc_after, $open_tags_R);
-               if ( !$math_mode ) {
-                   $pc_after = "<MATH>" . $pc_after . "</MATH>";
-                   ++$commands_outside_math{$cmd};
-               };
-           } elsif ($cmd_trans) { # One to one transform
-#print "\nCMD-DECL: $inside_tabular : $cmd_trans". join(',',@$open_tags_R);
-               if ($inside_tabular) {
-                   push (@ref_processed , "\\$cmd ")
-               } else {
-                   $cmd_trans =~ m|</.*$|;
-                   $pc_after = $` . $pc_after unless ($` =~ /^<>/);
-                   push(@$open_tags_R, $cmd)
-                       if ($cmd =~ /$fontchange_rx|$fontweight_rx|$sizechange_rx/o);
-               }
-           } elsif ($mathentity) {
-#print "\nM-ENT:$mathentity :  ";
-               if ( $math_mode ) {
-                   $pc_after = "&$mathentity#$cmd;" . $pc_after;
-               } elsif ($NO_SIMPLE_MATH) {
-                   $pc_after = "&$mathentity#$cmd;" . $pc_after;
-#                  ++$commands_outside_math{$cmd};
-               } else {
-                   $pc_after = "<MATH>&$mathentity#$cmd;</MATH>" . $pc_after;
-                   ++$commands_outside_math{$cmd};
-               }
-           } elsif ($ignore{$cmd}) { # Ignored command
-               print "\nignoring \\$cmd" if $VERBOSITY > 5;
-               $pc_after = join('', " ", $pc_after) if ($cmd eq " "); # catches `\ '
-               $pc_after = join(''," ", $pc_after)
-                   if (($cmd eq ',')&&($pc_after =~ /^\-/s)&&($ref_before =~/\-$/s));
-           } elsif ($cmd =~ /^the(.+)$/){
-               $counter = $1;
-               local($tmp)="do_cmd_$cmd";
-               if (defined &$tmp) { # Counter
-                   $pc_after = &do_cmd_thecounter($pc_after);
-               } else {
-                   if (defined $failed) {
-                       $failed = 1;
-#                      $ref_before .= "$cmd";
-                       push(@ref_processed,$cmd);  # $ref_before .= "$cmd";
-                   } else {  &declare_unknown_cmd($cmd) }
-#                  $ref_before .= "$cmd" if ($failed);
-               }
-           } elsif ($cmd eq "\n") { push(@ref_processed," ");  # $ref_before .= " "; 
-           } else {
-               # Do not add if reading an auxiliary file
-               if (defined $failed) { 
-                   $failed = 1;
-               } else { &declare_unknown_cmd($cmd) }
-           }
-       } else {
-           # &normalize should have already handled it adequately
-           # '\ ' (space) gets thru to here. Perhaps some others too ?
-#          print "\n ?? This should not happen: \\$cmd ??\n";
-       }
-#      $_[1] = join('', $ref_before, $pc_after);
-       $_[1] = $pc_after;
-       print STDOUT "\n-> $ref_before\n" if ($VERBOSITY > 6);
-    }
-    $_[1] = join('',@ref_processed).$_[1];
-}
-
-sub declare_unknown_cmd {
-    local($this_cmd) = @_;
-    local($tmp) = "wrap_cmd_$cmd";
-    do { ++$unknown_commands{$cmd};
-       print STDOUT "\n*** Unknown command[1]: \\$cmd *** \n" 
-           if ($VERBOSITY > 2);
-    } unless ($AUX_FILE||(defined &$tmp)||($image_switch_rx=~/\b\Q$cmd\E\b/));
-}
-
-
-# This makes images from the code for math-entities,
-# when $NO_SIMPLE_MATH is set and the  math  extension is loaded.
-#
-sub replace_math_constructions {
-    local($math_mode) = @_;
-    &make_math_box_images($math_mode) if (/<BOX>/);
-    &make_math_entity_images($math_mode) if (/\&\w+#\w+;/);
-}
-
-sub make_math_box_images {
-    local($math_mode) = @_;
-    local($pre,$this,$post,$tmp) = ('','','');
-    local($slevel,$blevel) = 0;
-
-    while (/<BOX>/) {
-       $pre .= $`; $tmp = $`; $this = ''; $post = $';  
-       # compute the super/sub-scripting level for each entity
-       $tmp =~ s/<(\/?)SU[BP]>/
-           if ($1) { $slevel--} else { $slevel++};''/eog;
-
-       $tmp = $post;
-       if ($tmp =~ /<(\/?)BOX>/o ) {
-           if ($1) { $this = $`; $post = $' }
-           else { $failed = 1 } # nested box, too complicated !
-       } else {
-           &write_warnings("\nLost end of a <BOX> ?");
-           $failed = 1;
-       }
-       last if ($failed);
-
-       ($this,$_) = &process_box_in_latex(
-                   $math_mode, $slevel, $this, $post);
-       $_ =~ s/^\s*//; # remove any leading spaces
-       $pre .= $this ."\001"; 
-    }
-    return  if ($failed);
-    $_ = $pre . $_;
-}
-
-sub make_math_entity_images {
-    local($math_mode) = @_;
-    local($pre,$this,$post,$tmp) = ('','','');
-    local($slevel) = 0;
-    # compute the super/sub-scripting level for each entity
-    while (/\&\w+#(\w+);/) {
-       $pre .= $`; $tmp = $`; $this = $1; $post = $';
-       $tmp =~ s/<(\/?)SU[BP]>/
-           if ($1) { $slevel--} else { $slevel++};''/eog; 
-       ($this,$_) = &process_entity_in_latex(
-               $math_mode, $slevel, $this, $post);
-       $_ =~ s/^\s*//; # remove any leading spaces
-       $pre .= $this ."\001"; 
-    }
-    $_ = $pre . $_;
-}
-
-
-#RRM:  Revert a math-entity to create image using LaTeX, together with
-# any super/sub-scripts (possibly nested or with \limits ).
-# Must also get the correct  \display/text/(script)script  style.
-#
-sub process_entity_in_latex {
-    local($mode,$level,$entity,$after) = @_;
-    local($math_style,$supsub,$rest) = ('','','');
-    $level++ if ($mode =~/box/); # for top/bottom of inline fractions, etc.
-
-    if ($level) {
-       $math_style = "\\". (($level > 1) ? "script" : "")."scriptstyle"
-    } else {
-       $math_style = "\\displaystyle" unless ($mode =~ /inline/);
-    }
-    while ($after =~ s/^\s*((\\limits|\&limits;)?\s*<SU(P|B)>)\s*/$supsub .= $1;''/eo) {
-       local($slevel) = 1;
-       local($aftersupb) = '';
-       while ($slevel) {
-           $after =~ s/(<(\/)SU(B|P)>)/($2)? $slevel-- : $slevel++;''/oe;
-           $supsub .= $`.$&;
-           $aftersupb = $';
-       }
-       $after = $aftersupb;
-    }
-
-    local($latex_code) = "\$$math_style\\$entity$supsub\$";
-
-    $global{'max_id'}++;
-    ( &process_undefined_environment('tex2html_wrap_inline'
-            ,$global{'max_id'}, $latex_code ) , $after);
-}
-
-sub process_box_in_latex {
-    local($mode,$level,$inside,$after) = @_;
-    local($math_style,$which,$pre,$post,$tmp) = ('','',"\{","\}");
-    
-    if ($level) {
-       $math_style = "\\". (($level > 1) ? "script" : "")."scriptstyle"
-    } else {
-       $math_style = "\\displaystyle" unless ($mode =~ /inline/);
-    }
-
-    if ($inside =~ /<((LEFT)|(RIGHT))>/ ) {
-       $pre = "\\left"; $post = "\\right";
-       if ($2) { 
-           $tmp = $`; $inside = $';
-           $pre .= (($tmp) ? $tmp : ".") . "\{";
-           if ( $inside =~ /<RIGHT>/ ) {
-               $tmp = $';
-               $inside = $`;
-               $post = "\}". (($tmp) ? $tmp : ".");
-           }
-       } else {
-           $pre .= ".\{"; $tmp = $'; $inside = $`;
-           $post = "\}". (($tmp) ? $tmp : ".");
-       }
-    }
-    if ( $inside =~ /<((OVER)|(ATOP)|(CHOOSE))>/ ) {
-       $pre .= $`;
-       $post = $' . $post ;
-       if ($2) { $which = "over " }
-       elsif ($3) { $which = "atop " }
-       elsif ($4) { $which = "atopwithdelims\(\)" }
-    }
-
-    local($latex_code) = join('', "\$" , $math_style , " ", $pre 
-         , (($which)? "\\$which" : "") , $post , "\$" );
-
-    if ($after =~ s/<SUP ALIGN=\"CENTER\">([^<]*)<\/SUP>/
-       $tmp =$1;''/eo ) {
-       $latex_code = join('', "\\stackrel" , $latex_code
-                          , "\{" , $tmp , "\}" );
-    }
-    
-    $global{'max_id'}++;
-    ( &process_undefined_environment('tex2html_wrap_inline'
-            ,$global{'max_id'}, $latex_code ) , $after);
-}
-
-####################### Processing Meta Commands ############################
-# This is a specialised version of process_command above.
-# The special commands (newcommand, newenvironment etc.)
-# must be processed before translating their arguments,
-# and before we cut up the document into sections
-# (there might be sectioning commands in the new definitions etc.).
-# \newtheorem commands are treated during normal processing by
-# generating code for the environments they define.
-
-sub substitute_meta_cmds {
-    local ($next_def);
-    local ($cmd, $arg, $argn, $opt, $body, $before, $xafter);
-    local ($new_cmd_no_delim_rx, $new_cmd_rx, $new_env_rx, $new_cmd_or_env_rx);
-    local ($new_end_env_rx);
-    &tokenize($meta_cmd_rx);   #JCL(jcl-del) - put delimiter after meta command
-    print "\nProcessing macros ..." if (%new_command || %new_environment);
-    # First complete any replacement left-over from the previous part.
-    if ($UNFINISHED_ENV) { 
-       s/$UNFINISHED_ENV/$REPLACE_END_ENV/;
-       $UNFINISHED_ENV = '';
-       $REPLACE_END_ENV = '';
-    }
-
-    local(@processed);
-    local($processed, $before, $after)=('', '', $_);
-    while ($after =~ /$meta_cmd_rx$EOL/o) {    # ... and uses the delimiter
-       ($cmd, $after) = ($1.$2, $');
-       $before .= $`;
-#      $next_def = '';
-       if (!($before =~ /$meta_cmd_rx$EOL/)) {
-           push(@processed, $before); $before = '';
-       }
-                
-       print ",";
-#      $next_def = "\\$cmd" unless (($cmd =~ /renewcommand/));
-       local($cmd_sub) = "get_body_$cmd";
-       if (defined &$cmd_sub) {
-#          $processed = &$cmd_sub(*after);
-           $processed = &$cmd_sub(\$after);
-#          if ($processed) { $after = $before . $processed; }
-#          $next_def = '' 
-#              if (($PREAMBLE > 1)&&($cmd =~ /(re)?newcommand/));
-#          &add_to_preamble($cmd, $next_def)
-#              unless ($next_def =~ /^\s*$/);
-### new style of handling meta-commands
-           if ($processed) { push(@processed, "\\".$processed) }
-       }
-       elsif ($before) {
-           # this shouldn't happen !!
-           print STDERR "\nCannot handle \\$cmd , since there is no $cmd_sub ";
-           $after = $before . $cmd . $after;
-           $before = '';
-       } else { 
-           push(@processed, "\\$cmd ") if $cmd;
-       }
-    }
-    print "\nmeta-commands: ". (0+@processed) ." found "
-       if ((@processed)&&($VERBOSITY > 1));
-    $_ = join('',@processed, $after); undef @processed;
-    if ($PREAMBLE) {
-       # MRO: replaced $* with /m
-        s/((\n$comment_mark\d*)+\n)//gm;
-        s/(\\par\b\s*\n?)+/\\par\n/gm;
-        s/(\\par\b\n?)+/\\par\n/gm;
-    }
-
-    # hard-code the new-command replacements for these
-    $new_command{'begingroup'} = "0:!:\\begin<<0>>tex2html_begingroup<<0>>:!:}";
-    $new_command{'endgroup'} = "0:!:\\end<<0>>tex2html_begingroup<<0>>:!:}";
-    $new_command{'bgroup'} = "0:!:\\begin<<0>>tex2html_bgroup<<0>>:!:}";
-    $new_command{'egroup'} = "0:!:\\end<<0>>tex2html_bgroup<<0>>:!:}";
-
-    # All the definitions have now moved to the $preamble and their bodies
-    # are stored in %new_command and %new_environment
-    #
-    # Now substitute the new commands and environments:
-    # (must do them all together because of cross definitions)
-    $new_cmd_rx = &make_new_cmd_rx(keys %new_command);
-    $new_cmd_no_delim_rx = &make_new_cmd_no_delim_rx(keys %new_command);
-    $new_env_rx = &make_new_env_rx;
-    $new_end_env_rx = &make_new_end_env_rx;
-#    $new_cnt_rx = &make_new_cnt_rx(keys %new_counter);
-    $new_cmd_or_env_rx = join("|", $new_cmd_no_delim_rx." ", $new_env_rx);
-#    $new_cmd_or_env_rx = join("|", $new_cmd_no_delim_rx." ", $new_env_rx, " ".$new_cnt_rx);
-    $new_cmd_or_env_rx =~ s/^ \||\|$//;
-
-    print STDOUT "\nnew commands:\n" if ($VERBOSITY > 2);
-    while (($cmd, $body) = each %new_command) {
-       unless ($expanded{"CMD$cmd"}++) {
-           print STDOUT ".$cmd " if ($VERBOSITY > 2);
-           $new_command{$cmd} = &expand_body;
-           print STDOUT " ".$new_command{$cmd}."\n" if ($VERBOSITY > 4);
-           &write_mydb("new_command", $cmd, $new_command{$cmd});
-       }
-    }
-
-    print STDOUT "\nnew environments:\n" if ($VERBOSITY > 2);
-    while (($cmd, $body) = each %new_environment) {
-       unless ($expanded{"ENV$cmd"}++) {
-           print STDOUT ".$cmd" if ($VERBOSITY > 2);
-           $new_environment{$cmd} = &expand_body;
-           &write_mydb("new_environment", $cmd, $new_environment{$cmd});
-       }
-    }
-
-    print STDOUT "\nnew counters and dependencies:\n" if ($VERBOSITY > 2);
-    &clear_mydb("dependent") if ($DEBUG);     #avoids appending to a previous version
-    while (($cmd, $body) = each %dependent) {
-       print STDOUT ".($cmd,$body)" if ($VERBOSITY > 2);
-        &write_mydb("dependent", $cmd, $dependent{$cmd});
-    }
-    &clear_mydb("img_style") if ($DEBUG);     #avoids appending to a previous version
-    while (($cmd, $body) = each %img_style) {
-        &write_mydb("img_style", $cmd, $img_style{$cmd});
-    }
-
-    &clear_mydb("depends_on") if ($DEBUG);     #avoids appending to a previous version
-    while (($cmd, $body) = each %depends_on) {
-       print STDOUT ".($cmd,$body)" if ($VERBOSITY > 2);
-        &write_mydb("depends_on", $cmd, $depends_on{$cmd});
-    }
-
-
-    &clear_mydb("styleID") if ($DEBUG);     #avoids appending to a previous version
-    while (($cmd, $body) = each %styleID) {
-        &write_mydb("styleID", $cmd, $styleID{$cmd});
-    }
-
-    &clear_mydb("env_style") if ($DEBUG);     #avoids appending to a previous version
-    while (($cmd, $body) = each %env_style) {
-        &write_mydb("env_style", $cmd, $env_style{$cmd});
-    }
-    &clear_mydb("txt_style") if ($DEBUG);     #avoids appending to a previous version
-    while (($cmd, $body) = each %txt_style) {
-        &write_mydb("txt_style", $cmd, $txt_style{$cmd});
-    }
-
-    print STDOUT "\ntheorem counters:\n" if ($VERBOSITY > 2);
-    &clear_mydb("new_theorem") if ($DEBUG);     #avoids appending to a previous version
-    while (($cmd, $body) = each %new_theorem) {
-       print STDOUT ".($cmd,$body)" if ($VERBOSITY > 2);
-        &write_mydb("new_theorem", $cmd, $new_theorem{$cmd});
-    }
-
-
-    print "+";
-    if (length($new_env_rx)) {
-       local(@pieces);
-        print STDOUT "\nsubstituting new environments: $new_env_rx\n" if ($VERBOSITY > 3);
-#      while (/\n?$new_env_rx/ && (($before, $cmd, $after) = ($`, $2, $'))) {
-       while (/$new_env_rx/ && (($before, $cmd, $after) = ($`, $2, $'))) {
-           print STDOUT ",";
-           print STDOUT "{$cmd}" if ($VERBOSITY > 1);
-           if (!($before =~ /$new_env_rx/)) {
-               push (@pieces, $before); $before = ''; print "{}";
-           }
-           $_ = join('',$before, &substitute_newenv);
-       }
-       print "\n ".(0+@pieces). " new environments replaced\n" if (@pieces);
-       $_ = join('', @pieces, $_); undef @pieces;      
-    }
-
-
-    print "+";
-    if (length($new_cmd_rx)) {
-       print STDOUT "\ntokenizing: $new_cmd_rx\n" if ($VERBOSITY > 2);
-       &tokenize($new_cmd_rx); # Put delimiter after the new commands
-
-       # and use the delimiter.
-       print STDOUT "\nsubstituting new commands: $new_cmd_rx\n" if ($VERBOSITY > 2);
-       print STDOUT "\ninitial size: ".length($after) if ($VERBOSITY > 1);
-       # store processed pieces in an array
-       local($this_cmd, @pieces);
-       # speed-up processing of long files by splitting into smaller segments
-       # but don't split within the preamble, else \newenvironment may break
-       local($pre_segment,@segments); &make_sections_rx;
-       local($within_preamble,$this_section) = 1 if ($PREAMBLE>1);
-       while (/$sections_rx/) {
-           $pre_segment .= $`; $_ = $'; $this_section = $&;
-           do {
-               push(@segments,$pre_segment);
-               $pre_segment = '';
-           } unless ($within_preamble);
-           $within_preamble = 0 if ($within_preamble && ($pre_segment =~ 
-                   /\\(startdocument|begin\s*($O\d+${C})\s*document\s*\2)/));
-           $pre_segment .= $this_section;
-       }
-       push(@segments,$pre_segment.$_);
-       local($replacements,$seg) ; $before = ''; # count the segments
-       local($within_preamble) = 1 if ($PREAMBLE>1);
-       foreach $after (@segments) {
-         while ($after =~ /(\\(expandafter|noexpand)\b\s*)?$new_cmd_no_delim_rx\b\s?/) {
-           ($before, $xafter, $cmd, $after) = ($`, $2, $3, $');
-           $within_preamble = 0
-               if ($before =~ /\\(startdocument|begin\s*($O\d+${C})\s*document\s*\2)/);
-           push(@pieces, $before);
-           print "."; ++$replacements;
-           print STDOUT "$cmd" if ($VERBOSITY > 2);
-           if ($xafter =~ /no/) { $this_cmd = "\\\@#\@\@".$cmd  }
-           elsif (($xafter =~ /after/)&&($after =~ /^\s*\\/)) {
-               local($delayed) = $cmd;
-               local($nextcmd);
-               $after =~ s/^\s*\\([a-zA-Z]+|.)/$nextcmd = $1;''/eo;
-               ($cmd,$nextcmd) = ($nextcmd, "do_cmd_$nextcmd");
-               if (defined &$nextcmd) { $after = &$nextcmd($after); }
-               elsif ($new_command{$cmd}) { 
-                   local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd});
-                   &make_unique($body) if ($body =~ /$O/);
-                   if ($argn) {
-                       do { 
-                           local($before) = '';
-                           $after = join('',&substitute_newcmd, $after);
-                           $after =~ s/\\\@#\@\@/\\/o ;
-                       };
-                   } else { $after = $body . $after; }
-               } else { print "\nUNKNOWN COMMAND: $cmd "; }
-               $cmd = $delayed;
-               if ($new_command{$cmd}) {
-                   if ($renew_command{$cmd}) {
-#                      # must wrap it in a deferred environment
-#                      $this_cmd = join('', &make_deferred_wrapper(1)
-#                              ,"\\$cmd".(($cmd =~ /\w$/)? " ":'')
-#                              , &make_deferred_wrapper(0));
-#                      push(@pieces, $this_cmd); $this_cmd = '';
-                       push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":''));
-                       $this_cmd = '';
-                   } elsif ($provide_command{$cmd}&&$within_preamble) {
-                       # leave it alone
-                       push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":''));
-                       $this_cmd = '';
-                   } else {
-                       # do the substitution
-                       $this_cmd = &substitute_newcmd;
-                   }
-               }
-           } elsif ($renew_command{$cmd}) {
-               # leave it alone
-               push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":''));
-               $this_cmd = '';
-           } elsif (($provide_command{$cmd})&&($within_preamble)) {
-               # leave it alone
-               push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":''));
-               $this_cmd = '';
-           } else {
-               # do the substitution
-               $this_cmd = &substitute_newcmd if ($new_command{$cmd});
-           }
-           if ($this_cmd =~ /(\\(expandafter|noexpand)\s*)?$new_cmd_no_delim_rx\b\s?/)
-               { $after = $this_cmd . $after }
-           elsif ($this_cmd) { push(@pieces, $this_cmd) }
-         }
-         push(@pieces, $after);
-               # after the first segment we should no longer be in the preamble
-               $within_preamble = 0;
-       }
-       print " $replacements new-command replacements\n"
-           if (($VERBOSITY>1) && $replacements);
-       # recombine the processed pieces
-       $_ = join('', @pieces); undef @pieces;
-        print STDOUT ", resulting size: ".length($_)." " if ($VERBOSITY > 1);
-       $_ =~ s/\\\@#\@\@/\\/go;
-    }
-
-    print STDOUT "\n *** substituting metacommands done ***\n" if ($VERBOSITY > 3);
-}
-
-sub insert_command_expansion {
-    ($xafter, $cmd) = @_;
-#   push(@pieces, $_[1]);
-    print ".$cmd";
-    print STDOUT "$_[3]" if ($VERBOSITY > 2);
-#   $xafter = $_[2];
-#   $cmd = $_[3];
-    if ($xafter =~ /no/) { $this_cmd = "\\\@#\@\@".$cmd }
-    elsif (($xafter =~ /after/)&&($after =~ /^\s*\\/)) {
-       local($delayed,$nextcmd) = ($_[3],'');
-
-       $after =~ s/^\s*\\([a-zA-Z]+|.)/$nextcmd = $1;''/eo;
-       ($cmd,$nextcmd) = ($nextcmd, "do_cmd_$nextcmd");
-       if (defined &$nextcmd) { $after = &$nextcmd($after); }
-       elsif ($new_command{$cmd}) { 
-           local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd});
-           &make_unique($body) if ($body =~ /$O/);
-           if ($argn) {
-               do { 
-                   local($before) = '';
-                   $after = join('',&substitute_newcmd, $after);
-                   $after =~ s/\\\@#\@\@/\\/o ;
-               };
-           } else { $after = $body . $after; }
-       } else { print "\nUNKNOWN COMMAND: $cmd "; }
-       $cmd = $delayed;
-       $this_cmd = &substitute_newcmd if ($new_command{$cmd});         
-    } else {
-       $this_cmd = &substitute_newcmd if ($new_command{$cmd});
-    }
-#   if ($this_cmd =~ /(\\(expandafter|noexpand)\s*)?$new_cmd_no_delim_rx\s?/){
-#      $after = $this_cmd . $after
-#   } else { push(@pieces, $this_cmd); }
-    $this_cmd;
-}
-
-
-sub expand_body {
-    return unless length($new_cmd_or_env_rx);
-    local($_) = $body;
-    local($cmd,$saveafter,$avoid_looping);
-    # Uses $before, $body, $arg, etc. of the caller, but not $cmd.
-    # Uses $new_cmd_rx (resp. $new_cmd_no_delim_rx) and $new_env_rx
-    # set in the caller, of which one might be empty.
-
-    # Puts delimiter after the new commands ...
-    &tokenize($new_cmd_rx) if length($new_cmd_rx);
-
-    while (/$new_cmd_or_env_rx/) {
-       # $new_cmd_rx binds $1, and $new_env_rx binds $3.
-       ($before,$cmd,$after,$saveafter) = ($`,$1.$3,$',$');
-       if (length($new_command{$cmd})) { # We have a command
-           # this tokenizes again
-           local($replace) = &substitute_newcmd; # sets $_, changes $after
-           if (!($replace)) {
-               # protect name of unexpanded macro
-               $_ = join('', $before ,"\\@#@@", $cmd, $saveafter );
-           } else {
-               $_ = join('', $before , $replace, $after );
-           }
-       } elsif (length($new_environment{$cmd})) {
-           $_ = join('',$before, &substitute_newenv);
-       }
-       last if $avoid_looping;
-    }
-    # remove protection from unreplaced macro names
-    s/\\\@#\@\@/\\/go;
-
-    # remove trivial comments
-    s/(\\\w+)$comment_mark\d*\n[ \t]*/$1 /go;
-    s/$comment_mark\d*\n[ \t]*//go;
-#    s/($O\d+$C)?($comment_mark\n)[ \t]*/($1 ? $1.$2 : '')/eg;
-
-    $_;
-}
-
-
-sub substitute_newcmd {
-    # Modifies $after in the caller
-    # Get the body from the new_command array
-    local($tmp,$cnt,$saved, $arg, $isword) = ('',0,$cmd);
-    local($argn, $_, $opt) = split(/:!:/, $new_command{$cmd});
-    $avoid_looping = 1 if ($new_command{$cmd} =~ /\\$cmd\b/);
-
-    &tokenize($new_cmd_rx); # must do it again for newly inserted cmd bodies
-    print STDOUT "\nNEW:$cmd:$_" if ($VERBOSITY > 5);
-    foreach $i (1..$argn) {
-       $arg = $isword = '';
-       if ($i == 1 && $opt ne '}') {
-           $arg = ($after =~ s/$optional_arg_rx//o) ? $1 : $opt;
-       }
-       else {
-           # Get the next argument, if not in braces, get next character
-           #RRM: allow also for processed braces, in case substitution
-           #     was delayed; e.g. by \renewcommand
-           if (!(($after =~ s/$next_pair_rx/$arg = $2;''/e)
-                 ||($after =~ s/$next_pair_pr_rx/$arg = $2;''/e))) {
-               $after =~ s/^\s*(\\[a-zA-Z]+|.)/$arg = $1;''/e;
-           }
-           if ($arg eq '#') { 
-               &write_warnings("\nSubstitution of arg to $cmd delayed."); 
-               $_ = "\\\@#\@\@$saved";
-               return ();
-           };
-       }
-       $arg =~ s/(^|\G|[^\\])\\\#/$1$hash_mark/gs;
-       $arg =~ s/\#/$param_mark/gs;
-
-       #RRM: Substitute the arguments in the body one at a time
-       #     else multiple instances would fail in  &make_unique
-
-       # First protect ## parameters in TeX-like substitutions
-       # suggested by Dirk Pleiter (Berlin)
-       s/((^|[^\\])(\\\\)*)\#\#$i/$1$protected_hash/gs;
-       $tmp = $_;
-       $cnt = $tmp =~ s/\#$i//g ;
-       $isword = 1 if ($arg =~ /^\w/);
-       if ($cnt > 1 ) {
-           $tmp = $_;
-           while ($cnt > 1) {
-               if ( s/(\\\w+)?\#$i/(($1&&$isword)? $1.' ': '').$arg/e) { 
-                   &make_unique($_) if ($arg =~ /$O/ ); 
-                   &make_unique_p($_) if ($arg =~ /$OP/ );
-               }
-               $cnt--;
-           }
-           $tmp = $_;
-       }
-#      s/(\\\w+)?\#$i/(($1&&$isword)? $1.' ': '').$arg/e ;
-       s/(\\\w+)?\#$i/$1.(($1&&$isword)? ' ': '').$arg/e ;
-       print "\n *** substitution: $arg \nfor \#$i in \\$cmd did not take ***\n"
-          if (/\#$i/);
-       &write_warnings("incomplete substitution in a \\$cmd command:\n$_") if (/\#$i/);
-       s/$protected_hash/\#$i/g;
-    }
-    s/$param_mark/\#/g;
-    s/$hash_mark/\\\#/g;
-    s/(\\\w+)$/$1 /s;
-
-    # Make the body unique (give unique id's to the brackets),
-    # translate, and return it
-    &make_unique($_);
-    if ($avoid_looping) {
-       s/\\$cmd\b/\\csname $cmd\\endcsname/g;
-       print STDERR "\n *** possible looping with new-command \\$cmd ***\n";
-       &write_warnings("\npossible looping with new-command \\$cmd ");
-    }
-    print STDOUT "\nOUT:$cmd:$_" if ($VERBOSITY > 5);
-
-# Insert a space to prevent letters from clashing together with a
-# letter command. Consider this:
-# New command substitution is restricted to commands introduced by
-# \newcommand etc. (so-called meta commands), but it is not done
-# for already defined commands, eg. \large.
-# But new command, as well as new environment, substitution is done
-# prior to any other substitution.
-# So \newcommand{\this}{...} {\large\this b} will get expanded the
-# following way:
-# 1. \newcommand{\this}{...}
-#    is handled by &substitute_meta_cmds, it gets the definition
-#    of \this and stores it within a table, %new_command.
-#    After all new commands are recognized, &expand_body is called
-#    to expand one command body from each other. That's O(n*n)!
-# 2. A regular expression $new_cmd_rx is built containing a pattern
-#    that matches all occurrences of a properly delimited \this
-#    macro. When matching, ensuing white space gets lost.
-#    (But only for letter commands, see also &make_new_cmd_rx.)
-#    Another regular expression called $new_cmd_no_delim_rx is built
-#    which matches exact the \this, and would also match the prefix
-#    of \thisx.
-# 3. The *whole* text is tokenized using $new_cmd_rx, with separates
-#    \this from the ensuing text by one white space.
-# 4. Then $new_cmd_no_delim_rx together with the delimiting space
-#    is used to substitute \this with its body.
-# 5. The following situations may occur:
-#  a) ... is some text (no macros) => {\large<text>yyy}
-#     Then we must prevent that the text clashes into \large.
-#     This is only dangerous when <text> begins with a letter.
-#  b) ... contains another, not expanded new command.
-#     This happens during &expand_body.
-#     In this case, make sure to &tokenize the body before giving
-#     the result to the caller. Also take care that leading letters
-#     of the body cannot clash into \large.
-#  e) ... contains a macro not known as new command:
-#     Make sure that the macro cannot clash with the ensuing yyy.
-#  f) ... is empty:
-#     Make sure that \large cannot clash with yyy.
-# 6. We prevent clashing by inserting a delimiting blank.
-#    Out of the scetched situation, there are three conditions to
-#    take care of:
-#  a) empty body, left a letter command, right a letter => blank
-#  b) body starts with letter, left a letter command    => blank
-#  c) body ends with letter command, right a letter     => blank
-#  d) else => no blank, clash all together, it will work.
-# 7. With this rules, the expansion should work quite well,
-#    concerning letter/non-letter commands and white space
-#    handling.
-# 8. Deficiencies:
-# 8.1 Consider \this<CR>that. It's handled this way:
-#  a) The \this swallows the <CR> in LaTeX, but what LaTeX2HTML does
-#     is to &tokenize the expression into \this <CR>that.
-#  b) If ... is some text, it results in <text><CR>that.
-#  c) If ... is a macro (or command, or control sequence, these
-#     terms are often mixed up, but effectively mean the same),
-#     then if the macro later takes at least one argument, the <CR>
-#     might get swallowed, this depends on the grace of $next_pair_rx
-#     resp. $next_pair_pr_rx.
-#     If the macro takes no arguments, the <CR> remains in the text.
-#  d) If ... ends in another new command, the problem repeats.
-# 8.2 The new commands are substituted in a very insensitive way.
-#     If \this occurs within an environment which sees \this
-#     totally different, there's no chance to substitute \this in
-#     a different way.
-# 8.3 In relation to 8.2 a similar problem arises when the meta
-#     command, or several meta commands redefining \this, occur
-#     amongst several \this macros.
-# 8.4 In raw TeX like environments it is not possible to revert the
-#     expansion of \this, but \this probably *must* occur in its
-#     raw form.
-
-# Handle the cases as depicted in the description of new command
-# substitution.
-    local($befdel,$aftdel);
-    $befdel = ' '
-       if ($before=~/(^|[^\\])\\[a-zA-Z]+$/ && /^$/ && $after=~/^[a-zA-Z]/) ||
-           ($before=~/(^|[^\\])\\[a-zA-Z]+$/ && /^[a-zA-Z]/);
-    $aftdel = ' '
-       if /(^|[^\\])\\[a-zA-Z]+$/s && $after=~/^[a-zA-Z]/;
-    join('', $befdel, $_, $aftdel);
-}
-
-#RRM:  use this to test whether a specific command is substituting correctly
-sub trace_cmd {
-    local($this) = @_;
-    if ($cmd eq $this) { print "\n$1=>$id:$2::"}
-}
-
-# Make the text unique (give unique id's to the brackets).
-# The text shouldn't contain processed brackets.
-sub make_unique {
-    # MRO: Change to references $_[0]
-    # local(*_) = @_;
-    my $id = $global{'max_id'};
-    # MRO: replaced $* by /m
-    # this looks quite funny but is optimized
-    1 while($_[0] =~ s/$O(\d+)$C([\w\W]*)$O\1$C/$id++;"\000$id $2\000$id "/geom);
-    $_[0] =~ s/\000(\d+) /$O$1$C/gom;
-    $global{'max_id'} = $id;
-}
-
-#RRM: this shouldn't be needed, but just in case...
-sub make_unique_p {
-    # MRO: Change to references $_[0]
-    my $id = $global{'max_id'};
-    # MRO: replaced $* by /m
-    # this looks quite funny but is optimized
-    1 while($_[0] =~ s/$OP(\d+)$CP([\w\W]*)$OP\1$CP/$id++;"\000$id $2\000$id "/geom);
-    $_[0] =~ s/\000(\d+) /$OP$1$CP/gom;
-    $global{'max_id'} = $id;
-}
-
-
-sub substitute_newenv {
-    # Modifies $cmd and $after in the caller
-    # Get the body from the new_environment array
-    local($argn, $begdef, $enddef, $opt) = split(/:!:/, $new_environment{$cmd});
-    local($arg,$new_def_rx,$tmp,$cnt);
-
-    # Note that latex allows argument substitution only in the
-    # \begin part of the new definition
-    foreach $i (1..$argn) {    # Process the arguments
-       if (($i == 1) && ($opt ne '}')) {
-           $after =~ s/$optional_arg_rx/$arg = $1;''/eo;
-           $arg = $opt unless $arg;
-       }
-       else {
-           $after =~ s/$next_pair_rx/$arg = $2;''/eo;
-       }
-       $arg =~ s/(^|[^\\])\\\#/$1$hash_mark/g;
-       $arg =~ s/\#/$param_mark/g;
-
-        #RRM: multiple instances can fail later in  &make_unique
-#       s/\#$i/$arg/g;          # Substitute the arguments in the body
-        #RRM: ...so do one at a time and  &make_unique_p
-        $tmp = $begdef;
-        $cnt = $tmp =~ s/\#$i//g ;
-        if ($cnt > 1) {
-            $tmp = $begdef;
-            while ($cnt > 1) {
-               if ( $begdef =~ s/\#$i/$arg/) { 
-                   &make_unique($begdef) if ($arg =~ /$O/ ); 
-                   &make_unique_p($begdef) if ($arg =~ /$OP/ );
-               }
-                $cnt--;
-            }
-            $tmp = $_;
-        }
-        $begdef =~ s/\#$i/$arg/ ;
-        print "\n *** substitution: $arg \nfor \#$i in {$cmd} did not take ***\n"
-           if ($begdef =~ /\#$i/);
-       &write_warnings("incomplete substitution in a {$cmd} environment:\n$begdef")
-           if ($begdef =~ /\#$i/);
-    }
-    $begdef =~ s/$param_mark/\#/g;
-    $begdef =~ s/$hash_mark/\\\#/g;
-    $begdef =~ s/(\\\w+)$/$1 /s;
-
-    # Make the body unique (Give unique id's to the brackets),
-    # translate, and return it
-#RRM: when are these needed ?
-#    $_ = &revert_to_raw_tex($_);
-#    &pre_process;
-
-    &make_unique($begdef);             # Make bracket IDs unique   
-    print STDOUT "\nBEGIN:$cmd:$begdef" if ($VERBOSITY > 4);
-
-    # Now substitute the \end part:
-#RRM: when are these needed ?
-#    $_ = &revert_to_raw_tex($enddef);
-#    &pre_process;
-
-    &make_unique($enddef);             # Make bracket IDs unique
-    print STDOUT "\nEND:$cmd:$enddef" if (($enddef)&&($VERBOSITY > 4));
-    $enddef =~ s/(\\\w+)$/$1 /s;
-
-    local($new_end_def_rx) = &make_end_env_rx($cmd);
-    if (($enddef)&&!($after =~ s/\n?$new_end_def_rx/$enddef/ )) {
-        $UNFINISHED_ENV = $new_end_def_rx;
-        $REPLACE_END_ENV = $enddef;
-    };
-    join('',$begdef,$after);
-}
-
-sub substitute_pars {
-    s/((\%|$comment_mark\d*)|.)(\r*\n[ \t]*){2,}[ \t]*/$1\n\\par \n/og;
-#    s/((\%|$comment_mark\d*)|\d|.)[\r\n\015]{2,}/print "\nPAR:".$`.$&;"$1\n\\par \n"/egs;
-}
-
-sub do_cmd_end { #RRM:  catches the end of any unclosed environments
-    local($_) = @_;
-    &missing_braces unless (
-       (s/$next_pair_pr_rx//o)||(s/$next_pair_rx//o));
-    s/^\n//;
-    $_;
-}
-
-# Removes the definition from the input string, 
-# adds to the preamble unless it is part of the preamble already
-# and stores the body in %new_command;
-sub get_body_newcommand {
-    local($newed, $n_after) = &process_body_newcommand(0,@_);
-    (($PREAMBLE)? "newed".$newed : '');
-}
-
-sub process_body_newcommand {
-#    local($renewed,*_) = @_;
-    local($renewed,$after_R) = @_;
-    local($_) = $$after_R;
-    local($no_change) = $_;
-    local($argn,$newcmd,$cmd_br,$body,$body_br,$tmp,$tmp1,$opt,$pat);
-    local($new_cmd) = 'command';
-    if ($renewed =~ /provide/||$renewed == 2) {
-       # $newcmd = &missing_braces unless (
-       ($newcmd,$pat) = &get_next(1) unless (
-               (s/$next_pair_pr_rx/$pat=$&;$newcmd=$2;''/e)
-               ||(s/$next_pair_rx/$pat=$&;$newcmd=$2;''/e));
-       if (!$pat) {
-           local($br_id) = ++$global{'max_id'};
-           $pat = "$O$br_id$C".$newcmd."$O$br_id$C";
-       }
-    } else {
-       ($newcmd,$pat) = &get_next(1); # Get command name
-    }
-    $pat =~ s/\\//; $new_cmd .= $pat;
-    $newcmd =~ s/^\s*\\//;
-    ($argn,$pat) = &get_next(0);       # Get optional no. of args
-    $argn = 0 unless $argn; $new_cmd .= $pat if $argn;
-    local($cmd) = $newcmd;
-
-    # Get the body of the code and store it with the name and number of args
-    # UNLESS THE COMMAND IS ALREADY DEFINED
-    # ...in which case $ALLOW_REDEFINE must also have been set.  # RRM
-    # (This is the mechanism with which raw html can be ignored in a Latex document
-    # but be recognised as such by the translator).
-    $opt = '}';                        # Flag for no optional arg
-    local($bodyA) = '';
-    if (/^\[/) {
-       ($opt,$pat) = &get_next(0);
-       $new_cmd .= $pat;
-       $bodyA .= "\n".'($dummy, $pat) = &get_next_optional_argument;' .
-                    "\n". '$args .= $pat;';
-    }
-    local($nargs) = $argn;
-    while ($nargs > 0) { $nargs--;
-       $bodyA .=
-           "\n".'$args .= $`.$& if ((s/$next_pair_pr_rx//o)||(s/$next_pair_rx//o));';
-    }
-    if ($renewed =~ /provide/||$renewed == 2 ) {
-        $body = &missing_braces unless (
-               (s/$next_pair_pr_rx/$pat=$&;$body=$2;''/e)
-               ||(s/$next_pair_rx/$pat=$&;$body=$2;''/e));
-       $new_cmd .= $pat;
-    } else {
-       ($body,$pat) = &get_next(4);  #get the body
-       $new_cmd .= $pat;
-    }
-
-    local($thisone);
-#    $thisone = 1 if ($cmd =~ /div|vec/);  # for debugging
-
-    $tmp = "do_cmd_$cmd";
-    local($wtmp) = "wrap_cmd_$cmd";
-    if ((defined &$tmp)||(defined &$wtmp)){
-       # command already exists, so \providecommand  does nothing
-       # but may still be needed in  images.tex
-       $$after_R = $_;
-       return ($new_cmd) if ($renewed =~ /provide/);
-
-       print "\n*** redefining \\$cmd ***\n";
-       &write_warnings("\nredefining command \\$cmd ");
-       if (!$ALLOW_REDEFINE) {
-           print "*** overriding previous meaning ***\n";
-           &write_warnings("\nprevious meaning of \\$cmd will be lost");
-       }
-#      local($code) = "undef \&$tmp"; eval ($code);
-#      if ($@) {print "\n*** undef \&$cmd failed \n"}
-       if ((!$PREAMBLE)||($renewed>1)) {
-           $new_command{$cmd} = join(':!:',$argn,$body,$opt);
-#          local($code) = "sub $tmp\{\&replace_new_command(\"$cmd\");\}";
-#          eval $code;
-#          print STDERR "\n*** sub do_cmd_$cmd failed:\nPERL: $@\n" if ($@);
-#          &replace_new_command($cmd);
-       }
-
-       $renew_command{$cmd} = 1;
-       &write_mydb("renew_command", $cmd, $renew_command{$cmd});
-        local($padding) = " ";
-        $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/));
-        # Generate a new subroutine
-        local($codeA) = "sub wrap_cmd_$cmd {" . "\n"
-            .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";'
-            . $bodyA
-           . (($thisone)? "\nprint \"\\nwrap $cmd:\".\$args.\"\\n\";" : '')
-            . "\n".'(&make_deferred_wrapper(1).$cmd.'
-            . "\"$padding\"".'.$args.&make_deferred_wrapper(0),$_)}'
-            . "\n";
-        print "\nWRAP_CMD: $codeA " if ($thisone); # for debugging
-        eval $codeA;
-        print STDERR "\n\n*** sub wrap_cmd_$cmd  failed: $@\n" if ($@);
-       $raw_arg_cmds{$cmd} = 1;
-
-    } elsif (($ALLOW_REDEFINE)&&($PREAMBLE < 2)) {
-       print "\n*** redefining \\$cmd ***\n";
-       &write_warnings("\ncommand \\$cmd had no previous definition")
-           if (!($new_command{$cmd}));
-    }
-    if ($renewed && ($PREAMBLE > 1) &&($new_command{$cmd})) {
-       $raw_arg_cmds{$cmd} = 1 ;
-       $renew_command{$cmd} = 1;
-        local($padding) = " ";
-        $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/));
-        # Generate a new subroutine
-        local($codeA) = "sub wrap_cmd_$cmd {" . "\n"
-            .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";'
-            . $bodyA
-           . (($thisone)? "\nprint \"\\nwrap $cmd:\".\$args.\"\\n\";" : '')
-            . "\n".'(&make_deferred_wrapper(1).$cmd.'
-           . "\"$padding\"".'.$args.&make_deferred_wrapper(0),$_)}'
-            . "\n";
-        print "\nWRAP_CMD: $codeA " if ($thisone); # for debugging
-        eval $codeA;
-        print STDERR "\n\n*** sub wrap_cmd_$cmd  failed: $@\n" if ($@);
-
-       &write_mydb("renew_command", $cmd, $renew_command{$cmd});
-    } elsif ($renewed) {
-        $new_command{$cmd} = join(':!:',$argn,$body,$opt);
-    } else {
-       $new_command{$cmd} = join(':!:',$argn,$body,$opt)
-           unless (($PREAMBLE > 1)&&($renew_command{$cmd}));
-    }
-
-    local($this_cmd);
-    $this_cmd = join(''
-       , "command{\\$cmd}"
-       , ($argn ? "[$argn]" :'') 
-       , (($opt =~ /^}$/) ? '' : "[$opt]" )
-       , "{", $body , "}" );
-    $this_cmd = &revert_to_raw_tex($this_cmd);
-    if ($renewed) {
-       if ($renewed=~/provide/){
-           $provide_command{$cmd} = 1;
-           &write_mydb("provide_command", $cmd, $provide_command{$cmd});
-#      } else {
-#          print "\n ** marking $cmd as renewed **";
-#          $renew_command{$cmd} = 1;
-       };
-       if ((!$PREAMBLE)&&($renewed>1)) {
-#          local($this_cmd) = join(''
-#              , "\n\\renewcommand{\\$cmd}"
-#              , ($argn ? "[$argn]" :'') 
-#              , (($opt =~ /^}$/) ? '' : "[$opt]" )
-#              , "{", $body , "}\n" );
-#          $latex_body .= &revert_to_raw_tex($this_cmd);
-           $latex_body .= "\n\\renew". $this_cmd."\n";
-       } else {
-##         &add_to_preamble('command',"\\" . $this_cmd);
-       }
-    } else {
-       &add_to_preamble('command',"\\new" . $this_cmd)
-           unless ($PREAMBLE);
-    }
-    undef $body;
-    if ($renewed == 2) {
-       # there is no output to return
-       $$after_R = $_;
-       return();
-    } 
-
-    if (!$PREAMBLE) {
-       $$after_R = $_;
-       return ($new_cmd) if ($renewed);
-#          $cmd_br =~ s/\\//;
-#      ( join ('', &make_deferred_wrapper(1)
-#          , "\\". ($renewed ? (($renewed =~ /provide/)? 'provid' : 'renew')
-#              : 'new')."edcommand"
-#          , $cmd_br , ($argn ? "[$argn]" :'') 
-#          , ( ($opt =~ /^\}$/ ) ? '' : "[$opt]" ) , $body_br
-#          , &make_deferred_wrapper(0)) , $_ );
-       $new_cmd = join('', "command{\\$cmd}"
-                        , ($argn ? "[$argn]" :'') 
-                        , (($opt =~ /^\}$/) ? '' : "[$opt]" )
-                        , "{", $body , "}" );
-       $new_cmd = &revert_to_raw_tex($new_cmd);
-       &add_to_preamble('command', "\\provide".$new_cmd );
-       $$after_R = $_;
-       return();
-    }
-    $new_cmd =~ s/\\$cmd([\d\W]|$)/$cmd$1/s;
-    $$after_R = $_;
-    $new_cmd;
-}
-
-sub replace_new_command {
-    local($cmd) = @_;
-    local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd});
-    do { ### local($_) = $body;
-        &make_unique($body);
-        } if ($body =~ /$O/);
-    $body =~ s/(^|[^\\])\~/$1\\nobreakspace /g;
-    if ($argn) {
-       do { 
-           local($before) = '';
-           local($after) = "\\$cmd ".$_;
-           $after = &substitute_newcmd;   # may change $after
-           $after =~ s/\\\@#\@\@/\\/o ;
-       };
-    } elsif ($body =~ /\\/) {
-       $body = &translate_commands($body);  # ???
-       $_ = $body . $_;
-    } else { $_ = $body . $_; }
-    $_;
-}
-
-sub get_body_let {
-#    local(*_) = @_;
-    local($_) = @_;
-    local($cmd,$body,$replace,$tmp,$pat);
-    ($cmd,$body) = &get_next_tex_cmd;
-    s/^\s*=?\s*/$body .= $&;''/e;
-    ($replace,$pat) = &get_next_tex_cmd;
-#    return() if ($replace eq $cmd);
-    $body .= $pat;
-    $body = &revert_to_raw_tex($body);
-    &add_to_preamble('', "\\let ".$body );
-    $_[0] = $_;
-    if (($replace eq $cmd)||($cmd="\\")||($cmd =~/(style|size)$/)) {
-       "let ".$body
-    } else {
-       $new_command{$cmd} = join(':!:','',"\\$replace ",'}');
-       '';
-    }
-}
-
-
-#  do not remove the \renewcommand code, since it may be needed
-#  within images. Instead replace it with \renewedcommand;
-#  This will be reverted in &revert_to_raw_tex
-sub get_body_renewcommand {
-    local($ALLOW_REDEFINE) = 1;
-    local($renew, $n_after) = &process_body_newcommand(1,@_);
-    ($renew ? 'renewed' . $renew : '');
-}
-
-sub do_cmd_renewedcommand {
-    local($_) = @_;
-    local($ALLOW_REDEFINE) = 1;
-    &process_body_newcommand(2,\$_);
-    $_ ;
-}
-
-sub get_body_providecommand {
-    local($provide, $n_after) = &process_body_newcommand('provide',@_);
-    (($PREAMBLE && $provide) ? 'provided'.$provide : '');
-}
-
-sub do_cmd_providedcommand{ &do_cmd_renewedcommand(@_) }
-
-sub get_body_DeclareRobustCommand {
-    local($provide, $n_after) = &process_body_newcommand('provide',@_);
-    (($PREAMBLE && $provide) ? 'provided'.$provide : '');
-}
-
-sub get_body_DeclareMathOperator {
-    local($after_R) = @_;
-    local($_) = $$after_R;
-    my $star;
-    s/^\\DeclareMathOperator\s*(\*|star)/$star = $1;''/s;
-    my ($mcmd,$patA) = &get_next(1);
-    my ($mop,$patB) = &get_next(1);
-    if ($star) {
-       $patA .= "${O}0$C\\mathop${O}1$C\\mathrm${patB}${O}1$C${O}0$C".$_;
-    } else {
-       $patA .= "${O}0$C${O}1$C\\mathrm${patB}${O}1$C${O}0$C".$_;
-    }
-    local($provide, $n_after) = &process_body_newcommand('provide',\$patA);
-    $$after_R = $patA;
-    (($PREAMBLE && $provide) ? 'provided'.$provide : '');
-}
-
-sub get_body_DeclareMathOperatorstar {
-    local($after_R) = @_;
-    local($_) = $$after_R;
-    my $star;
-    s/^\\DeclareMathOperator\s*(\*|star)/$star = $1;''/s;
-    my ($mcmd,$patA) = &get_next(1);
-    my ($mop,$patB) = &get_next(1);
-    $patA .= "${O}0$C\\mathop${O}1$C\\mathrm${patB}${O}1$C${O}0$C".$_;
-    local($provide, $n_after) = &process_body_newcommand('provide',\$patA);
-    $$after_R = $patA;
-    (($PREAMBLE && $provide) ? 'provided'.$provide : '');
-}
-
-
-# Removes the definition from the input string, adds to the preamble
-# and stores the body in %new_environment;
-sub get_body_newenvironment {
-    local($newed,$after) = &process_body_newenvironment(0,@_);
-    ( $PREAMBLE ? "newed".$newed : '');
-}
-
-sub process_body_newenvironment {
-#    local($renew,*_) = @_;
-    local($renew,$after_R) = @_;
-    local($_) = $$after_R;
-    local($no_change) = $_;
-    local($argn,$env,$begin,$end,$tmp,$opt,$pat);
-    local($new_env) = 'environment';
-    if ($renew == 2) {
-        $env = &missing_braces unless (
-               (s/$next_pair_pr_rx/$pat=$&;$env=$2;''/e)
-               ||(s/$next_pair_rx/$pat=$&;$env=$2;''/e));
-       $new_env .= $pat;
-    } else {
-       ($env,$pat) = &get_next(1);     # Get the environment name
-       $env =~ s/^\s*\\//; $new_env .= $pat;
-    }
-    ($argn,$pat) = &get_next(0);       # Get optional no. of args
-    $argn = 0 unless $argn; $new_env .= $pat if $argn;
-
-    # Get the body of the code and store it with the name and number of args
-    # UNLESS THE COMMAND IS ALREADY DEFINED (see get_body_newcommand)
-    # ...in which case $ALLOW_REDEFINE must also have been set.  # RRM
-    $opt = '}';                        # Flag for no optional arg
-    if (/^\[/) {
-       ($opt,$pat) = &get_next(0);
-       $new_env .= $pat;
-    }
-    $tmp = "do_env_$env";
-
-    if ($renewed == 2 ) {
-        $begin = &missing_braces unless (
-               (s/$next_pair_pr_rx/$pat=$&;$begin=$2;''/e)
-               ||(s/$next_pair_rx/$pat=$&;$begin=$2;''/e));
-       $new_env .= $pat;
-       $end = &missing_braces unless (
-               (s/$next_pair_pr_rx/$pat=$&;$end=$2;''/e)
-               ||(s/$next_pair_rx/$pat=$&;$end=$2;''/e));
-       $new_env .= $pat;
-    } else {
-       ($begin,$pat) = &get_next(1); $new_env .= $pat;
-       ($end,$pat) = &get_next(1); $new_env .= $pat;
-    }
-    if ((defined &$tmp)&&($ALLOW_REDEFINE)) {
-       print STDOUT "\n*** redefining environment {$env} ***\n";
-       &write_warnings("\nredefined environment {$env} ");
-    }
-    $new_environment{$env} = join(':!:', $argn, $begin, $end, $opt)
-       unless ((defined &$tmp)&&(! $ALLOW_REDEFINE));
-
-    if (!$PREAMBLE) {
-       $new_env = join ('', 
-           , "environment{$env}" 
-           , ($argn ? "[$argn]" : '')
-           , (($opt ne '}')? "[$opt]" : '')
-           , "{$begin}{$end}"
-           );
-       &revert_to_raw_tex($new_env);
-       if ($renew == 2) {
-           $latex_body .= "\n\\".($renew ? 're':'').'new'.$new_env."\n";
-       } else {
-           &add_to_preamble ('environment'
-               , "\\".($renew ? 're':'').'new'.$new_env );
-       }
-       $$after_R = $_;
-       return();
-    }
-    if ($new_env =~ /$sections_rx/) {
-       $new_env = join('', $`,'\csname ',$2,'\endcsname',$3,$');
-    }
-    $new_env =~ s/$par_rx/\\par /g;
-    $$after_R = $_;
-    $new_env;
-}
-
-sub get_body_renewenvironment {
-    local($ALLOW_REDEFINE) = 1;
-    local($renewed, $after) = &process_body_newenvironment(1,@_);
-    'renewed'.$renewed;
-}
-
-sub do_cmd_renewedenvironment {
-    local($ALLOW_REDEFINE) = 1;
-    local($_) = @_;
-    &process_body_newenvironment(2,\$_);
-    $_;
-}
-
-# Instead of substituting as with newcommand and newenvironment,
-# or generating code to handle each new theorem environment,
-# it now does nothing. This forces theorem environments to be passed
-# to latex. Although it would be possible to handle theorem
-# formatting in HTML as it was done previously it is impossible
-# to keep the theorem counters in step with other counters (e.g. equations)
-# to which only latex has access to. Sad...
-sub get_body_newtheorem {
-#    local(*_) = @_;
-    local($after_R) = @_;
-    local($_) = $$after_R;
-    my ($orig, $body) = ($_, '');
-    my ($title, $env, $ctr, $within, $cmd, $tmp, $begin, $end, $pat);
-    my ($new_thm) = 'theorem';
-    # Just chop off the arguments and append to $next_def
-    ($env,$pat) = &get_next(1); $new_thm .= $pat;
-    ($ctr,$pat) = &get_next(0); $new_thm .= $pat;
-    ($title,$pat) = &get_next(1); $new_thm .= $pat;
-    ($within,$pat) = &get_next(0); $new_thm .= $pat;
-
-    #check the style parameters
-    my ($hfont,$bfont,$thm_style);
-    my ($before_thm) = join('',@processed);
-    my ($which,$cmds);
-    while ($before_thm =~ /$theorem_cmd_rx/) {
-       $which = $1;
-       $before_thm = $';
-       $before_thm =~ s/$next_pair_rx/$cmds = $2;''/e;
-       $cmds =~ s/\\/\|/g;  # escape any backslash
-       if ($which =~ /style/) { $thm_style = $cmds }
-       elsif ($which =~ /header/) { $hfont = $cmds }
-       elsif ($which =~ /body/)   { $bfont = $cmds }
-    }
-    $hfont = '['.$hfont.']';
-    $bfont = '['.$bfont.']';
-    $thm_style = '['.$thm_style.']';
-    undef $before_thm;
-
-    if (!($ctr)) {
-       # define the new counter
-       $ctr = $env;
-       do {
-###        local($_) = "\\arabic<<1>>$ctr<<1>>";
-###        $_ = join('',"\\the$within", "." , $_) if ($within);
-           $body = "\\arabic<<1>>$ctr<<1>>";
-           $body = join('',"\\the$within", "." , $body) if ($within);
-           &make_unique($body);
-           $cmd = "the$ctr";
-           $tmp = "do_cmd_$cmd";
-           do {
-                $new_command{$cmd} = join(':!:',0,$body,'}') 
-           } unless (defined &$tmp);
-           &write_mydb("new_command", $cmd, $new_command{$cmd});
-           eval "sub do_cmd_$cmd {\n"
-               . 'local($_,$ot) = @_;'."\n"
-               . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'."\n"
-               . '&translate_commands(' . "\"$body\"" . ");\n}\n";
-           print STDERR "\n*** sub $tmp failed:\n$@\n" if ($@);
-           $raw_arg_cmds{$cmd} = 1;
-           undef $body;
-       };
-       &do_body_newcounter($ctr);
-    } else {
-       do {
-###        local($_) = "\\arabic<<1>>$ctr<<1>>";
-           $body = "\\arabic<<1>>$ctr<<1>>";
-           &make_unique($body);
-           $cmd = "the$env";
-           $tmp = "do_cmd_$cmd";
-           do {
-                $new_command{$cmd} = join(':!:',0,$body,'}') 
-           } unless (defined &$tmp);
-           &write_mydb("new_command", $cmd, $new_command{$cmd});
-           eval "sub do_cmd_$cmd {\n"
-               . 'local($_,$ot) = @_;'
-               . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'
-               . '&translate_commands(' . "\"$body\"" . ");\n}\n";
-           print STDERR "\n*** sub $tmp failed:\n$@\n" if ($@);
-           $raw_arg_cmds{$cmd} = 1;
-           undef $body;
-       };
-    }
-
-    # record the counter dependency
-    &addto_dependents($within,$ctr) if ($within);
-
-    # save the text-label in the %new_theorem hash
-    $new_theorem{$env} = $title;
-
-    # define a new environment
-    my ($id) = ++$global{'max_id'};
-    $begin = "\\begin<<$id>>theorem_type<<$id>>"
-       . "[$env][$ctr][$within]$thm_style$hfont$bfont\n";
-    $id = ++$global{'max_id'};
-    $end = "\\end<<$id>>theorem_type<<$id>>\n";
-    $tmp = "do_env_$env";
-    if ((defined &$tmp)&&($ALLOW_REDEFINE)) {
-       print STDOUT "\n*** redefining theorem environment {$env} ***\n";
-    }
-    $new_environment{$env} = join(':!:', '', $begin, $end, '')
-       unless ((defined &$tmp)&&(! $ALLOW_REDEFINE));
-
-    if (!$PREAMBLE) {
-       my ($new_cmd) = join(''
-           , 'theorem{}' );
-       &add_to_preamble('theorem', "\\new".$new_cmd );
-       $$after_R = $_;
-       return();
-    }
-    $$after_R = $_;
-    'newed'.$new_thm;
-}
-
-sub do_cmd_theoremstyle {
-    local($_) = @_;
-    local($thm_type);
-    $thm_type = &missing_braces unless (
-       (s/$next_pair_pr_rx/$thm_type=$2;''/e)
-       ||(s/$next_pair_rx/$thm_type=$2;''/e));
-#   $THM_STYLE = $thm_type;
-    $_;
-}
-sub do_cmd_theoremheaderfont {
-    local($_) = @_;
-    local($thm_type);
-    $thm_type = &missing_braces unless (
-       (s/$next_pair_pr_rx/$thm_type=$2;''/e)
-       ||(s/$next_pair_rx/$thm_type=$2;''/e));
-#   $THM_HFONT = $thm_type;
-    $_;
-}
-sub do_cmd_theorembodyfont {
-    local($_) = @_;
-    local($thm_type);
-    $thm_type = &missing_braces unless (
-       (s/$next_pair_pr_rx/$thm_type=$2;''/e)
-       ||(s/$next_pair_rx/$thm_type=$2;''/e));
-#   $THM_BFONT = $thm_type;
-    $_;
-}
-
-sub do_env_theorem_type {
-    local($_) = @_;
-    local($dum,$env,$ctr,$within, $label, $name, $title, $text, $index);
-    ($env, $dum) = &get_next_optional_argument;
-    ($ctr, $dum) = &get_next_optional_argument;
-    ($within, $dum) = &get_next_optional_argument;
-
-    local($thm_num, $thm_style);
-    # defaults for plain theorem-style
-    my ($hfont,$bfont) = ('','');
-
-    ($thm_style, $dum) = &get_next_optional_argument;
-    ($hfont, $dum) = &get_next_optional_argument;
-    $hfont =~ s/\|/\\/og;
-    ($bfont, $dum) = &get_next_optional_argument;
-    $bfont =~ s/\|/\\/og;
-
-    # the pre-defined alternative theorem-styles
-    if ($thm_style =~ /definition/) {
-       $bfont = '\normalfont' unless $bfont;
-    } elsif ($thm_style =~ /remark/) {
-       $hfont = '\itshape' unless $hfont;
-       $bfont = '\normalfont' unless $bfont;
-    }
-
-    # defaults for plain theorem-style
-    $hfont = '\bfseries' unless $hfont;
-    $bfont = '\itshape' unless $bfont;
-
-    ($name, $dum) = &get_next_optional_argument;
-    $name = &translate_environments("${O}0$C".$name."${O}0$C") if $name;
-    $name = &translate_commands($name) if ($name =~ /\\/);
-
-    $index = $section_commands{$ctr};
-    if ($index) { 
-       # environment actually starts a new (sub-)section
-       $curr_sec_id[$index]++;
-       local($this) = &translate_commands("\\the$ctr");
-       local($hash) = &sanitize($name." $this");
-       local($section_tag) = join('', @curr_sec_id);
-       $encoded_section_number{$hash} = join($;, $section_tag);
-       &reset_dependents($ctr) if ($dependent{$ctr});
-       $thm_num = &translate_commands("\\the$ctr");
-       $thm_num =~ s/(\w)\.(\.\w)/$1$2/g;
-
-       # construct the sectioning title from the counter values
-       $title = join( '', $new_theorem{$env}, " "
-           , &translate_commands("\\the$ctr") );
-       $toc_section_info{join(' ',@curr_sec_id)} = \
-           "$current_depth$delim$CURRENT_FILE$delim$title"
-               if ($current_depth <= $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH);
-       $section_info{join(' ',@curr_sec_id)} = \
-           "$current_depth$delim$CURRENT_FILE$delim$title$delim";
-       $title = join('',"<A NAME=\"SECTION$section_tag\"><B>"
-                     , $title , "</B></A>" );
-    } else {
-       if ($ctr) {
-           print STDOUT "\nSTP:$ctr:+1" if ($VERBOSITY > 3);
-           $global{$ctr}++;
-           print STDOUT "=".$global{$ctr}." " if ($VERBOSITY > 3);
-           &reset_dependents($ctr) if ($dependent{$ctr});
-           $thm_num = "\\the$ctr ";
-       } else { $thm_num = ''; }
-
-       # construct the full title from the counter values
-       $title = $new_theorem{$env};
-       if (($thm_style =~ /margin/)&&($HTML_VERSION > 2.1)) {
-           # don't use the number yet
-       } elsif ($thm_style =~ /change/) {
-           $title = join(' ', $thm_num, "\\space", $title)
-       } else {
-           $title = join(' ', $title, "\\space", $thm_num);
-       }
-
-       if ($hfont) {
-           $title = join('',$O,++$global{'max_id'},$C,$hfont," "
-                     , $title, $O,++$global{'max_id'},$C);
-           $title = &translate_environments($title);
-           $title = &translate_commands($title);
-       } else {
-           $title = join('',"<B>",&translate_commands($title),"</B>");
-       }
-       $title =~ s/(\w)\.(\.\w)/$1$2/g;
-    }
-    # extract any name or label that may occur at the start
-    s/^\s*(\\label(($O|$OP)\d+($C|$CP))([^<]*)\2)?\s*(\(([^\)]*)\))?/
-       $label=$1; $text=$5; $name=$7 if ($7); ''/eo;
-    if ($label) {
-       $label = &anchor_label($text,$CURRENT_FILE,'');
-       $label =~ s/$anchor_mark/$title/;
-       $title = $label;
-    }
-    if ($name) {
-       $name =~ s/^\s*|\s*$//g; 
-       $name = join('', " (", $name, ") ") if $name;
-    }
-    local($attribs, $border);
-    if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-    elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-
-    $_ = join('', $O,++$global{'max_id'},$C, $bfont
-           , " ", $_ ,$O,++$global{'max_id'},$C) if ($bfont);
-
-    my($cmd) = 'do_thm_'.$env;
-    if (defined &$cmd) {
-       $_ = &$cmd($ctr, $title, $_);
-    } else {
-       $_ = &translate_environments($_);
-       $_ = &translate_commands($_);
-    }
-
-    if ($thm_style =~ /margin/) {
-       local($valign);
-       $valign = ($NETSCAPE_HTML ? ' VALIGN="BASELINE"':'');
-       if ($hfont) {
-           $thm_num = join('',$O,++$global{'max_id'},$C,$hfont," "
-                     , $thm_num, $O,++$global{'max_id'},$C);
-           $thm_num = &translate_environments($thm_num);
-           $thm_num = &translate_commands($thm_num);
-       } else {
-           $thm_num = join('',"<B>",&translate_commands($thm_num),"</B>");
-       }
-       $thm_num =~ s/(\w)\.(\.\w)/$1$2/g;
-
-       # code copied from  &make_table
-       local($Tattribs);
-       if ($attribs) {
-           if (!($attribs =~ /=/)) {
-               $Tattribs = &parse_valuesonly($attribs,"TABLE");
-           } else {
-               $Tattribs = &parse_keyvalues($attribs,"TABLE");
-           }
-           $Tattribs = ' '.$Tattribs if ($Tattribs);
-       }
-       $_ = join ('', "\n<P><DIV$env_id><TABLE"
-               , (($border) ? " BORDER=\"$border\"" : '')
-               , $Tattribs , ">\n<TR VALIGN=\"TOP\">"
-               , "<TD$valign>", &translate_commands($thm_num)
-               , "</TD>\n<TD>", $title, $name
-               , (($thm_style =~ /break/)? "\n<BR>":" \&nbsp; \n")
-               , $_ , "\n</TD></TR></TABLE></DIV>");
-    } else {
-       $_ = join('', "<P><DIV$env_id>"
-               , $title, $name
-               , (($thm_style =~ /break/)? "\n<BR>":" \&nbsp; \n")
-               , $_
-               ,"</DIV><P></P>\n");
-       if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 
-           &make_table( $border, $attribs, '', '', '', $_ ) 
-       } else { $_ }
-    }
-}
-
-# Modifies $_ in the caller and as a side-effect it modifies $next_def
-# which is local to substitute_meta_cmds
-sub get_next {
-    local($what) = @_;
-    local($next, $pat, $tmp);
-    if ($what == 1) {
-       ($next, $tmp, $pat) = &get_next_argument;
-    }
-    elsif ($what == 2) {
-       ($next, $pat) = &get_next_tex_cmd;
-    }
-    elsif ($what == 3) {
-       ($next, $pat) = &get_next_def_arg;
-    }
-    elsif ($what == 4) {
-       ($next, $tmp, $pat) = &get_next_argument;
-    }
-    else {
-       ($next, $pat) =  &get_next_optional_argument;
-    }
-    do {
-       $next_def .= &revert_to_raw_tex($pat) if $pat;
-    } unless ($renewed); # don't add \renewcommand to preamble
-#    $next =~ s/(^\s*)|(\s*$)//g unless ($what == 4); #don't lose white space on body
-    $next =~ s/(^\s*)|(\s*$)//g unless ($what =~ /[14]/); #retain white space in body
-    ($next, $pat);
-}
-
-# The following get_next_<something> ARE ALL DESTRUCTIVE.
-sub get_next_argument {
-    local($next, $br_id, $pat);
-    if (!(s/$next_pair_rx/$br_id=$1;$next=$2;$pat=$&;''/seo)) {
-       print " *** Could not find argument for command \\$cmd ***\n";
-       print "$_\n";
-    };
-    ($next, $br_id, $pat);
-}
-
-sub get_next_pair_or_char_pr {
-    local($next, $br_id, $pat, $epat);
-    if ( /^\{([^\}]*)\}/o && (! $`)) {
-       ($next, $pat) = ($1, $&);
-    } elsif ( (/^\s*([^\s\\<])/o && (! $`))) {
-       ($next, $pat) = ($1, $&);
-    } elsif ( /$next_pair_pr_rx/o && (! $`)) {
-       ($next, $br_id, $pat) = ($2, $1, $&);
-    };
-    $epat = &escape_rx_chars($pat);
-    s/$epat// if $pat;
-    ($next, $br_id, $pat);
-}
-
-sub get_next_optional_argument {
-    local($next, $pat);
-    s/$optional_arg_rx/$next=$1;$pat=$&;''/eo
-       if (/\s*[[]/ && (! $`)); # if the first character is a [
-    #remove trailing spaces and/or comments
-    s/^($comment_mark(\d+\n?)?|$EOL)//gos;
-
-    # if  nested inside {}s  we need to get more tokens  
-    if ($pat) {
-       # check for \item, indicating something has gone wrong
-       if ($pat =~ /\\item\b/ ) {
-           print "\n*** optional argument badly formed:\n" . $pat . "\n\n";
-           $_ = $pat . $_;
-           return('','');
-       }
-       # check for being nested inside {}s
-       local($found) = $pat;
-       while ($found =~ s/$O(\d+)$C[\s\S]*$O\1$C//g) {
-           if ($found =~ /$O(\d+)$C/) {
-               local($br_id) = $1;
-               if (s/$O$br_id$C//) {
-                   $found .= $`.$&;
-                   $pat .= "]".$`.$&;
-                   $next .= "]".$`.$&;
-                   $_ = $';
-                   s/^([^]]*)\]/$next.=$1;$pat.=$&;''/e;
-                   $found .= $&;
-               } else { last } # give up if no closing brace
-           }
-       }
-    } else {
-       s/^\s*\[\]/$pat=$&;''/e; # This is not picked by $optional_arg_rx
-    }
-    ($next, $pat);
-}
-
-#JCL(jcl-del) - use new form of $single_cmd_rx.
-sub get_next_tex_cmd {
-    local($next, $pat);
-    s/^\s*\=?\s*$single_cmd_rx/$4/;
-    ($next, $pat) = ($1.$2,"\\".$1.$2);
-}
-
-sub get_next_def_arg {
-    local($next, $pat);
-
-    # Sets is_simple_def for caller.  Start by turning it off, then
-    # turn it on if we find one of the "simple" patterns.
-
-    # This has got to be hit-or-miss to an extent, given the
-    # thoroughly incestuous relationship between the TeX macroprocessor
-    # ('mouth') and typesetting back-end ('stomach').  Anything which
-    # even does catcode hacking is going to lose BAD.
-
-    s/^\s*//so;                        # Remove whitespace
-
-    $is_simple_def = 0;
-
-    # no arguments
-
-    if (/^$O/ && (! $`)) { $next=0; $pat=''; $is_simple_def=1; }
-
-    # 'simple' arguments
-
-    if (! $is_simple_def && /$tex_def_arg_rx/o && (! $`)) {
-       s/$tex_def_arg_rx/$next=$1; $pat=$&; $is_simple_def=1; $2/seo; }
-
-    # MESSY arguments
-
-    if (! $is_simple_def) {
-       print "Arguments to $cmd are too complex ...\n";
-       print "It will not be processed unless used in another environment\n";
-       print "which is passed to LaTeX whole for processing.\n";
-
-       s/^[^<]*(<[^<]+)*<</$next=''; $pat=$&; $O/seo;
-    }
-
-    $pat =~ s/$O$//so;
-
-    ($next, $pat);
-}
-
-#### Key-value parsing added by RRM
-#
-#   This cleans-up the key-value pairs for a given tag, 
-#   by removing unnecessary spaces and commas, inserting quotes
-#   around the value and puts a preceding space.
-#   The key becomes upper-case, while the value becomes lower-case.
-#   If specific `tags' are provided, then checking is done to verify 
-#   that the keys and values are valid for these tags, eliminating
-#   any that are not; unmatched keys or values are handled as well.
-#   If no tags are provided, then just a list of pairs is returned.
-#
-sub parse_keyvalues {
-    local($_,@tags) = @_;
-    local($key,$KEY,$attribs,$atts,%attributes)=('','','','');
-
-    # beware active " in german
-    local($is_german);
-    if (s/\&#34;/'/g) { 
-       $is_german=1;
-       s/(^|[\s,=])(\&\#\d\d\d;)/$1'$2/g
-    }
-    local($saved) = &revert_to_raw_tex(&translate_commands($_));
-    print "\nATTRIBS: $saved\n" if ($VERBOSITY > 6);
-
-    $saved =~ s/$percent_mark/%/g;
-    $saved =~ s/((^|[\s,=])')\\\W{(\w)}/$1$3/g
-       if $is_german;  #unwanted accents, from active "
-    if (@tags) {
-       foreach $tag (@tags) {
-           $_ = $saved;
-           local($name)= $tag."_attribs";
-           $taglist = $$name;
-           $name .= "_rx_list";
-           $taglist .= $$name;
-           $taglist =~ s/,,/,/;
-#          s/(^|,)\s*([a-zA-Z]+)\s*\=\s*"?([\#\%\w\d]+)"?\s*/$attributes{$2}="$3";''/eg;
-#          s/(^|,)\s*([a-zA-Z]+)\s*\=\s*(\"([^"]*)\"|\'([^\']*)\'|([#%\w\d]*))\s*/
-#          s/(^|,)\s*([a-zA-Z]+)\s*\=\s*(\"([^"]*)\"|\'([^\']*)\'|([#%&@;:+-\/\w\d]*))\s*/
-           s/(^|,)\s*([a-zA-Z]+)\s*\=\s*(\"([^"]*)\"|\'([^\']*)\'|([^<>,=\s]*))\s*/
-               $attributes{$2}=($4?$4:($5?$5:$6));' '/eg;
-           foreach $key (keys %attributes){ 
-               $KEY = $key;
-               $KEY =~ tr/a-z/A-Z/;
-               if ($taglist =~ /,$KEY,/i) {            
-                   local($keyname) = $tag."__".$KEY; 
-                   local($keyvalues) = '';
-                   if ($$keyname) {
-                       $keyvalues = $$keyname;
-                       $atts = $attributes{$key};
-                       if ($keyvalues =~ /\,$atts\,/i ) {
-#                          $atts =~ tr/A-Z/a-z/;
-                           $attribs .= " $KEY=\"$atts\"";
-                           print "\n$KEY=$atts " if ($VERBOSITY > 3);
-                       } else { &invalid_tag($tag,$KEY,$atts); }
-                   } else {    # test for a regular expression
-                       $keyname = $keyname."_rx";
-                       if ($$keyname) {
-                           $keyvalues = $$keyname;
-                           $atts = $attributes{$key};
-                           if ($atts =~ /$keyvalues/) {
-#                              $atts =~ tr/A-Z/a-z/;
-                               $attribs .= " $KEY=\"$atts\"";                          
-                               print "\n$KEY=$atts " if ($VERBOSITY > 3);
-                           } else { &invalid_tag($tag,$KEY,$atts) }
-                       } else {
-                           $atts = $attributes{$key};
-#                          $atts =~ tr/A-Z/a-z/;
-                           $attribs .= " $KEY=\"$atts\"";
-                           print "\n$KEY=$atts " if ($VERBOSITY > 3);
-                       }
-                   }
-               } else {
-                   print "\n$key not in $taglist for $tag" if ($VERBOSITY > 3);
-               }
-           }
-       }
-        s/(^|\s,)\'([^\s,]*)\'(\s|$)/$1$2 /g if $is_german;
-       $attribs .= &parse_valuesonly($_,@tags);
-    } else {
-       # with no tags provided, just list the key-value pairs
-       $_ = $saved;
-       s/\s*(\w+)\s*=\s*\"?(\w+)\"?\s*,?/$attributes{$1}=$2;''/eg;
-       foreach $key (keys %attributes){ 
-           $KEY = $key;
-           $KEY =~ tr/a-z/A-Z/;
-           $atts = $attributes{$key};
-           $atts =~ tr/A-Z/a-z/;
-           $attribs .= " $KEY=\"$atts\"";
-       }
-    }
-    $attribs;
-}
-
-sub invalid_tag {
-    local($tag,$key,$value) = @_;
-    &write_warnings("$key=$value is an invalid value in the <$tag> tag\n");
-}
-
-# RRM
-#   This creates key-value pairs from values only, 
-#   by checking whether the data matches any key to the provided tags.
-#   Only the first match found is retained.
-#   Attributes with no values are also recognised here.
-#
-sub parse_valuesonly {
-    local($values,@tags) = @_;
-    local($i,$tag,$key,$KEY,$attribs,$atts)=(0,'','','','','');
-    local($saved) = &revert_to_raw_tex(&translate_commands($values));
-    $saved =~ s/$percent_mark/%/g;
-    foreach $tag (@tags) {
-       local($name)= $tag."_attribs";
-       $taglist = $$name;
-       $values = $saved;
-        $values =~ s/\s*\"?([^,\s\"]+)\"?\s*,?/$i++;$attributes{$i}=$1;''/eg;
-        local($j) = 0;
-       while ($j < $i) {
-           $j++;
-           $key = $attributes{$j};
-           if ($taglist =~ /,$key,/i) {
-               $KEY = $key;
-               $KEY =~ tr/a-z/A-Z/;
-               $attribs .= " $KEY";
-               print " $KEY" if ($VERBOSITY > 3);
-           } else {
-               $atts = $attributes{$j};
-               $key = &find_attribute($key,$tag);
-               if ($key) {
-                   $KEY = $key;
-                   $KEY =~ tr/a-z/A-Z/;
-                   $atts =~ tr/A-Z/a-z/;
-                   $attribs .= " $KEY=\"$atts\"";
-                   print " $KEY = $atts" if ($VERBOSITY > 3);
-               } else { }
-           }
-       }
-    }
-    $attribs;
-}
-
-# RRM
-#   Extracts key-value pairs using a supplied (comma-separated) list.
-#   When no list is given, it checks for a pre-defined list for the tag.
-#   
-sub extract_attributes {
-    local($tag,$taglist,$_) = @_;
-    local($key,$attribs,$unused,%attributes);
-    if (! ($taglist)) {
-       local($name) = "$tag"."_attribs";
-       if ($$name) { $taglist = $$name }
-    }
-    s/\s*(\w+)\s*=\s*\"?(\w+)\"?\s*,?/$attributes{$1}=$2;''/eg;
-    foreach $key (keys %attributes){ 
-       if ($taglist =~ /\,$key\,/) {
-           $attribs .= " $key=\"$attributes{$key}\"";
-           &write_warnings("valid attribute $key for $tag\n");
-       } else {
-           &write_warnings("unknown attribute $key for $tag\n");
-           $unused .= " $key=\"$attributes{$key}\"";
-       }
-    }
-    ($attribs,$unused);
-}
-
-# RRM
-#   Finds the attribute of a given tag, for which a given value is valid.
-#   Requires variables: <tag>_<key> to be a comma-separated list of keys.
-#   So far it cannot recognise data-types, only names.
-#
-sub find_attribute {
-    local($key,$attrib,$tag) = ('',@_);
-    local($name) = $tag."_attribs";
-    local($attrib_list)=$$name;
-    if ($attrib_list) {
-       $attrib_list =~ s/^\,//o;
-       $attrib_list =~ s/\,$//o;
-       local(@keys) = split(',',$attrib_list);
-       local($attrib_vals) = '';
-       foreach $key (@keys) {
-           $name = $tag."__".$key;
-           $attrib_vals = $$name;
-           return ($key) if ($attrib_vals =~ /\,$attrib\,/i ); 
-       }
-    }
-    $name = $tag."_attribs_rx_list";
-    $attrib_list=$$name;
-    if (!($attrib_list)) { return(); }
-    $attrib_list =~ s/^\,//o;
-    $attrib_list =~ s/\,$//o;
-    @keys = split(',',$attrib_list);
-    foreach $key (@keys) {
-       next if ($attribs =~ / $key=/);
-       $name = $tag."__".$key."_rx";
-       $attrib_vals = $$name;
-       if ( $attrib =~ /^$attrib_vals$/ ) { 
-           return ($key);
-       }
-    }
-    0;
-}
-
-# in case \HTML is defined differently in packages
-sub do_cmd_HTML { &do_cmd_HTMLcode(@_) }
-
-sub do_cmd_HTMLcode {
-    local($_) = @_;
-    local($tag,$attribs,$dum);
-    local($attribs, $dum) = &get_next_optional_argument;
-    $tag = &missing_braces unless (
-       (s/$next_pair_pr_rx/$tag = $2;''/eo)
-       ||(s/$next_pair_rx/$tag = $2;''/eo));
-    $tag = &translate_commands($tag) if ($tag =~ /\\/);
-    if (! $tag) {
-       print "*** no tag given with \\HTML command, ignoring it";
-       return($_);
-    }
-    local($afterHTML) = $_;
-    local($value,$TAGattribs,$etag);
-    if (defined $unclosed_tags_list{$tag}) {
-    } elsif (defined $closed_tags_list{$tag}) {
-       $value = &missing_braces unless (
-           (s/$next_pair_pr_rx/$value = $2;''/eo)
-           ||(s/$next_pair_rx/$value = $2;''/eo));
-       $etag = "</$tag>";
-       $afterHTML = $_;
-    } else {
-       print "\n*** <$tag> is not a valid tag for HTML $HTML_VERSION";
-       print "\n rejecting: \\HTML".(($attribs)? "[$attribs]" : '')."{$tag}";
-       return $_ ;
-    }
-    if ($dum) {
-       $attribs = &translate_commands($attribs) if ($attribs=~/\\/);
-        if ($attribs) {
-            if (!($attribs =~ /=/)) {
-                $TAGattribs = &parse_valuesonly($attribs,$tag);
-            } else {
-                $TAGattribs = &parse_keyvalues($attribs,$tag);
-            }
-        }
-    } else { }  # default if no [...]
-    local($needed) = join(','
-           , $closed_tags_list{$tag},$unclosed_tags_list{$tag});
-    $needed =~ s/,,/,/g; $needed =~ s/^,|,$//g;
-    if ($TAGattribs) {
-       if ($needed) {
-           $needed =~ s/,,/,/g;
-           local($this, @needed);
-           (@needed) = split(',',$needed);
-           foreach $this (@needed) {
-               next unless ($this);
-               next if ($TAGattribs =~ /\b$this\b/);
-               print "\n*** attribute $this required for <$tag> ***";
-               print "\n rejecting: \\HTML".(($attribs)? "[$attribs]" : '')."{$tag}";
-               return($value.$afterHTML);
-           }
-       }
-       $value = &translate_environments($value);
-       $value = &translate_commands($value) if ($value =~ /\\/);
-       $_ = join('', "<$tag", $TAGattribs, ">", $value, $etag);
-   } elsif ($needed) {
-       print STDOUT "\n*** attributes $needed are required for <$tag> ***";
-       return($value.$after);
-    } elsif ($value) {
-       $value = &translate_environments($value);
-       $value = &translate_commands($value) if ($value =~ /\\/);
-       $_ = join('', "<$tag>", $value, $etag);
-    } else {
-       $_ = join('', "<$tag>", $etag);
-    }
-    $_.$afterHTML; 
-}
-
-sub do_cmd_HTMLget {
-    local($_) = @_;
-    local($which,$value,$hash,$dummy);
-    local($hash, $dummy) = &get_next_optional_argument;
-    $which = &missing_braces unless (
-       (s/$next_pair_pr_rx/$which = $2;''/eo)
-       ||(s/$next_pair_rx/$which = $2;''/eo));
-    if ($hash) {
-       local($tmp) = "\%$hash";
-       if (eval "defined \%{$hash}") { $! = '';
-           $value = ${$hash}{'$which'};
-       } else { print "\nhash: \%$hash not defined" }
-    } elsif ($which) {
-       $value = ${$which};
-    }
-    $value.$_;
-}
-
-sub do_cmd_HTMLset {
-    local($_) = @_;
-    local($which,$value,$hash,$dummy);
-    local($hash, $dummy) = &get_next_optional_argument;
-    $which = &missing_braces unless (
-       (s/$next_pair_pr_rx/$which = $2;''/eo)
-       ||(s/$next_pair_rx/$which = $2;''/eo));
-    $value = &missing_braces unless (
-       (s/$next_pair_pr_rx/$value = $2;''/eo)
-       ||(s/$next_pair_rx/$value = $2;''/eo));
-    if ($hash) {
-       local($tmp) = "\%$hash";
-       if (eval "defined \%{$hash}") { $! = '';
-#          eval "\$$hash{'$which'} = \"$value\";";
-           ${$hash}{'$which'} = $value;
-           print "\nHTMLset failed: $! " if ($!);
-       } else { print "\nhash: \%$hash not defined" }
-    } elsif ($which) { $! = '';
-       eval "\${$which} = \"$value\";";
-       print "\nHTMLset failed: $! " if ($!);
-    }
-    $_;
-}
-
-sub do_cmd_HTMLsetenv { &do_cmd_HTMLset(@_) }
-
-####
-
-
-# Appends $next_def to the preamble if it is not already there.
-sub add_to_preamble {
-    local($type, $next_def) = @_;
-    local($name);
-    if ($type =~ /def|include|special|graphicspath/) {
-        local($pat) = &escape_rx_chars ($next_def);
-#      $preamble .= $next_def . "\n" unless ($preamble =~ /$pat/);
-       push(@preamble, $pat); 
-    } 
-    elsif ($type =~ /command|environment|theorem|counter/) {
-       push(@preamble, $next_def ); 
-    }
-    else {
-       ($name) = $next_def =~ /$marker\s*({[^}]+})/; # matches type{name}
-       $name = &escape_rx_chars($name);
-#      $preamble .= $next_def . "\n" unless ($preamble =~ /$marker\s*$name/);
-       push(@preamble, $name ); 
-    }
-}
-
-sub make_latex{
-# This is the environment in which to process constructs that cannot be
-# translated to HTML.
-# The environment tex2html_wrap will be wrapped around any shorthand
-# environments (e.g. $, \(, \[).
-# The tex2html_wrap environment will be treated as an unrecognised
-# evironment by the translator and its contents (i.e. the 'shorthand'
-# environment) will be passed to latex for processing as usual.
-    local($contents) = @_;
-    local($preamble) = $preamble;
-    local($aux_preamble) = $aux_preamble;
-    while ($preamble =~ s/^(\@.*\n)/$prelatex .= $1;''/e) {}
-    print "\nPRE-LATEX: $prelatex" if (($prelatex)&&($VERBOSITY > 1));
-
-    %newed_commands =
-        ( 'newedcommand' , 'newcommand'
-        , 'renewedcommand' , 'renewcommand'
-        , 'providedcommand' , 'providecommand'
-        , 'newedenvironment' , 'newenvironment'
-        , 'newedboolean' , 'newboolean'
-        , 'newedcounter' , 'newcounter'
-        , 'newedtheorem' , 'newtheorem'
-        , 'newedfont' , 'newfont' , 'newedif', 'newif'
-        );
-                    
-
-    # Make the @ character a normal letter ...
-    $preamble =~ s/\\par([^A-Za-z]|$)/\n$1/g;
-    $preamble =~ s/(\\document(class|style)(\[[^\]]+\])?\{\w+\})/$1\n/;
-    $preamble =~ s/(\\document(class|style)(\[[^\]]+\])?\{\w+\})/$1\n\\RequirePackage{ifthen}\n/
-                        unless ($preamble =~/\{ifthen\}/);
-#    $preamble =~ s/(\\document(class|style)(\[[^\]]+\])?\{\w+\})/$1\n\\makeatletter/;
-    # ... and make it special again after the preamble
-    # remove the  \begin/\end  for  tex2html_nowrap and tex2html_deferred environments
-    $preamble =~s/\\(begin|end)\s*\{(tex2html_(nowrap|deferred|nomath|preform)[_a-z]*|imagesonly)\}//g;
-    $preamble =~s/\n?\s?<tex2html_(end)?file>\#[^#]*\#//mg;
-
-    $preamble = "\\documentclass\{article\}%\n\\usepackage{html}\n\\usepackage[dvips]{color}\n"
-       unless ($preamble);
-    if (($LATEX_DUMP)&&(!($preamble =~ /\\usepackage\{ldump\}/))) {
-       # MRO: replaced $* with /m
-       $preamble =~ s/(\\document(class|style)[^\n]*\n)/$1\\usepackage\{ldump\}\n/m;
-    }
-    if ($preamble =~ /pstricks/) {
-       if ($LOAD_LATEX_COLOR) {
-           $LOAD_LATEX_COLOR =~ s/\{color\}/\{pstcol\}/ ;
-       } else {
-           $LOAD_LATEX_COLOR = "\n\\usepackage[dvips]{pstcol}\n";
-       }
-    } else {
-       $LOAD_LATEX_COLOR = "\n\\usepackage[dvips]{color}";
-    }
-    $LATEX_COLOR = "\\pagecolor[gray]{.85}\\nobreak " unless $LATEX_COLOR;
-    if ($preamble =~ /(^|\s*[^%])\s*\\documentstyle/) {
-       # \usepackage is invalid in LaTeX 2.09 and LaTeX-2e compatibility mode
-       $LATEX_COLOR = ''; $LOAD_LATEX_COLOR = '';
-       # ... so is \providecommand 
-       $preamble =~ s/\\documentstyle[^{]*{[^}]*}\n?/
-               $&."\n\\let\\providecommand\\newcommand\n"/eo;
-    }
-
-    $preamble .= $LOAD_LATEX_COLOR."\n" unless ($preamble =~ /[,\{]color[,\}]/);
-    $preamble .= "\n\n".$LATEX_COLOR."\n" unless ($preamble =~ /\\pagecolor/);
-    do {
-       if ($ISOLATIN_CHARS) { $INPUTENC = $INPUTENC || 'latin1' };
-       $preamble .= "\n\\usepackage[".$INPUTENC."]\{inputenc\}\n";
-       } unless ($preamble =~ /\\inputenc/);
-
-    $aux_preamble = '' unless (($aux_preamble)&&($contents =~ /\\(hyper)?(ref|cite)/));
-
-    $preamble =~ s/\\((provide|(re)?new)ed(command|counter|if|theorem|environment|font))\b/
-                        "%\n\\".$newed_commands{$1}/eg;
-    $preamble =~ s/(\\(re)?newcommand)\s*(\{(\\?)(\}|[^\}]+)\})/
-               $1.(($4)? $3 : "{\\".$5.'}' )/eg;
-
-    $preamble =~s/$verbatim_mark(imagesonly)(\d+)#/$verbatim{$2}/eg; # for images.tex only
-
-#    local($key);
-#    foreach $key (keys %newed_commands) {
-#      $preamble .= "\n\\let\\$key\\".$newed_commands{$key}
-#    }
-    $preamble .= "\n";
-
-    local($paperwidth) = '';
-    if ($PAPERSIZE) { $paperwidth = &adjust_textwidth($PAPERSIZE); }
-    else { $paperwidth = &adjust_textwidth("a5"); }
-    local($kern) = ($EXTRA_IMAGE_SCALE ? $EXTRA_IMAGE_SCALE/2 : ".5" );
-    $kern = $kern * $MATH_SCALE_FACTOR;
-    $prelatex . ($DEBUG ? "\\nonstopmode" : "\\batchmode") .
-    "\n$preamble\n\n\\makeatletter\n$aux_preamble\n" .
-    "\\makeatletter\n\\count\@=\\the\\catcode`\\_ \\catcode`\\_=8 \n" .
-    "\\newenvironment{tex2html_wrap}{}{}%\n" .
-    "\\catcode`\\<=12\\catcode`\\_=\\count\@\n" .
-    "\\newcommand{\\providedcommand}[1]{\\expandafter\\providecommand\\csname #1\\endcsname}%\n" .
-    "\\newcommand{\\renewedcommand}[1]{\\expandafter\\providecommand\\csname #1\\endcsname{}%\n" .
-    "  \\expandafter\\renewcommand\\csname #1\\endcsname}%\n" .
-    "\\newcommand{\\newedenvironment}[1]{\\newenvironment{#1}{}{}\\renewenvironment{#1}}%\n" .
-    "\\let\\newedcommand\\renewedcommand\n" .
-    "\\let\\renewedenvironment\\newedenvironment\n" .
-    "\\makeatother\n" .
-    "\\let\\mathon=\$\n\\let\\mathoff=\$\n" .
-    "\\ifx\\AtBeginDocument\\undefined \\newcommand{\\AtBeginDocument}[1]{}\\fi\n" .
-    "\\newbox\\sizebox\n" . "$paperwidth" .
-    "\\newwrite\\lthtmlwrite\n" . "\\makeatletter\n" .
-    "\\let\\realnormalsize=\\normalsize\n\\global\\topskip=2sp\n\\def\\preveqno{}" .
-    "\\let\\real\@float=\\\@float \\let\\realend\@float=\\end\@float\n" .
-    "\\def\\\@float{\\let\\\@savefreelist\\\@freelist\\real\@float}\n" .
-#    "\\def\\\@float{\\\@dbflt}\n" .
-    "\\def\\liih\@math{\\ifmmode\$\\else\\bad\@math\\fi}\n" .
-    "\\def\\end\@float{\\realend\@float\\global\\let\\\@freelist\\\@savefreelist}\n" . 
-    "\\let\\real\@dbflt=\\\@dbflt \\let\\end\@dblfloat=\\end\@float\n" .
-    "\\let\\\@largefloatcheck=\\relax\n" .
-    "\\let\\if\@boxedmulticols=\\iftrue\n" .
-    "\\def\\\@dbflt{\\let\\\@savefreelist\\\@freelist\\real\@dbflt}\n" .
-    "\\def\\adjustnormalsize{\\def\\normalsize{\\mathsurround=0pt \\realnormalsize\n" .
-    " \\parindent=0pt\\abovedisplayskip=0pt\\belowdisplayskip=0pt}%\n" .
-    " \\def\\phantompar{\\csname par\\endcsname}\\normalsize}%\n" .
-    "\\def\\lthtmltypeout#1{{\\let\\protect\\string \\immediate\\write\\lthtmlwrite{#1}}}%\n" .
-    "\\newcommand\\lthtmlhboxmathA{\\adjustnormalsize\\setbox\\sizebox=\\hbox\\bgroup\\kern.05em }%\n" .
-    "\\newcommand\\lthtmlhboxmathB{\\adjustnormalsize\\setbox\\sizebox=\\hbox to\\hsize\\bgroup\\hfill }%\n" .
-    "\\newcommand\\lthtmlvboxmathA{\\adjustnormalsize\\setbox\\sizebox=\\vbox\\bgroup %\n".
-    " \\let\\ifinner=\\iffalse \\let\\)\\liih\@math }%\n" .
-    "\\newcommand\\lthtmlboxmathZ{\\\@next\\next\\\@currlist{}{\\def\\next{\\voidb\@x}}%\n" .
-#    " \\expandafter\\box\\next\\edef\\next{\\egroup\\def\\noexpand\\thiseqn{\\theequation}}\\next}%\n" .
-    " \\expandafter\\box\\next\\egroup}%\n" .
-    "\\newcommand\\lthtmlmathtype[1]{\\gdef\\lthtmlmathenv{#1}}%\n" .
-    "\\newcommand\\lthtmllogmath{\\dimen0\\ht\\sizebox \\advance\\dimen0\\dp\\sizebox\n" .
-    "  \\ifdim\\dimen0>.95\\vsize\n" .  "   \\lthtmltypeout{%\n" .
-    "*** image for \\lthtmlmathenv\\space is too tall at \\the\\dimen0, reducing to .95 vsize ***}%\n" .
-    "   \\ht\\sizebox.95\\vsize \\dp\\sizebox\\z\@ \\fi\n" .  "  \\lthtmltypeout{l2hSize %\n" .
-    ":\\lthtmlmathenv:\\the\\ht\\sizebox::\\the\\dp\\sizebox::\\the\\wd\\sizebox.\\preveqno}}%\n" .
-    "\\newcommand\\lthtmlfigureA[1]{\\let\\\@savefreelist\\\@freelist
-       \\lthtmlmathtype{#1}\\lthtmlvboxmathA}%\n" .
-    "\\newcommand\\lthtmlpictureA{\\bgroup\\catcode`\\_=8 \\lthtmlpictureB}%\n" . 
-    "\\newcommand\\lthtmlpictureB[1]{\\lthtmlmathtype{#1}\\egroup
-       \\let\\\@savefreelist\\\@freelist \\lthtmlhboxmathB}%\n" .
-    "\\newcommand\\lthtmlpictureZ[1]{\\hfill\\lthtmlfigureZ}%\n" .
-    "\\newcommand\\lthtmlfigureZ{\\lthtmlboxmathZ\\lthtmllogmath\\copy\\sizebox
-       \\global\\let\\\@freelist\\\@savefreelist}%\n" .
-    "\\newcommand\\lthtmldisplayA{\\bgroup\\catcode`\\_=8 \\lthtmldisplayAi}%\n" .
-    "\\newcommand\\lthtmldisplayAi[1]{\\lthtmlmathtype{#1}\\egroup\\lthtmlvboxmathA}%\n" .
-    "\\newcommand\\lthtmldisplayB[1]{\\edef\\preveqno{(\\theequation)}%\n" .
-    "  \\lthtmldisplayA{#1}\\let\\\@eqnnum\\relax}%\n" .
-    "\\newcommand\\lthtmldisplayZ{\\lthtmlboxmathZ\\lthtmllogmath\\lthtmlsetmath}%\n" .
-    "\\newcommand\\lthtmlinlinemathA{\\bgroup\\catcode`\\_=8 \\lthtmlinlinemathB}\n" .
-    "\\newcommand\\lthtmlinlinemathB[1]{\\lthtmlmathtype{#1}\\egroup\\lthtmlhboxmathA\n" .
-    "  \\vrule height1.5ex width0pt }%\n" .
-    "\\newcommand\\lthtmlinlineA{\\bgroup\\catcode`\\_=8 \\lthtmlinlineB}%\n" .
-    "\\newcommand\\lthtmlinlineB[1]{\\lthtmlmathtype{#1}\\egroup\\lthtmlhboxmathA}%\n" .
-    "\\newcommand\\lthtmlinlineZ{\\egroup\\expandafter\\ifdim\\dp\\sizebox>0pt %\n" .
-    "  \\expandafter\\centerinlinemath\\fi\\lthtmllogmath\\lthtmlsetinline}\n" .
-    "\\newcommand\\lthtmlinlinemathZ{\\egroup\\expandafter\\ifdim\\dp\\sizebox>0pt %\n" .
-    "  \\expandafter\\centerinlinemath\\fi\\lthtmllogmath\\lthtmlsetmath}\n" .
-    "\\newcommand\\lthtmlindisplaymathZ{\\egroup %\n" .
-    "  \\centerinlinemath\\lthtmllogmath\\lthtmlsetmath}\n" .
-    "\\def\\lthtmlsetinline{\\hbox{\\vrule width.1em \\vtop{\\vbox{%\n" .
-    "  \\kern.1em\\copy\\sizebox}\\ifdim\\dp\\sizebox>0pt\\kern.1em\\else\\kern.3pt\\fi\n" .
-    "  \\ifdim\\hsize>\\wd\\sizebox \\hrule depth1pt\\fi}}}\n" .
-    "\\def\\lthtmlsetmath{\\hbox{\\vrule width.1em\\kern-.05em\\vtop{\\vbox{%\n" .
-    "  \\kern.1em\\kern$kern pt\\hbox{\\hglue.17em\\copy\\sizebox\\hglue$kern pt}}\\kern.3pt%\n" .
-    "  \\ifdim\\dp\\sizebox>0pt\\kern.1em\\fi \\kern$kern pt%\n" .
-    "  \\ifdim\\hsize>\\wd\\sizebox \\hrule depth1pt\\fi}}}\n" .
-    "\\def\\centerinlinemath{%\n" . 
-    "  \\dimen1=\\ifdim\\ht\\sizebox<\\dp\\sizebox \\dp\\sizebox\\else\\ht\\sizebox\\fi\n" .
-    "  \\advance\\dimen1by.5pt \\vrule width0pt height\\dimen1 depth\\dimen1 \n".
-    " \\dp\\sizebox=\\dimen1\\ht\\sizebox=\\dimen1\\relax}\n\n" .
-    "\\def\\lthtmlcheckvsize{\\ifdim\\ht\\sizebox<\\vsize \n" .
-    "  \\ifdim\\wd\\sizebox<\\hsize\\expandafter\\hfill\\fi \\expandafter\\vfill\n" .
-    "  \\else\\expandafter\\vss\\fi}%\n" .
-    "\\providecommand{\\selectlanguage}[1]{}%\n" .
-#    "\\def\\\@enddocumenthook{\\ifnum\\count0>1 \\ifvoid\\\@cclv\\penalty-\\\@MM\\fi\\fi}\n" .
-    "\\makeatletter \\tracingstats = 1 \n"
-    . ($itrans_loaded ? $itrans_tex_mod : '')
-    . $LaTeXmacros . "\n"  # macros defined in extension files
-#    "\\usepackage{lthimages}\n" .
-    . (($LATEX_DUMP)? "\\latexdump\n" : '')
-    . "\n\\begin{document}\n" .
-    "\\pagestyle{empty}\\thispagestyle{empty}\\lthtmltypeout{}%\n" .
-    "\\lthtmltypeout{latex2htmlLength hsize=\\the\\hsize}\\lthtmltypeout{}%\n" .
-    "\\lthtmltypeout{latex2htmlLength vsize=\\the\\vsize}\\lthtmltypeout{}%\n" .
-    "\\lthtmltypeout{latex2htmlLength hoffset=\\the\\hoffset}\\lthtmltypeout{}%\n" .
-    "\\lthtmltypeout{latex2htmlLength voffset=\\the\\voffset}\\lthtmltypeout{}%\n" .
-    "\\lthtmltypeout{latex2htmlLength topmargin=\\the\\topmargin}\\lthtmltypeout{}%\n" .
-    "\\lthtmltypeout{latex2htmlLength topskip=\\the\\topskip}\\lthtmltypeout{}%\n" .
-    "\\lthtmltypeout{latex2htmlLength headheight=\\the\\headheight}\\lthtmltypeout{}%\n" .
-    "\\lthtmltypeout{latex2htmlLength headsep=\\the\\headsep}\\lthtmltypeout{}%\n" .
-    "\\lthtmltypeout{latex2htmlLength parskip=\\the\\parskip}\\lthtmltypeout{}%\n" .
-    "\\lthtmltypeout{latex2htmlLength oddsidemargin=\\the\\oddsidemargin}\\lthtmltypeout{}%\n" .
-    "\\makeatletter\n" .
-    "\\if\@twoside\\lthtmltypeout{latex2htmlLength evensidemargin=\\the\\evensidemargin}%\n" .
-    "\\else\\lthtmltypeout{latex2htmlLength evensidemargin=\\the\\oddsidemargin}\\fi%\n" .
-    "\\lthtmltypeout{}%\n" .
-    "\\makeatother\n\\setcounter{page}{1}\n\\onecolumn\n\n% !!! IMAGES START HERE !!!\n\n"
-    . "$contents\n"
-#    "\\clearpage\n" .
-    . "\\end{document}";
-}
-
-sub adjust_textwidth {
-    local($_) = @_;
-    local($width,$length) = ('','');
-    if (/a4/) {$width = 595; $length= 842; }
-    elsif (/letter/) {$width = 612; $length= 792; }
-    elsif (/legal/) {$width = 612; $length= 1008; }
-    elsif (/note/) {$width = 540; $length= 720; }
-    elsif (/b5/) {$width = 501; $length= 709; }
-    elsif (/a5/) {$width = 421; $length= 595; }
-    elsif (/a6/) {$width = 297; $length= 421; }
-    elsif (/a7/) {$width = 210; $length= 297; }
-    elsif (/a8/) {$width = 148; $length= 210; }
-    elsif (/a9/) {$width = 105; $length= 148; }
-    elsif (/a10/) {$width = 74; $length= 105; }
-    elsif (/b4/) {$width = 709; $length= 1002; }
-    elsif (/a3/) {$width = 842; $length= 1190; }
-    elsif (/b3/) {$width = 1002; $length= 1418; }
-    elsif (/a2/) {$width = 1190; $length= 1684; }
-    elsif (/b2/) {$width = 1418; $length= 2004; }
-    elsif (/a1/) {$width = 1684; $length= 2380; }
-    elsif (/b1/) {$width = 2004; $length= 2836; }
-    elsif (/a0/) {$width = 2380; $length= 3368; }
-    elsif (/b0/) {$width = 2836; $length= 4013; }
-    else {
-       &write_warnings("\nPAPERSIZE: $_ unknown, using LaTeX's size.");
-       return();
-     }
-    if ($width > 500) { $width = $width - 144; $length = $length - 288; }
-    elsif ($width > 250) { $width = $width - 72; $length = $length - 144; }
-    elsif ($width > 125) { $width = $width - 36; $length = $length - 72; }
-#    "\\setlength{\\oddsidemargin}{0pt}\n" .
-#    "\\setlength{\\evensidemargin}{0pt}\n" .
-#    "\\setlength{\\parskip}{0pt}\\setlength{\\topskip}{0pt}\n" .
-    "\\setlength{\\hoffset}{0pt}\\setlength{\\voffset}{0pt}\n" .
-    "\\addtolength{\\textheight}{\\footskip}\\setlength{\\footskip}{0pt}\n" .
-    "\\addtolength{\\textheight}{\\topmargin}\\setlength{\\topmargin}{0pt}\n" .
-    "\\addtolength{\\textheight}{\\headheight}\\setlength{\\headheight}{0pt}\n" .
-    "\\addtolength{\\textheight}{\\headsep}\\setlength{\\headsep}{0pt}\n" .
-    "\\setlength{\\textwidth}{${width}pt}\n"
-    . (($length > 500) ? "\\setlength{\\textheight}{${length}pt}\n" : '')
-}
-
-# Given the depth of the current sectioning declaration and the current
-# section numbers it returns the new section numbers.
-# It increments the $depth-ieth element of the @curr_sec_id list and
-# 0's the elements after the $depth-ieth element.
-sub new_level {
-    local($depth, @curr_sec_id) = @_;
-    $depth = $section_commands{$outermost_level} unless $depth;
-    local($i) = 0;
-    grep( do { if ($i == $depth) {$_++ ;}
-              elsif ($i > $depth) {$_ = 0 ;};
-              $i++;
-              0;
-          },
-        @curr_sec_id);
-    @curr_sec_id;
-}
-
-sub make_head_and_body {
-    local($title,$body,$before_body) = @_;
-    local($DTDcomment) = '';
-    local($version,$isolanguage) = ($HTML_VERSION, 'EN');
-    local(%isolanguages) = (  'english',  'EN'   , 'USenglish', 'EN-US'
-                           , 'original', 'EN'   , 'german'   , 'DE'
-                           , 'austrian', 'DE-AT', 'french'   , 'FR'
-                           , 'spanish',  'ES'
-                           , %isolanguages );
-#    $isolanguage = $isolanguages{$default_language};  # DTD is in EN
-    $isolanguage = 'EN' unless $isolanguage;
-#JCL(jcl-tcl)
-# clean title as necessary
-# the first words ... is a kludge, but reasonable (or not?) 
-#RRM: why bother? --- as long as it is pure text.
-    $title = &purify($title,1);
-    eval("\$title = ". $default_title ) unless ($title);
-#    $title = &get_first_words($title, $WORDS_IN_NAVIGATION_PANEL_TITLES);
-
-    # allow user-modification of the <TITLE> tag; thanks Dan Young
-    if (defined &custom_TITLE_hook) {
-       $title = &custom_TITLE_hook($title, $toc_sec_title);
-    }
-
-    if ($DOCTYPE =~ /\/\/[\w\.]+\s*$/) { # language spec included
-       $DTDcomment = '<!DOCTYPE HTML PUBLIC "'. $DOCTYPE .'"';
-    } else {
-       $DTDcomment = '<!DOCTYPE HTML PUBLIC "'. $DOCTYPE .'//'
-           . ($ISO_LANGUAGE ? $ISO_LANGUAGE : $isolanguage) . '"'
-    }
-    $DTDcomment .= ($PUBLIC_REF ? "\n  \"".$PUBLIC_REF.'"' : '' ) . '>'."\n";
-
-    $STYLESHEET = $FILE.".css" unless defined($STYLESHEET);
-
-    my ($this_charset) = $charset;
-    if ($USE_UTF) { $charset = $utf8_str; $NO_UTF = ''; }
-    if (!$charset && $CHARSET) {
-       $this_charset = $CHARSET;
-       $this_charset =~ s/_/\-/go;
-    }
-    if ($NO_UTF && $charset =~/utf/) {
-       $this_charset = $PREV_CHARSET||$CHARSET; 
-       $this_charset =~ s/_/\-/go;
-    }
-
-    join("\n", (($DOCTYPE)? $DTDcomment : '' )
-       ,"<!--Converted with LaTeX2HTML $TEX2HTMLVERSION"
-       , "original version by:  Nikos Drakos, CBLU, University of Leeds"
-       , "* revised and updated by:  Marcus Hennecke, Ross Moore, Herb Swan"
-       , "* with significant contributions from:"
-       , "  Jens Lippmann, Marek Rouchal, Martin Wilck and others"
-           . " -->\n<HTML>\n<HEAD>\n<TITLE>".$title."</TITLE>"
-       , &meta_information($title)
-       ,  ($CHARSET && $HTML_VERSION ge "2.1" ? 
-             "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=$this_charset\">" 
-             : "" )
-       , $LATEX2HTML_META
-       , ($BASE ? "<BASE HREF=\"$BASE\">" : "" )
-       , $STYLESHEET_CASCADE
-       , ($STYLESHEET ? "<LINK REL=\"STYLESHEET\" HREF=\"$STYLESHEET\">" : '' )
-       , $more_links_mark
-       , "</HEAD>" , ($before_body? $before_body : '')
-       , "<BODY $body>", '');
-}
-
-
-sub style_sheet {
-    local($env,$id,$style);
-    #AXR:  don't overwrite existing .css
-    #MRO: This is supposed to be $FILE.css, no?
-    #RRM: only by default, others can be specified as well, via $EXTERNAL_STYLESHEET
-    #return if (-f $EXTERNAL_STYLESHEET);
-    return if (-r "$FILE.css" && -s _ && !$REFRESH_STYLES );
-
-    unless(open(STYLESHEET, ">$FILE.css")) {
-        print "\nError: Cannot write '$FILE.css': $!\n";
-        return;
-    }
-    if ( -f $EXTERNAL_STYLESHEET ) {
-        if(open(EXT_STYLES, "<$EXTERNAL_STYLESHEET")) {
-            while (<EXT_STYLES>) { print STYLESHEET $_; }
-            close(EXT_STYLES);
-        } else {
-            print "\nError: Cannot read '$EXTERNAL_STYLESHEET': $!\n";
-        }
-    } else {
-       print STYLESHEET <<"EOF"
-/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */
-.MATH    { font-family: \"Century Schoolbook\", serif; }
-.MATH I  { font-family: \"Century Schoolbook\", serif; font-style: italic }
-.BOLDMATH { font-family: \"Century Schoolbook\", serif; font-weight: bold }
-
-/* implement both fixed-size and relative sizes */
-SMALL.XTINY            { font-size : xx-small }
-SMALL.TINY             { font-size : x-small  }
-SMALL.SCRIPTSIZE       { font-size : smaller  }
-SMALL.FOOTNOTESIZE     { font-size : small    }
-SMALL.SMALL            {  }
-BIG.LARGE              {  }
-BIG.XLARGE             { font-size : large    }
-BIG.XXLARGE            { font-size : x-large  }
-BIG.HUGE               { font-size : larger   }
-BIG.XHUGE              { font-size : xx-large }
-
-/* heading styles */
-H1             {  }
-H2             {  }
-H3             {  }
-H4             {  }
-H5             {  }
-
-/* mathematics styles */
-DIV.displaymath                { }     /* math displays */
-TD.eqno                        { }     /* equation-number cells */
-
-
-/* document-specific styles come next */
-EOF
-    }
-    print "\n *** Adding document-specific styles *** ";
-    while (($env,$style) = each %env_style) {
-        if ($env =~ /\./) {
-            $env =~ s/\.$//;
-            print STYLESHEET "$env\t\t{ $style }\n";
-        } elsif ($env =~ /inline|^(text|math)?((tt|rm|sf)(family)?|(up|it|sl|sc)(shape)?|(bf|md)(series)?|normal(font)?)$/) {
-            print STYLESHEET "SPAN.$env\t\t{ $style }\n";
-        } elsif ($env =~ /\./) {
-            print STYLESHEET "$env\t\t{ $style }\n";
-        } elsif ($env =~ /^(preform|\w*[Vv]erbatim(star)?)$/) {
-            print STYLESHEET "PRE.$env\t\t{ $style }\n";
-        } elsif ($env =~ /figure|table|tabular|equation|$array_env_rx/) {
-            print STYLESHEET "TABLE.$env\t\t{ $style }\n";
-        } else {
-            print STYLESHEET "DIV.$env\t\t{ $style }\n";
-        }
-    }
-    while (($env,$style) = each %txt_style) {
-        print STYLESHEET "SPAN.$env\t\t{ $style }\n";
-    }
-    while (($env,$style) = each %img_style) {
-        print STYLESHEET "IMG.$env\t\t{ $style }\n";
-    }
-
-    my ($style);
-    foreach $id (sort(keys  %styleID)) {
-        $style =  $styleID{$id};
-        $style =~ s/font-(color)/$1/;
-        print STYLESHEET "\#$id\t\t{ $style }\n"
-            if ($styleID{$id} ne '');
-    }
-    close(STYLESHEET);
-}
-
-sub clear_styleID {
-    return unless ($USING_STYLES);
-    local($env_id,$id) = ("grp", @_); 
-    undef $styleID{$env_id} if ($id =~ /^\d+$/);
-}
-
-sub make_address { 
-    local($addr) = &make_real_address(@_);
-    $addr .= "\n</BODY>\n</HTML>\n";
-    &lowercase_tags($addr) if $LOWER_CASE_TAGS;
-    $addr;
-}
-
-sub make_real_address {
-    local($addr) = $ADDRESS;
-    if ((defined &custom_address)&&($addr)) {
-       &custom_address($addr)
-    } elsif ($addr) {
-       "<ADDRESS>\n$addr\n</ADDRESS>";
-    } else { '' }
-}
-
-sub purify_caption {
-    local($_) = @_;
-    local($text) = &recover_image_code($_);
-    $text =~ s/\\protect|ALT\=|%EQNO:\d+//g;
-    $text =~ s/[\\\#\'\"\`]//g;
-    $text;
-}
-
-sub recover_image_code {
-    local($key) = @_;
-    local($text) = $img_params{$key};
-    if (!$text) {
-       if ($text = $id_map{$key}) {
-           if ($orig_name_map{$text}) {
-               $text = $img_params{$orig_name_map{$text}}
-           }
-       } elsif ($cached_env_img{$key}) {
-           $text = $img_params{$cached_env_img{$key}};
-       }
-       if ($text =~ /\#*ALT="([^"]+)"(>|#)/s) { $text = $1 }
-    }
-    $text =~ s/\\protect|%EQNO:\d+//g;
-    $text =~ s/&(gt|lt|amp|quot);/&special_html_inv($1)/eg;
-    $text;
-}
-
-sub encode_title {
-    local($_) = @_;
-    $_ = &encode($_);
-    while (/(<[^<>]*>)/o) {s/$1//g}; # Remove HTML tags
-    s/#[^#]*#//g;               # Remove #-delimited markers
-    $_;
-}
-
-# Encodes the contents of enviroments that are passed to latex. The code
-# is then used as key to a hash table pointing to the URL of the resulting
-# picture.
-sub encode {
-    local($_) = @_;
-    # Remove invocation-specific stuff
-    1 while(s/\\(begin|end)\s*(($O|$OP)\d+($C|$CP))?|{?tex2html_(wrap|nowrap|deferred|)(_\w+)?}?(\2)?//go);
-    $_ = &revert_to_raw_tex($_);
-    s/\\protect//g;            # remove redundant \protect macros
-    #$_ = pack("u*", $_);      # uuencode
-    s/\\\$/dollar/g;           # replace funnies, may cause problems in a hash key
-    s/\//slash/g;              # replace funnies, may cause problems in a hash key
-    s/\$|\/|\\//g;             # remove funnies, may cause problems in a hash key
-    s/\s*|\n//g;               # Remove spaces  and newlines
-    s/^(.{80}).*(.{80})$/$1$2/;                # truncate to avoid DBM problems
-    $_;
-}
-
-
-##################### Hypertext Section Links ########################
-sub post_process {
-    # Put hyperlinks between sections, add HTML headers and addresses,
-    # do cross references and citations.
-    # Uses the %section_info array created in sub translate.
-    # Binds the global variables
-    # $PREVIOUS, $PREVIOUS_TITLE
-    # $NEXT, $NEXT_TITLE
-    # $UP, $UP_TITLE
-    # $CONTENTS, $CONTENTS_TITLE 
-    # $INDEX, $INDEX_TITLE
-    # $NEXT_GROUP, $NEXT_GROUP_TITLE
-    # $PREVIOUS_GROUP, $PREVIOUS_GROUP_TITLE
-    # Converting to and from lists and strings is very inefficient.
-    # Maybe proper lists of lists should be used (or wait for Perl5?)
-    # JKR:  Now using top_navigation and bot_navigation instead of navigation
-    local($_, $key, $depth, $file, $title, $header, @link, @old_link,
-         $top_navigation, $bot_navigation, @keys,
-         @tmp_keys, $flag, $child_links, $body, $more_links);
-
-    @tmp_keys = @keys = sort numerically keys %section_info;
-    print "\nDoing section links ...";
-    while (@tmp_keys) {
-       $key = shift @tmp_keys;
-       next if ($MULTIPLE_FILES &&!($key =~ /^$THIS_FILE/));
-       print ".";
-       $more_links = "";
-       ($depth, $file, $title, $body) = split($delim,$section_info{$key});
-       print STDOUT "\n$key $file $title $body" if ($VERBOSITY > 3);
-       next if ($body =~ /external/);
-       $PREVIOUS = $PREVIOUS_TITLE = $NEXT = $NEXT_TITLE = $UP = $UP_TITLE
-           = $CONTENTS = $CONTENTS_TITLE = $INDEX = $INDEX_TITLE
-           = $NEXT_GROUP = $NEXT_GROUP_TITLE
-           = $PREVIOUS_GROUP = $PREVIOUS_GROUP_TITLE
-           = $_ = $top_navigation = $bot_navigation = undef;
-       &add_link_tag('previous',$file);
-       @link =  split(' ',$key);
-        ($PREVIOUS, $PREVIOUS_TITLE) =
-           &add_link($previous_page_visible_mark,$file,@old_link);
-       @old_link = @link;
-       unless ($done{$file}) {
-           ++$link[$depth];
-#          if ($MULTIPLE_FILES && !$depth && $multiple_toc ) {
-#              local($save_depth) = $link[$depth];
-#              $link[$depth] = 1;
-#              ($NEXT_GROUP, $NEXT_GROUP_TITLE) =
-#                  &add_link($next_visible_mark, $file, @link);
-#              &add_link_tag('next', $file, @link);
-#              $link[$depth] = $save_depth;
-#          } else {
-               ($NEXT_GROUP, $NEXT_GROUP_TITLE) =
-                   &add_link($next_visible_mark, $file, @link);
-               &add_link_tag('next', $file, @link);
-#          }
-
-           $link[$depth]--;$link[$depth]--;
-           if ($MULTIPLE_FILES && !$depth ) {
-           } else {
-               ($PREVIOUS_GROUP, $PREVIOUS_GROUP_TITLE) =
-                   &add_link($previous_visible_mark, $file,@link);
-               &add_link_tag('previous', $file,@link);
-           }
-
-           $link[$depth] = 0;
-           ($UP, $UP_TITLE) =
-               &add_link($up_visible_mark, $file, @link);
-           &add_link_tag('up', $file, @link);
-
-           if ($CONTENTS_IN_NAVIGATION) {
-               ($CONTENTS, $CONTENTS_LINK) = 
-                   &add_special_link($contents_visible_mark, $tocfile, $file);
-               &add_link_tag('contents', $file, $delim.$tocfile);
-           }
-
-           if ($INDEX_IN_NAVIGATION) {
-               ($INDEX, $INDEX_LINK) = 
-                   &add_special_link($index_visible_mark, $idxfile, $file);
-               &add_link_tag('index', $file, $delim.$idxfile,);
-           }
-
-           @link = split(' ',$tmp_keys[0]);
-           # the required `next' link may be several sub-sections along
-           local($nextdepth,$nextfile,$nextkey,$nexttitle,$nextbody)=
-               ($depth,$file,$key,'','');
-           $nextkey = shift @tmp_keys;
-           ($nextdepth, $nextfile,$nexttitle,$nextbody) = split($delim,$section_info{$nextkey});
-           if (($nextdepth<$MAX_SPLIT_DEPTH)&&(!($nextbody=~/external/))) {
-               ($NEXT, $NEXT_TITLE) =
-                   &add_link($next_page_visible_mark, $file, @link);
-               &add_link_tag('next', $file, @link);
-           } else {
-               ($NEXT, $NEXT_TITLE) = ('','');
-               $nextfile = $file;
-           }
-           if ((!$NEXT || $NEXT =~ /next_page_inactive_visible_mark/)&&(@tmp_keys)) {
-               # the required `next' link may be several sub-sections along
-               while ((@tmp_keys)&&(($MAX_SPLIT_DEPTH < $nextdepth+1)||($nextfile eq $file))) {
-                   $nextkey = shift @tmp_keys;
-                   ($nextdepth, $nextfile,$nexttitle,$nextbody) = split($delim,$section_info{$nextkey});
-                   if ($nextbody =~ /external/) {
-                       $nextfile = $file;
-                       next;
-                   };
-                   print ",";
-                   print STDOUT "\n $nextkey" if ($VERBOSITY > 3);
-               }
-               @link = split(' ',$nextkey);
-               if (($nextkey)&&($nextdepth<$MAX_SPLIT_DEPTH)) {
-                   ($NEXT, $NEXT_TITLE) =
-                       &add_link($next_page_visible_mark, $file, @link);
-                   &add_link_tag('next', $file, @link);
-               } else {
-                   ($NEXT, $NEXT_TITLE) = ($NEXT_GROUP, $NEXT_GROUP_TITLE);
-                   $NEXT =~ s/next_page_(inactive_)?visible_mark/next_page_$1visible_mark/;
-                   ($PREVIOUS, $PREVIOUS_TITLE) = ($PREVIOUS_GROUP, $PREVIOUS_GROUP_TITLE);
-                   $PREVIOUS =~ s/previous_(inactive_)?visible_mark/previous_page_$1visible_mark/;
-               }
-           }
-           unshift (@tmp_keys,$nextkey) if ($nextkey);
-#
-           $top_navigation = (defined(&top_navigation_panel) ?
-                              &top_navigation_panel : &navigation_panel)
-               unless $NO_NAVIGATION;
-           $bot_navigation = (defined(&bot_navigation_panel) ?
-                              &bot_navigation_panel : &navigation_panel)
-               unless $NO_NAVIGATION;
-           local($end_navigation) = "\n<!--End of Navigation Panel-->\n";
-           if ($USING_STYLES) {
-               $top_navigation = "\n".'<DIV CLASS="navigation">' . $top_navigation
-                       if $top_navigation;
-               $bot_navigation = "\n".'<DIV CLASS="navigation">' . $bot_navigation
-                       if $bot_navigation;
-               $end_navigation = '</DIV>' . $end_navigation;
-               $env_style{'navigation'} = " ";
-           }
-
-           $header = &make_head_and_body($title, $body);
-           $header = join('', $header, $top_navigation, $end_navigation) if ($top_navigation);
-
-           local($this_file) = $file;
-           if ($MULTIPLE_FILES && $ROOTED) {
-               if ($this_file =~ /\Q$dd\E([^$dd$dd]+)$/) { $this_file = $1 }
-           }
-           &slurp_input($this_file);
-           open(OUTFILE, ">$this_file")
-                || die "\nError: Cannot write file '$this_file': $!\n";
-
-           if (($INDEX) && ($SHORT_INDEX) && ($SEGMENT eq 1)) {
-               &make_index_segment($title,$file); }
-
-           local($child_star,$child_links);
-           local($CURRENT_FILE) = $this_file; # ensure $CURRENT_FILE is set correctly
-           if (/$childlinks_on_mark\#(\d)\#/) { $child_star = $1 }
-           $child_links = &add_child_links('',$file, $depth, $child_star,$key, @keys)
-               unless (/$childlinks_null_mark\#(\d)\#/);
-           if (($child_links)&&(!/$childlinks_mark/)&&($MAX_SPLIT_DEPTH > 1)) {
-               if ($depth < $MAX_SPLIT_DEPTH -1) {
-                   $_ = join('', $header, $_, &child_line(), $childlinks_mark, "\#0\#" );
-               } else {
-                   $_ = join('', $header, "\n$childlinks_mark\#0\#", &upper_child_line(), $_ );
-               }
-           } else {
-               $_ = join('', $header, $_ );
-           }
-           $flag = (($BOTTOM_NAVIGATION || &auto_navigation) && $bot_navigation);
-           $_ .= $bot_navigation . $end_navigation if ($flag &&($bot_navigation));
-           $_ .= &child_line() unless $flag;
-           print STDOUT "\n *** replace markers *** " if ($VERBOSITY > 1);
-           &replace_markers;
-           print STDOUT "\n *** post-post-process *** " if ($VERBOSITY > 1);
-           &post_post_process if (defined &post_post_process);
-           &adjust_encoding;
-           print OUTFILE $_;
-           print OUTFILE &make_address;
-           close OUTFILE;
-           $done{$file}++;
-       }
-    }
-    &post_process_footnotes if ($footfile);
-}
-
-sub adjust_encoding {
-    &convert_to_utf8($_) if ($USE_UTF);
-    &lowercase_tags($_) if $LOWER_CASE_TAGS;
-}
-
-sub post_replace_markers {
-    # MRO: replaced $* with /m
-    # clean up starts and ends of  P, BR and DIV tags
-    s/(<\/?(P|BR|DIV)>)\s*(\w)/$1\n$3/gom unless ($file eq $citefile);
-    s/([^\s])(<(BR|DIV))/$1\n$2/gom unless ($file eq $citefile);
-    local($keep,$after);
-
-    # anchor images when otherwise there is an invisible-anchor
-#    s/(<A[^>]*>)\&\#160;<\/A>\s?(<(P|DIV)[^>]*>)\s*(<IMG[^>]*>)\s*(<\/(P|DIV)>)/
-    s/(<A[^>]*>)($anchor_mark|$anchor_invisible_mark)<\/A>\s?(<(P|DIV)[^>]*>)\s*(<IMG[^>]*>)\s*(<\/(P|DIV)>)/
-       do{ $keep="$3$1$5<\/A>";
-           $after = $6;
-           join('',$keep, &after_punct_break($after), $after);
-       } /egom;
-
-    # absorb named anchor (e.g. from index-entry) into preceding or following anchor
-#    s/(<A NAME=\"[^\"]+\")>\&#160;<\/A>\s*\b?<A( HREF=\"[^\"]+\">)/$1$2/gom;
-#    s/(<A HREF=\"[^\"]+\")(>\s*\b?([^<]+|<([^>\/]+|\/[^>A]+)>\s*)*<\/A>)\s*\b?<A( NAME=\"[^\"]+\")>\&#160;<\/A>/$1$5$2/gom;
-
-    # clean up empty table cells
-    s/(<TD[^>]*>)\s*(<\/TD>)/<TD>$2/gom;
-
-    # clean up list items (only desirable in the bibliography ?)
-    # s/\n<P>(<DT[^>]*>)/\n<P><\/P>\n$1/gom;
-
-    # remove blank lines and comment-markers
-#    s/\n\n/\n/g;  # no, cause this kills intended ones in verbatims
-    s/$comment_mark(\d+\n?)?//gm;
-    s/\&quot;/"/gm;  # replace  &quot;  entities
-
-    # italic \LaTeX looks bad
-    s:<(I|EM)>(($Laname|$AmSname)?$TeXname)</\1>:$2:gm;
-}
-
-sub lowercase_tags {
-    # MRO: modified to use $_[0]
-    # local(*stream) = @_;
-    my ($tags,$attribs);
-    $_[0] =~ s!<(/?\w+)( [^>]*)?>!
-       $tags = $1; $attribs = $2;
-       $attribs =~ s/ ([\w\d-]+)(=| |$)/' '.lc($1).$2/eg;
-       join('', '<', lc($tags) , $attribs , '>')!eg;
-}
-
-sub after_punct_break {
-    # MRO: modified to use $_[0]
-    # local(*stream) = @_;
-#    $stream =~ s/^([ \t]*)([,;\.\)\!\"\'\?])[ \t]*(\n)?/(($2)? "$2" : "$1")."\n"/em;
-#    $stream;
-    $_[0] =~ s/^([ \t]*)([,;\.\)\!\"\'\?\>]|\&gt;)[ \t]*(\n)?//em;
-    ($2 ? $2 : $1)."\n";
-}
-
-sub make_index_segment {
-    local($title,$file)= @_ ;
-#JCL(jcl-tcl)
-#    s/<[^>]*>//g;
-#
-    $index_segment{$PREFIX} = "$title";
-    if (!($ref_files{"segment"."$PREFIX"} eq "$file")) {
-       $ref_files{"segment"."$PREFIX"} = "$file";
-       $changed = 1
-    }
-    $SEGMENT = 2;
-}
-
-
-sub add_link {
-    # Returns a pair (iconic link, textual link)
-    local($icon, $current_file, @link) = @_;
-    local($dummy, $file, $title, $lbody) = split($delim,$section_info{join(' ',@link)});
-    if ($lbody =~ /external/) { return ('','') };
-
-#    local($dummy, $file, $title) = split($delim,$toc_section_info{join(' ',@link)});
-
-    if ($MULTIPLE_FILES && $ROOTED && $file) {
-        if (!($DESTDIR =~ /\Q$FIXEDDIR\E[$dd$dd]?$/)) { $file = "..$dd$file" }
-    }
-#    if ($title && ($file ne $current_file || $icon ne $up_visible_mark)) {
-    if ($title && ($file ne $current_file)) {
-       #RRM: allow user-customisation of the link-text; thanks Dan Young
-       if (defined &custom_link_hook ) {
-           $title = &custom_link_hook($title,$toc_section_info{join(' ',@link)});
-       } else {
-            $title = &purify($title);
-           $title = &get_first_words($title, $WORDS_IN_NAVIGATION_PANEL_TITLES);
-       }
-       return ("\n".&make_href($file, $icon), &make_href($file, "$title"))
-    }
-#    elsif ($icon eq $up_visible_mark && $file eq $current_file && $EXTERNAL_UP_LINK) {
-    elsif ($icon eq $up_visible_mark && $EXTERNAL_UP_LINK) {
-       return ("\n".&make_href($EXTERNAL_UP_LINK, $icon),
-               &make_href($EXTERNAL_UP_LINK, "$EXTERNAL_UP_TITLE"))
-    }
-    elsif (($icon eq $previous_visible_mark || $icon eq $previous_page_visible_mark)
-       && $EXTERNAL_PREV_LINK && $EXTERNAL_PREV_TITLE) {
-       return ("\n".&make_href($EXTERNAL_PREV_LINK, $icon),
-               &make_href($EXTERNAL_PREV_LINK, "$EXTERNAL_PREV_TITLE"))
-    }
-    elsif (($icon eq $next_visible_mark ||  $icon eq $next_page_visible_mark)
-       && $EXTERNAL_DOWN_LINK && $EXTERNAL_DOWN_TITLE) {
-       return ("\n".&make_href($EXTERNAL_DOWN_LINK, $icon),
-               &make_href($EXTERNAL_DOWN_LINK, "$EXTERNAL_DOWN_TITLE"))
-    }
-    (&inactive_img($icon), "");
-}
-
-sub add_special_link { &add_real_special_link(@_) }
-sub add_real_special_link {
-    local($icon, $file, $current_file) = @_;
-    local($text);
-    if ($icon eq $contents_visible_mark) { $text = $toc_title }
-    elsif ($icon eq $index_visible_mark) { $text = $idx_title }
-    elsif ($icon eq $biblio_visible_mark) { $text = $bib_title }
-    (($file && ($file ne $current_file)) ? 
-       ("\n" . &make_href($file, $icon), 
-           ($text ? " ". &make_href($file, $text) : undef))
-       : ( undef, undef ))
-}
-
-#RRM: add <LINK ...> tag to the HTML head.
-#     suggested by Marcus Hennecke
-#
-sub add_link_tag {
-    local($rel, $currentfile, @link ) = @_;
-#    local($dummy, $file, $title) = split($delim,$toc_section_info{join(' ',@link)});
-    local($dummy, $file, $title) = split($delim,$section_info{join(' ',@link)});
-    ($dummy, $file, $title) = split($delim,$toc_section_info{join(' ',@link)})
-       unless ($title);
-
-    if ($MULTIPLE_FILES && $ROOTED && $file) {
-        if (!($DESTDIR =~ /\Q$FIXEDDIR\E[$dd$dd]?$/)) { $file = "..$dd$file" }
-    }
-    if ($file && !($file eq $currentfile) && (!$NO_NAVIGATION)) {
-       #RRM: allow user-customisation of the REL attribute
-       if (defined &custom_REL_hook ) {
-           $rel = &custom_REL_hook($rel,$toc_section_info{join(' ',@link)});
-       }
-        $more_links .= "\n<LINK REL=\"$rel\" HREF=\"$file\">";
-    }
-}
-
-sub remove_markers {
-# modifies $_
-    s/$lof_mark//go;
-    s/$lot_mark//go;
-    &remove_bbl_marks;
-    s/$toc_mark//go;
-    s/$idx_mark//go;
-    &remove_cross_ref_marks;
-    &remove_external_ref_marks;
-    &remove_cite_marks;
-    &remove_file_marks;
-# sensitive markers
-    &remove_image_marks;
-    &remove_icon_marks;
-    &remove_verbatim_marks;
-    &remove_verb_marks;
-    &remove_child_marks;
-# uncaught markers
-    s/$percent_mark/%/go;
-    s/$ampersand_mark/\&amp;/go;
-    s/$comment_mark\s*(\d+\n?)?//sgo;
-    s/$caption_mark//go;
-    s/<tex2html[^>]*>//g;
-    s/$OP\d+\$CP//g;
-    $_;
-}
-
-sub replace_markers {
-    &find_quote_ligatures;
-    &replace_general_markers;
-    &text_cleanup;
-    # Must NOT clean the ~'s out of the navigation icons (in panel or text),
-    # and must not interfere with verbatim-like environments
-    &replace_sensitive_markers;
-    &replace_init_file_mark if (/$init_file_mark/);
-    &replace_file_marks;
-    &post_replace_markers;
-}
-
-sub replace_general_markers {
-    if (defined &replace_infopage_hook) {&replace_infopage_hook if (/$info_page_mark/);}
-    else { &replace_infopage if (/$info_page_mark/); }
-    if (defined &add_idx_hook) {&add_idx_hook if (/$idx_mark/);}
-    else {&add_idx if (/$idx_mark/);}
-
-    if ($segment_figure_captions) {
-#      s/$lof_mark/<UL>$segment_figure_captions<\/UL>/o
-#   } else { s/$lof_mark/<UL>$figure_captions<\/UL>/o }
-       s/$lof_mark/$segment_figure_captions/o
-    } else { s/$lof_mark/$figure_captions/o }
-    if ($segment_table_captions) {
-#      s/$lot_mark/<UL>$segment_table_captions<\/UL>/o
-#   } else { s/$lot_mark/<UL>$table_captions<\/UL>/o }
-       s/$lot_mark/$segment_table_captions/o
-    } else { s/$lot_mark/$table_captions/o }
-    &replace_morelinks();
-    if (defined &replace_citations_hook) {&replace_citations_hook if /$bbl_mark/;}
-    else {&replace_bbl_marks if /$bbl_mark/;}
-    if (defined &add_toc_hook) {&add_toc_hook if (/$toc_mark/);}
-    else {&add_toc if (/$toc_mark/);}
-    if (defined &add_childs_hook) {&add_childs_hook if (/$childlinks_on_mark/);}
-    else {&add_childlinks if (/$childlinks_on_mark/);}
-    &remove_child_marks;
-
-    if (defined &replace_cross_references_hook) {&replace_cross_references_hook;}
-    else {&replace_cross_ref_marks if /$cross_ref_mark||$cross_ref_visible_mark/;}
-    if (defined &replace_external_references_hook) {&replace_external_references_hook;}
-    else {&replace_external_ref_marks if /$external_ref_mark/;}
-    if (defined &replace_cite_references_hook) {&replace_cite_references_hook;}
-    else { &replace_cite_marks if /$cite_mark/; }
-    if (defined &replace_user_references) {
-       &replace_user_references if /$user_ref_mark/; }
-}
-
-sub replace_sensitive_markers {
-    if (defined &replace_images_hook) {&replace_images_hook;}
-    else {&replace_image_marks if /$image_mark/;}
-    if (defined &replace_icons_hook) {&replace_icons_hook;}
-    else {&replace_icon_marks if /$icon_mark_rx/;}
-    if (defined &replace_verbatim_hook) {&replace_verbatim_hook;}
-    else {&replace_verbatim_marks if /$verbatim_mark/;}
-    if (defined &replace_verb_hook) {&replace_verb_hook;}
-    else {&replace_verb_marks if /$verb_mark|$verbstar_mark/;}
-    s/;SPMdollar;/\$/g; s/;SPMtilde;/\~/g; s/;SPMpct;/\%/g;
-    s/;SPM/\&/go;
-    s/$percent_mark/%/go;
-    s/$ampersand_mark/\&amp;/go;
-    #JKR: Turn encoded ~ back to normal
-    s/&#126;/~/go;
-}
-
-sub find_quote_ligatures {
-    my $ent;
-
-# guillemets, governed by $NO_FRENCH_QUOTES
-    do {
-       $ent = &iso_map('laquo', "", 1);
-       if ($NO_UTF && !$USE_UTF && $ent=~/\&\#(\d+);/) {
-           $ent='' if ($1 > 255);
-       }
-       s/((\&|;SPM)lt;){2}/$ent/ogs if $ent;
-       $ent = &iso_map('raquo', "", 1) if ($ent);
-       s/((\&|;SPM)gt;){2}/$ent/ogs if $ent;
-       # single guillemot chars cannot be easily implemented this way
-       # finding an approp regexp is work for the future
-    } unless ($NO_FRENCH_QUOTES);
-
-    $ent = &iso_map("gg", "", 1);
-    s/;SPMgg;/($ent ? $ent : '&gt;&gt;')/eg unless ($USE_NAMED_ENTITIES);
-    $ent = &iso_map("ll", "", 1);
-    s/;SPMll;/($ent ? $ent : '&lt;&lt;')/eg unless ($USE_NAMED_ENTITIES);
-
-    my $ldquo, $rdquo;
-# "curly" quotes, governed by  $USE_CURLY_QUOTES.
-    do {
-       $ldquo = &iso_map("ldquo", "", 1);
-       if ($NO_UTF && !$USE_UTF && $ldquo =~ /\&\#(\d+);/) {
-           $ldquo = '' if ($1 > 255);
-       }
-       s/``/$ldquo/ogs if ($ldquo);
-       $rdquo = &iso_map("rdquo", "", 1) if ($ldquo);
-       s/''/$rdquo/ogs if ($rdquo);
-       
-       # single curly quotes cannot be easily implemented this way
-       # finding an approp regexp is work for the future
-    } if ($USE_CURLY_QUOTES);
-
-# "german" quotes, governed by  $NO_GERMAN_QUOTES.
-    do {
-       $ent = &iso_map('bdquo', "", 1);
-       if ($NO_UTF && !$USE_UTF && $ent =~ /\&\#(\d+);/) {
-           $ent = '' if ($1 > 255);
-       }
-       s/,,/$ent/eg if $ent;
-
-       # closing upper quotes are not properly displayed in browsers
-       s/($ent[\w\s\&\#;']+)$ldquo/$1``/og
-               if ($USE_CURLY_QUOTES && $ldquo && $ent);
-    } unless ($NO_GERMAN_QUOTES);
-}
-
-sub add_childlinks {
-    local($before, $after, $star);
-    while (/$childlinks_on_mark\#(\d)\#/) {
-       $star = $1;
-       $before = $`;
-       $after = $';
-       $before =~ s/\n\s*$//;
-       $_ = join('', $before, "\n", $child_links, $after);
-    }
-}
-
-sub replace_infopage {
-    local($INFO)=1 if !(defined $INFO);
-    if ($INFO == 1) {
-       local($title);
-       if ((defined &do_cmd_infopagename)||$new_command{'infopagename'}) {
-           local($br_id)=++$global{'max_id'};
-           $title = &translate_environments("$O$br_id$C\\infopagename$O$br_id$C");
-       } else { $title = $info_title }
-           if ($MAX_SPLIT_DEPTH <= $section_commands{$outermost_level}) {
-               $_ =~ s/(<HR[^>]*>\s*)?$info_title_mark/
-                   ($1? $1 : "\n<HR>")."\n<H2>$title<\/H2>"/eog;
-           } else {
-               $_ =~ s/$info_title_mark/"\n<H2>$title<\/H2>"/eog;
-           }
-    }
-    while (/$info_page_mark/o) {
-       $_ = join('', $`, &do_cmd_textohtmlinfopage, $');
-    }
-}
-
-sub replace_init_file_mark {
-    local($init_file, $init_contents, $info_line)=($INIT_FILE,'','');
-    if (-f $init_file) {
-    } elsif (-f "$orig_cwd$dd$init_file") {
-       $init_file = $orig_cwd.$dd.$init_file;
-    } else {
-       s/$init_file_mark//g;
-       return();
-    }
-    if(open(INIT, "<$init_file")) {
-        foreach $info_line (<INIT>) {
-           $info_line =~ s/[<>"&]/'&'.$html_special_entities{$&}.';'/eg;
-           $init_contents .= $info_line;
-       }
-        close INIT;
-    } else {
-        print "\nError: Cannot read '$init_file': $!\n";
-    }
-    s/$init_file_mark/\n<BLOCKQUOTE><PRE>\n$init_contents\n<\/PRE><\/BLOCKQUOTE>\n/g;
-}
-
-sub replace_morelinks {
-    $_ =~ s/$more_links_mark/$more_links/e;
-}
-
-# This code is extremely inefficient. At least the subtrees should be
-# filtered according to $MAX_LINK_DEPTH before going into the
-# inner loops.
-# RRM: revamped parts, for $TOC_STARS, fixing some errors.
-#
-sub add_child_links { &add_real_child_links(@_) }
-sub add_real_child_links {
-    local($exclude, $base_file, $depth, $star, $current_key, @keys) = @_;
-    local $min_depth = $section_commands{$outermost_level} - 1;
-    return ('') if ((!$exclude)&&(!$LEAF_LINKS)&&($depth >= $MAX_SPLIT_DEPTH));
-    if ((!$depth)&&($outermost_level)) { $depth = $min_depth }
-
-    local($_, $child_rx, @subtree, $next, %open, @roottree);
-    local($first, $what, $pre, $change_key, $list_class);
-    $childlinks_start = "<!--Table of Child-Links-->";
-    $childlinks_end = "<!--End of Table of Child-Links-->\n";
-    $child_rx = $current_key;
-    $child_rx =~ s/( 0)*$//;   # Remove trailing 0's
-    if ((!$exclude)&&($depth < $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH -1 )
-#          &&($depth >= $MAX_SPLIT_DEPTH-1)) {
-           &&($depth > $min_depth)) {
-       if ((defined &do_cmd_childlinksname)||$new_command{'childlinksname'}) {
-           local($br_id)=++$global{'max_id'};
-           $what = &translate_environments("$O$br_id$C\\childlinksname$O$br_id$C");
-       } else {
-           $what = "<strong>$child_name</strong>";
-       }
-       $list_class = ' CLASS="ChildLinks"' if ($USING_STYLES);
-       $first = "$childlinks_start\n<A NAME=\"CHILD_LINKS\">$what<\/A>\n";
-    } elsif ($exclude) {
-       # remove any surrounding braces
-       $exclude =~ s/^($O|$OP)\d+($C|$CP)|($O|$OP)\d+($C|$CP)$//g;
-       # Table-of-Contents
-       $list_class = ' CLASS="TofC"' if ($USING_STYLES);
-       $childlinks_start = "\n<!--Table of Contents-->\n";
-       $childlinks_end = "<!--End of Table of Contents-->";
-       $first = "$childlinks_start";
-    } else {
-       $list_class = ' CLASS="ChildLinks"' if ($USING_STYLES);
-       $first = "$childlinks_start\n"
-           . ($star ? '':"<A NAME=\"CHILD_LINKS\">$anchor_mark<\/A>\n");
-    }
-    my $startlist, $endlist;
-    $startlist = "<UL$list_class>" unless $CHILD_NOLIST;
-    $endlist = '</UL>' unless $CHILD_NOLIST;
-    my $alt_item = '<BR>&nbsp;<BR>'."\n";
-    my $outer_item = ($CHILD_NOLIST ? $alt_item : '<LI>');
-    my $inner_item = '<LI>';
-    my $inner_end = '</UL><BR>';
-
-    # collect the relevant keys...
-    foreach $next (@keys) {
-       if ($MULTIPLE_FILES && $exclude) {
-           # ...all but with this document as the root
-           if ($next =~ /^$THIS_FILE /) {
-#              # make current document the root
-#              $change_key = '0 '.$';
-               push(@roottree,$next);
-               print "\n$next : m-root" if ($VERBOSITY > 3);
-           } else {
-               push(@subtree,$next);
-               print "\n$next : m-sub" if ($VERBOSITY > 3);
-           }
-       } elsif (($next =~ /^$child_rx /)&&($next ne $current_key)) {
-       # ...which start as $current_key
-           push(@subtree,$next);
-           print "\n$next : sub $child_rx" if ($VERBOSITY > 3);
-       } else {
-           print "\n$next : out $current_key" if ($VERBOSITY > 3);
-       }
-    }
-    if (@subtree) { @subtree = sort numerically @subtree; }
-    if (@roottree) {
-       @roottree = sort numerically @roottree;
-       @subtree = ( @roottree, @subtree );
-    }
-    # @subtree now contains the subtree rooted at the current node
-
-    local($countUL); #counter to ensure correct tag matching
-    my $root_file, $href;
-    if (@subtree) {
-       local($next_depth, $file, $title, $sec_title, $star, $ldepth,$this_file, $prev_file);
-       $ldepth = $depth;
-       $prev_file = $base_file;
-#      @subtree = sort numerically @subtree;
-       foreach $next (@subtree) {
-           $title = '';
-           if ($exclude) {
-               # making TOC
-               ($next_depth, $file, $sec_title) =
-                       split($delim,$section_info{$next});
-               ($next_depth, $file, $title, $star) =
-                       split($delim,$toc_section_info{$next});
-               # use the %section_info  title, in case there are images
-               $title = $sec_title if ($sec_title =~ /image_mark>\#/);
-           } else {
-               # making mini-TOC i.e. the child-links tables
-               $star = '';
-               ($next_depth, $file, $title) =
-                       split($delim,$section_info{$next});
-           }
-           $root_file = $file unless $root_file;
-           if ($root_file && $root_file =~ /_mn\./) { $root_file=$` };
-           # remove any surrounding braces
-           $title =~ s/^($O|$OP)\d+($C|$CP)|($O|$OP)\d+($C|$CP)$//g;
-           next if ($exclude && $title =~ /^$exclude$/);
-           if (!$title) {
-               ($next_depth, $file, $title, $star) =
-                       split($delim,$toc_section_info{$next});
-           }
-           $this_file = $file;
-           $title = "\n".$title if !($title =~/^\n/);
-           next if ( $exclude &&(                              # doing Table-of-Contents
-               ( $TOC_DEPTH &&($next_depth > $TOC_DEPTH))      # and  too deep
-               ||($star && !$TOC_STARS ) ));                   # or no starred sections 
-           $file = "" if (!$MAX_SPLIT_DEPTH); # Martin Wilck
-           next if ($exclude && !$MULTIPLE_FILES &&($title =~ /^\s*$exclude\s*$/));
-           next if (!$exclude && $next_depth > $MAX_LINK_DEPTH + $depth);
-           print "\n$next :" if ($VERBOSITY > 3);
-           if ($this_file =~ /^(\Q$prev_file\E|\Q$base_file\E)$/) {
-               $file .= join('', "#SECTION", split(' ', $next));
-           } else { $prev_file = $file }
-
-           if (!$next_depth && $MULTIPLE_FILES) { ++$next_depth }
-           local($num_open) = (split('/',%open))[0];
-           if ((($next_depth > $ldepth)||$first)
-               && ((split('/',%open))[0] < $MAX_LINK_DEPTH + $depth )
-               ) {
-               # start a new <UL> list
-               if ($first) {
-                   $_ = "$first\n$startlist\n"; $countUL++;
-                   local $i = 1;
-                   while ($i <= $ldepth) {
-                       $open{$i}=0; $i++
-                   }
-                   $first = '';        # include NAME tag first time only
-                   while ($i < $next_depth) {
-                       $open{$i}=1; $i++; 
-                       $_ .= ($countUL >1 ? $inner_item : $outer_item)."<UL>\n";
-                       $countUL++;
-                   }
-               } else {
-                   $_ .= "<UL>\n"; $countUL++;
-               }
-               $ldepth = $next_depth;
-               $open{$ldepth}++; 
-               # append item to this list
-               print " yes " if ($VERBOSITY > 3);
-               if (defined &add_frame_child_links) {
-                   $href = &make_href($file,$title);
-                   if ($href =~ s/($root_file)_mn/$1_ct/) {
-                       $href =~ s/(target=")main(")/$1contents$2/i;
-                   };
-                   $_ .= ($countUL >1 ? $inner_item : $outer_item)
-                       . $href . "\n";
-               } else {
-                   $_ .= ($countUL >1 ? $inner_item : $outer_item)
-                       . &make_href($file,$title) . "\n";
-               }
-           }
-           elsif (($next_depth)&&($next_depth <= $ldepth)
-               &&((split('/',%open))[0] <= $MAX_LINK_DEPTH + $depth )
-               ) {
-               # append item to existing <UL> list
-               while (($next_depth < $ldepth) && %open ) {
-               # ...closing-off any nested <UL> lists
-                   if ($open{$ldepth}) {
-                       if (!(defined $open{$next_depth}))  {
-                           $open{$next_depth}++;
-                       } else {
-                           $_ .= ($countUL==2 ? $inner_end : '</UL>')."\n";
-                           $countUL--;
-                       }
-                       delete $open{$ldepth};
-                   };
-                   $ldepth--;
-               }
-               $ldepth = $next_depth;
-               print " yes" if ($VERBOSITY > 3);
-               if (defined &add_frame_child_links) {
-                   $href = &make_href($file,$title);
-                   if ($href =~ s/($root_file)_mn/$1_ct/) {
-                       $href =~ s/(target=")main(")/$1contents$2/i;
-                   };
-                   $_ .= ($countUL >1 ? $inner_item : $outer_item)
-                       . $href . "\n";
-               } else {
-                   $_ .= ($countUL >1 ? $inner_item : $outer_item)
-                       . &make_href($file,$title) . "\n";
-               }
-           } else {
-               # ignore items that are deeper than $MAX_LINK_DEPTH
-               print " no" if ($VERBOSITY > 3);
-           }
-       }
-
-       if (%open) {
-       # close-off any remaining <UL> lists
-           $countUL-- if $CHILD_NOLIST;
-           local $cnt = (split('/',%open))[0];
-           local $i = $cnt;
-               while ($i > $depth) { 
-                   if ($open{$i}) {
-                       $_ .= '</UL>' if $countUL;
-                       $countUL--;
-                       delete $open{$i};
-                   }
-               $i--;
-           }
-       }
-    }
-    # just in case the count is wrong
-    $countUL-- if ($CHILD_NOLIST && $countUL > 0);
-    $countUL = '' if ($countUL < 0);
-    while ($countUL) { $_ .= '</UL>'; $countUL-- }
-    ($_ ? join('', $_, "\n$childlinks_end") : '');
-}
-
-sub child_line {($CHILDLINE) ? "$CHILDLINE" : "<BR>\n<HR>";}
-sub upper_child_line { "<HR>\n"; }
-
-sub adjust_root_keys {
-    return() unless ($MULTIPLE_FILES && $ROOTED);
-    local($next,$change_key,$current_rx);
-    local(@keys) = (keys %toc_section_info);
-    
-    local($current_key) = join(' ',@curr_sec_id);
-    $current_key =~ /^(\d+ )/;
-    $current_rx = $1;
-    return() unless $current_rx;
-
-    # alter the keys which start as $current_key
-    foreach $next (@keys) {
-       if ($next =~ /^$current_rx/) {
-           # make current document the root
-           $change_key = '0 '.$';
-           $toc_section_info{$change_key} = $toc_section_info{$next};
-           $section_info{$change_key} = $section_info{$next};
-#          if (!($next eq $current_key)) {
-#              $toc_section_info{$next} = $section_info{$next} = '';
-#          }
-       }
-    }
-}
-
-sub top_page {
-    local($file, @navigation_panel) = @_;
-    # It is the top page if there is a link to itself
-    join('', @navigation_panel) =~ /$file/;
-}
-
-# Sets global variable $AUX_FILE
-sub process_aux_file {
-    local(@exts) = ('aux');
-    push(@exts, 'lof') if (/\\listoffigures/s);
-    push(@exts, 'lot') if (/\\listoftables/s);
-    local($_, $status);                # To protect caller from &process_ext_file
-    $AUX_FILE = 1;
-    foreach $auxfile (@exts) {
-       $status = &process_ext_file($auxfile);
-       if ($auxfile eq "aux" && ! $status) {
-           print "\nCannot open $FILE.aux $!\n";
-           &write_warnings("\nThe $FILE.aux file was not found," .
-                           " so sections will not be numbered \nand cross-references "
-                           . "will be shown as icons.\n");
-       }
-    }
-    $AUX_FILE = 0;
-}
-
-sub do_cmd_htmlurl {
-    local($_) = @_;
-    local($url);
-    $url = &missing_braces unless (
-       (s/$next_pair_pr_rx/$br_id=$1;$url=$2;''/e)
-       ||(s/$next_pair_rx/$br_id=$1;$url=$2;''/e));
-    $url =~ s/\\(html)?url\s*($O|$OP)([^<]*)\2/$3/;
-    $url =~ s/\\?~/;SPMtilde;/og;
-    join('','<TT>', &make_href($url,$url), '</TT>', $_);
-}
-sub do_cmd_url { &do_cmd_htmlurl(@_) }
-
-sub make_href { &make_real_href(@_) }
-sub make_real_href {
-    local($link, $text) = @_;
-    $href_name++;
-    my $htarget = '';
-    $htarget = ' target="'.$target.'"'
-       if (($target)&&($HTML_VERSION > 3.2));
-    #HWS: Nested anchors not allowed.
-    $text =~ s/<A .*><\/A>//go;
-    #JKR: ~ is handled different - &#126; is turned to ~ later.
-    #$link =~ s/&#126;/$percent_mark . "7E"/geo;
-    if ($text eq $link) { $text =~ s/~/&#126;/g; }
-    $link =~ s/~/&#126;/g;
-    # catch \url or \htmlurl
-    $link =~ s/\\(html)?url\s*(($O|$OP)\d+($C|$CP))([^<]*)\2/$5/;
-    $link =~ s:(<TT>)?<A [^>]*>([^<]*)</A>(</TT>)?(([^<]*)|$):$2$4:;
-    # this should not be here; else TOC, List of Figs, etc. fail:
-    # $link =~ s/^\Q$CURRENT_FILE\E(\#)/$1/ unless ($SEGMENT||$SEGMENTED);
-    $text = &simplify($text);
-    "<A NAME=\"tex2html$href_name\"$htarget\n  HREF=\"$link\">$text</A>";
-}
-
-sub make_href_noexpand { # clean
-    my ($link, $name, $text) = @_;
-    do {$name = "tex2html". $href_name++} unless $name;
-    #HWS: Nested anchors not allowed.
-    $text =~ s/<A .*><\/A>//go;
-    #JKR: ~ is handled different - &#126; is turned to ~ later.
-    #$link =~ s/&#126;/$percent_mark . "7E"/geo;
-    if ($text eq $link) { $text =~ s/~/&#126;/g; }
-    $link =~ s/~/&#126;/g;
-    # catch \url or \htmlurl
-    $link =~ s/\\(html)?url\s*(($O|$OP)\d+($C|$CP))([^<]*)\2/$5/;
-    $link =~ s:(<TT>)?<A [^>]*>([^<]*)</A>(</TT>)?(([^<]*)|$):$2$4:;
-    "<A NAME=\"$name\"\n HREF=\"$link\">$text</A>";
-}
-
-sub make_named_href {
-    local($name, $link, $text) = @_;
-    $text =~ s/<A .*><\/A>//go;
-    $text = &simplify($text);
-    if ($text eq $link) { $text =~ s/~/&#126;/g; }
-    $link =~ s/~/&#126;/g;
-    # catch \url or \htmlurl
-    $link =~ s/\\(html)?url\s*(($O|$OP)\d+($C|$CP))([^<]*)\2/$5/;
-    $link =~ s:(<TT>)?<A [^>]*>([^<]*)</A>(</TT>)?(([^<]*)|$):$2$4:;
-    if (!($name)) {"<A\n HREF=\"$link\">$text</A>";}
-    elsif ($text =~ /^\w/) {"<A NAME=\"$name\"\n HREF=\"$link\">$text</A>";}
-    else {"<A NAME=\"$name\"\n HREF=\"$link\">$text</A>";}
-}
-
-sub make_section_heading {
-    local($text, $level, $anchors) = @_;
-    local($elevel) = $level; $elevel =~ s/^(\w+)\s.*$/$1/;
-    local($section_tag) = join('', @curr_sec_id);
-    local($align,$pre_anchors);
-
-    # separate any invisible anchors or alignment, if this has not already been done
-    if (!($anchors)){ ($anchors,$text) = &extract_anchors($text) }
-    else { 
-       $anchors =~ s/(ALIGN=\"\w*\")/$align = " $1";''/e;
-       $align = '' if ($HTML_VERSION < 2.2);
-       $anchors = &translate_commands($anchors) if ($anchors =~ /\\/);
-    }
-
-    # strip off remains of bracketings
-    $text =~ s/$OP\d+$CP//g;
-    if (!($text)) {
-       # anchor to a single `.' only
-       $text = "<A NAME=\"SECTION$section_tag\">.</A>$anchors\n";
-    } elsif ($anchors) {
-#      # put anchors immediately after, except if title is too long
-#      if ((length($text)<60 )&&(!($align)||($align =~/left/))) {
-#          $text = "<A NAME=\"SECTION$section_tag\">$text</A>\n" . $anchors;
-       # ...put anchors preceding the title, on a separate when left-aligned
-#      } else {
-           $text = "<A NAME=\"SECTION$section_tag\">$anchor_invisible_mark</A>$anchors"
-               . (!($align)||($align =~ /left/i ) ? "<BR>" : "") . "\n". $text;
-#      }
-    } elsif (!($text =~ /<A[^\w]/io)) {
-       # no embedded anchors, so anchor it all
-       $text = "<A NAME=\"SECTION$section_tag\">\n" . $text . "</A>";
-    } else {
-       # there are embedded anchors; these cannot be nested
-       local ($tmp) = $text;
-       $tmp =~ s/<//o ;        # find 1st <
-       if ($`) {               # anchor text before the first < 
-#          $text = "<A NAME=\"SECTION$section_tag\">\n" . $` . "</A>\n<" . $';
-           $text = "<A NAME=\"SECTION$section_tag\">\n" . $` . "</A>";
-           $pre_anchors = "<" . $';
-           if ($pre_anchors =~ /^(<A NAME=\"[^\"]+>${anchor_invisible_mark}<\/A>\s*)+$/) {
-               $pre_anchors .= "\n"
-           } else { $text .= $pre_anchors; $pre_anchors = '' }
-       } else {
-           # $text starts with a tag
-           local($after,$tmp) = ($','');
-           if ( $after =~ /^A[^\w]/i ) {       
-               # it is an anchor already, so need a separate line
-               $text = "<A NAME=\"SECTION$section_tag\">$anchor_invisible_mark</A><BR>\n$text";
-           } else {
-               # Is it a tag enclosing the anchor ?
-               $after =~ s/^(\w)*[\s|>]/$tmp = $1;''/eo;
-               if ($after =~ /<A.*<\/$tmp>/) {
-                   # it encloses an anchor, so use anchor_mark + break
-                   $text = "<A NAME=\"SECTION$section_tag\">$anchor_invisible_mark</A><BR>\n$text";
-               } else {
-                   # take up to the anchor
-                   $text =~ s/^(.*)<A([^\w])/"<A NAME=\"SECTION$section_tag\">$1<A$2"/oe;
-               }
-           }
-       }
-    }
-    "$pre_anchors\n<$level$align>$text\n<\/$elevel>";
-}
-
-sub do_cmd_captionstar { &process_cmd_caption(1, @_) }
-sub do_cmd_caption { &process_cmd_caption('', @_) }
-sub process_cmd_caption {
-    local($noLOTentry, $_) = @_;
-    local($text,$opt,$br_id, $contents);
-    local($opt) = &get_next_optional_argument;
-    $text = &missing_braces unless (
-       (s/$next_pair_pr_rx/$br_id=$1;$text=$2;''/e)
-       ||(s/$next_pair_rx/$br_id=$1;$text=$2;''/e));
-
-    # put it in $contents, so &extract_captions can find it
-    local($contents) = join('','\caption', ($opt ? "[$opt]" : '')
-          , "$O$br_id$C" , $text , "$O$br_id$C");
-
-    # $cap_env is set by the surrounding figure/table
-    &extract_captions($cap_env);
-    $contents.$_;
-}
-
-sub extract_captions {
-    # Uses and modifies $contents and $cap_anchors, defined in translate_environments
-    # and modifies $figure_captions, $table_captions, $before and $after
-    # MRO: no effect! local($env,*cap_width) = @_;
-    local($env) = @_;
-    local(%captions, %optional_captions, $key, $caption, $optional_caption,
-         $item, $type, $list, $extra_list, $number, @tmp, $br_id, $_);
-    # associate the br_id of the caption with the argument of the caption
-    $contents =~ s/$caption_rx(\n)?/do {
-       $key = $9; $caption = $10; $optional_caption = $3;
-       $key = &filter_caption_key($key) if (defined &filter_caption_key);
-       $optional_captions{$key} = $optional_caption||$caption;
-       $captions{$key} = $10; ''}/ego;
-#      $captions{$9} = $10; $caption_mark }/ego;
-    $key = $caption = $optional_caption = '';
-
-    #catch any  \captionwidth  settings that may remain
-    $contents =~ s/$caption_width_rx(\n)?/&translate_commands($&);''/eo;
-    
-#    $after = join("","<P>",$after) if ($&);
-#    $before .= "</P>" if ($&);
-    #JKR: Replaced "Figure" and "Table" with variables (see latex2html.config too).
-    if ($env eq 'figure') {
-       if ((defined &do_cmd_figurename)||$new_command{'figurename'}){
-           $br_id = ++$global{'max_id'};
-           $type = &translate_environments("$O$br_id$C\\figurename$O$br_id$C")
-               unless ($noLOFentry);
-       } else { $type = $fig_name }
-       $list = "\$figure_captions";
-#      $extra_list = "\$segment_figure_captions" if ($figure_table_captions);
-       $extra_list = "\$segment_figure_captions" if ($segment_figure_captions);
-    }
-    elsif ($env =~ /table/) {
-       if ((defined &do_cmd_tablename)||$new_command{'tablename'}) {
-           $br_id = ++$global{'max_id'};
-           $type = &translate_environments("$O$br_id$C\\tablename$O$br_id$C")
-               unless ($noLOTentry);
-       } else { $type = $tab_name }
-       $list = "\$table_captions";
-       $extra_list = "\$segment_table_captions" if ($segment_table_captions);
-    }
-
-#    $captions = "";
-    $cap_anchors = "";
-    local($this);
-    foreach $key (sort {$a <=> $b;} keys %captions){ # Sort numerically
-       $this = $captions{$key};
-       $this =~ s/\\label\s*($O\d+$C)[^<]+\1//g; # remove \label commands
-               local($br_id) = ++$global{'max_id'};
-       local($open_tags_R) = []; # locally, initially no style
-       $caption = &translate_commands(
-            &translate_environments("$O$br_id$C$this$O$br_id$C"));
-
-       # same again for the optional caption
-       $this = $optional_captions{$key};
-       $this =~ s/\\label\s*($O\d+$C)[^<]+\1//g; # remove \label commands
-       local($open_tags_R) = []; local($br_id) = ++$global{'max_id'};
-       $this = &translate_environments("$O$br_id$C$this$O$br_id$C");
-       $optional_caption = &translate_commands($this);
-
-       $cap_anchors .= "<A NAME=\"$key\">$anchor_mark</A>";
-       $_ = $optional_caption || $caption;
-
-
-       # split at embedded anchor or citation marker
-       local($pre_anchor,$post_anchor) = ('','');
-       if (/\s*(<A\W|\#[^#]*\#<tex2html_cite_[^>]*>)/){
-           $pre_anchor = "$`";
-           $post_anchor = "$&$'";
-           $pre_anchor = $anchor_invisible_mark
-               unless (($pre_anchor)||($SHOW_SECTION_NUMBERS));
-       } else {
-           $pre_anchor = "$_";
-       }
-
-#JCL(jcl-tcl)
-##     &text_cleanup;
-##     $_ = &encode_title($_);
-##     s/&nbsp;//g;            # HWS - LaTeX changes ~ in its .aux files
-#      $_ = &sanitize($_);
-##
-#      $_ = &revert_to_raw_tex($_);
-
-       #replace image-markers by the image params
-       s/$image_mark\#([^\#]+)\#/&purify_caption($1)/e;
-
-       local($checking_caption, $cap_key) = (1, $_);
-       $cap_key = &simplify($cap_key);
-       $cap_key = &sanitize($cap_key);
-       @tmp = split(/$;/, eval ("\$encoded_$env" . "_number{\$cap_key}"));
-       $number = shift(@tmp);
-       $number = "" if ($number eq "-1");
-
-       if (!$number) {
-           $cap_key = &revert_to_raw_tex($cap_key);
-           @tmp = split(/$;/
-              , eval ("\$encoded_$env" . "_number{\$cap_key}"));
-           $number = shift(@tmp);
-           $number = "" if ($number eq "-1");
-       }
-
-       #resolve any embedded cross-references first
-       $checking_caption = '';
-       $_ = &simplify($_);
-       $_ = &sanitize($_);
-
-
-#      @tmp = split(/$;/, eval ("\$encoded_$env" . "_number{\$_}"));
-#      $number = shift(@tmp);
-#      $number = "" if ($number eq "-1");
-
-       &write_warnings(qq|\nNo number for "$_"|) if (! $number);
-       eval("\$encoded_$env" . "_number{\$_} = join(\$;, \@tmp)");
-
-       $item = join( '', ($SHOW_SECTION_NUMBERS ? $number."\. " : '')
-           , &make_href("$CURRENT_FILE#$key", $pre_anchor)
-           , $post_anchor);
-       undef $_;
-       undef @tmp;
-
-       $captions = join("", ($captions ? $captions."\n<BR>\n" : '')
-               , "<STRONG>$type" , ($number ? " $number:" : ":")
-               , "</STRONG>\n$caption" , (($captions) ? "\n" : "" ));
-
-       do {
-           eval "$extra_list .= \"\n<LI>\" .\$item" if ($extra_list);
-           eval "$list .= \"\n<LI>\" .\$item" }
-                unless ( $noLOTentry || $noLOFentry);
-#      eval("print \"\nCAPTIONS:\".$extra_list.\n\"");
-    }
-}
-
-
-# This processes \label commands found in environments that will
-# be handed over to Latex. Sets the table %symbolic_labels
-sub do_labels {
-    local($context,$new_context) = @_;
-    local($label);
-    # MRO: replaced $* by /m
-    $context =~ s/\s*$labels_rx/do {
-       $label = &do_labels_helper($2);
-       $new_context = &anchor_label($label,$CURRENT_FILE,$new_context);""}/geom;
-    $new_context;
-}
-
-sub extract_labels {
-    local($_) = @_;
-    local($label,$anchors);
-    # MRO: replaced $* by /m
-    while (s/[ \t]*$labels_rx//om) {
-        $label = &do_labels_helper($2);
-        $anchors .= &anchor_label($label,$CURRENT_FILE,'');
-    }
-    ($_, $anchors);
-}
-
-# This should be done inside the substitution but it doesn't work ...
-sub do_labels_helper {
-    local($_) = @_;
-    s/$label_rx/_/g;  # replace non-alphanumeric characters
-    $symbolic_labels{$_} = $latex_labels{$_}; # May be empty;
-    $_;
-}
-
-sub convert_to_description_list {
-    # MRO: modified to use $_[1]
-    # local($which, *list) = @_;
-    my $which = $_[0];
-    $_[1] =~ s!(</A>\s*)<[OU]L([^>]*)>!$1<DD><DL$2>!ig;
-    $_[1] =~ s!<(/?)[OU]L([^>]*)>!$1? "<$1DL$2>":"<DL$2>"!eig;
-    $_[1] =~ s!(</?)LI>!$1D$which>!ig;
-#    $_[1] =~ s/^\s*<DD>//;
-}
-
-sub add_toc { &add_real_toc(@_) }
-sub add_real_toc {
-    local($temp1, $temp2);
-    print "\nDoing table of contents ...";
-    local(@keys) = keys %toc_section_info;
-    @keys = sort numerically @keys;
-    $temp1 = $MAX_LINK_DEPTH; $temp2 = $MAX_SPLIT_DEPTH;
-    $MAX_SPLIT_DEPTH = $MAX_LINK_DEPTH = 1000;
-    #JKR: Here was a "Contents" - replaced it with $toc_title
-    local($base_key) = $keys[0];
-    if ($MULTIPLE_FILES) {
-       $base_key = $THIS_FILE;
-    }
-    local($title);
-    if ((defined &do_cmd_contentsname)||$new_command{'contentsname'}) {
-       local($br_id)=++$global{'max_id'};
-       $title = &translate_environments("$O$br_id$C\\contentsname$O$br_id$C");
-    } else { $title = $toc_title }
-    local($toc,$on_first_page) = ('','');
-    $on_first_page = $CURRENT_FILE
-       unless ($MAX_SPLIT_DEPTH && $MAX_SPLIT_DEPTH <1000);
-    $toc = &add_child_links($title,$on_first_page,'',1,$keys[0],@keys);
-    &convert_to_description_list('T',$toc) if ($use_description_list);
-    s/$toc_mark/$toc/;
-    $MAX_LINK_DEPTH = $temp1; $MAX_SPLIT_DEPTH = $temp2;
-}
-
-# Assign ref value, but postpone naming the label
-sub make_half_href {
-    local($link) = $_[0];
-    $href_name++;
-    "<A NAME=\"tex2html$href_name\"\n HREF=\"$link\">";
-}
-
-
-# Redefined in makeidx.perl
-sub add_idx {
-    local($sidx_style, $eidx_style) =('<STRONG>','</STRONG>');
-    if ($INDEX_STYLES) {
-       if ($INDEX_STYLES =~/,/) {
-       local(@styles) = split(/\s*,\s*/,$INDEX_STYLES);
-           $sidx_style = join('','<', join('><',@styles) ,'>');
-           $eidx_style = join('','</', join('></',reverse(@styles)) ,'>');
-       } else {
-           $sidx_style = join('','<', $INDEX_STYLES,'>');
-           $eidx_style = join('','</', $INDEX_STYLES,'>');
-       }
-    }
-    &add_real_idx(@_)
-}
-sub add_real_idx {
-    print "\nDoing the index ...";
-    local($key, $str, @keys, $index, $level, $count,
-         @previous, @current);
-    @keys = keys %index;
-    @keys = sort keysort  @keys;
-    $level = 0;
-    foreach $key (@keys) {
-       @current = split(/!/, $key);
-       $count = 0;
-       while ($current[$count] eq $previous[$count]) {
-           $count++;
-       }
-       while ($count > $level) {
-           $index .= "\n<DL COMPACT>";
-           $level++;
-       }
-       while ($count < $level) {
-           $index .= "\n</DL>";
-           $level--;
-       }
-       foreach $term (@current[$count .. $#current-1]) {
-           # need to "step in" a little
-#          $index .= "<DT>" . $term . "\n<DL COMPACT>";
-           $index .= "\n<DT>$sidx_style" . $term . "$eidx_style\n<DD><DL COMPACT>";
-           $level++;
-       }
-       $str = $current[$#current];
-       $str =~ s/\#\#\#\d+$//o; # Remove the unique id's
-       $index .= $index{$key} .
-           # If it's the same string don't start a new line
-           (&index_key_eq(join('',@current), join('',@previous)) ?
-            ", $sidx_style" . $cross_ref_visible_mark . "$eidx_style</A>\n" :
-            "<DT>$sidx_style" . $str . "$eidx_style</A>\n");
-       @previous = @current;
-    }
-    while ($count < $level) {
-       $index .= "\n</DL>";
-       $level--;
-    }
-    $index = '<DD>'.$index unless ($index =~ /^\s*<D(T|D)>/);
-
-    $index =~ s/(<A [^>]*>)(<D(T|D)>)/$2$1/g;
-    
-#    s/$idx_mark/<DL COMPACT>$index<\/DL>/o;
-    s/$idx_mark/$preindex\n<DL COMPACT>\n$index<\/DL>\n/o;
-}
-
-sub keysort {
-    local($x, $y) = ($a,$b);
-    $x = &clean_key($x);
-    $y = &clean_key($y);
-#    "\L$x" cmp "\L$y";  # changed sort-rules, by M Ernst.
-    # Put alphabetic characters after symbols; already downcased
-    $x =~ s/^([a-z])/~~~$1/;
-    $y =~ s/^([a-z])/~~~$1/;
-    $x cmp $y;
-}
-
-sub index_key_eq {
-    local($a,$b) = @_;
-    $a = &clean_key($a);
-    $b = &clean_key($b);
-    $a eq $b;
-}
-
-sub clean_key {
-    local ($_) = @_;
-    tr/A-Z/a-z/;
-    s/\s+/ /g;         # squeeze white space and newlines into space
-    s/ (\W)/$1/g;      # make foo( ), foo () and foo(), or <TT>foo</TT>
-    ;                  # and <TT>foo </TT> to be equal
-    s/$O\d+$C//go;     # Get rid of bracket id's
-    s/$OP\d+$CP//go;   # Get rid of processed bracket id's
-    s/\#\#\#\d+$//o;   # Remove the unique id
-    $_;
-}
-
-
-sub make_footnotes {
-    # Uses $footnotes defined in translate and set in do_cmd_footnote
-    # Also uses $footfile
-    local($_) = "\n<DL>$footnotes\n<\/DL>";
-    $footnotes = ""; # else they get used
-    local($title);
-    if ((defined &do_cmd_footnotename)||$new_command{'footnotename'}) {
-       local($br_id)=++$global{'max_id'};
-       $title = &translate_environments("$O$br_id$C\\footnotename$O$br_id$C");
-    } else {
-       $foot_title = "Footnotes" unless $foot_title;
-       $title = $foot_title;
-    }
-    print "\nDoing footnotes ...";
-#JCL(jcl-tcl)
-# If the footnotes go into a separate file: see &make_file.
-    if ($footfile) {
-       $toc_sec_title = $title;
-       &make_file($footfile, $title, $FOOT_COLOR); # Modifies $_;
-       $_ = "";
-    } else {
-       $footnotes = ""; # else they get re-used
-       $_ = join ('', '<BR><HR><H4>', $title, '</H4>', $_ );
-    }
-    $_;
-}
-
-sub post_process_footnotes {
-    &slurp_input($footfile);
-    open(OUT, ">$footfile") || die "Cannot write file '$footfile': $!\n";
-    &replace_markers;
-    &post_post_process if (defined &post_post_process);
-    &adjust_encoding;
-    print OUT $_;
-    close OUT;
-}
-
-sub make_file {
-    # Uses and modifies $_ defined in the caller
-    local($filename, $title, $layout) = @_;
-    $layout = $BODYTEXT unless $layout;
-    $_ = join('',&make_head_and_body($title,$layout), $_
-       , (($filename =~ /^\Q$footfile\E$/) ? '' : &make_address )
-       , (($filename =~ /^\Q$footfile\E$/) ? "\n</BODY>\n</HTML>\n" : '')
-       );
-    &replace_markers unless ($filename eq $footfile); 
-
-    unless(open(FILE,">$filename")) {
-        print "\nError: Cannot write '$filename': $!\n";
-        return;
-    }
-    print FILE $_;
-    close(FILE);
-}
-
-sub add_to_body {
-    local($attrib, $value) = @_;
-    local($body) = $BODYTEXT;
-    if ($body =~ s/\Q$attrib\E\s*=\s*"[^"]*"/$attrib="$value"/) {
-    } else {
-       $body .= " $attrib=\"$value\""; $body =~ s/\s{2,}/ /g;
-    }
-    $BODYTEXT = $body if $body;
-}
-
-sub replace_verbatim_marks {
-    # Modifies $_
-    my($tmp);
-    s/$math_verbatim_rx/&make_comment('MATH', $verbatim{$1})/eg;
-    s/$mathend_verbatim_rx/&make_comment('MATHEND', '')/eg;
-#    s/$verbatim_mark(verbatim\*?)(\d+)#/<PRE>\n$verbatim{$2}\n<\/PRE>/go;
-##    s/$verbatim_mark(\w*[vV]erbatim\*?)(\d+)#/\n$verbatim{$2}\n/go;
-    s!$verbatim_mark(\w*[vV]erbatim\*?|tex2html_code)(\d+)#\n?!$tmp=$verbatim{$2};
-       $tmp.(($tmp =~/\n\s*$/s)? '':"\n")!eg;
-#      "\n".$tmp.(($tmp =~/\n\s*$/s)? '':"\n")!eg;
-#    s/$verbatim_mark(rawhtml)(\d+)#/$verbatim{$2}/eg; # Raw HTML
-    s/$verbatim_mark(imagesonly)(\d+)#//eg; # imagesonly is *not* replaced
-    # Raw HTML, but replacements may have protected characters
-    s/$verbatim_mark(rawhtml)(\d+)#/&unprotect_raw_html($verbatim{$2})/eg;
-    s/$verbatim_mark$keepcomments_rx(\d+)#/$verbatim{$2}/ego; # Raw TeX
-    s/$unfinished_mark$keepcomments_rx(\d+)#/$verbatim{$2}/ego; # Raw TeX
-}
-
-# TeX's special characters may have been escaped with a '\'; remove it.
-sub unprotect_raw_html {
-    local($raw) = @_;
-    $raw =~ s/\\($latex_specials_rx|~|\^|@)/$1/g;
-    $raw;
-}
-
-# remove file-markers; special packages may redefine &replace_file_marks
-sub remove_file_marks {
-    s/<(DD|LI)>\n?($file_mark|$endfile_mark)\#.*\#\n<\/\1>(\n|(<))/$4/gm;
-    s/($file_mark|$endfile_mark)\#.*\#(\n|(<))/$3/gm;
-}
-sub replace_file_marks { &remove_file_marks }
-
-sub remove_verbatim_marks {
-    # Modifies $_
-    s/($math_verbatim_rx|$mathend_verbatim_rx)//go;
-#    s/$verbatim_mark(verbatim\*?)(\d+)#//go;
-    s/$verbatim_mark(\w*[Vv]erbatim\w*\*?)(\d+)#//go;
-    s/$verbatim_mark(rawhtml|imagesonly)(\d+)#//go;
-    s/$verbatim_mark$keepcomments_rx(\d+)#//go;
-    s/$unfinished_mark$keepcomments_rx(\d+)#//go;
-}
-
-sub replace_verb_marks {
-    # Modifies $_
-    s/(?:$verb_mark|$verbstar_mark)(\d+)$verb_mark/
-       $code = $verb{$1};
-       $code = &replace_comments($code) if ($code =~ m:$comment_mark:);
-       "<code>$code<\/code>"/ego;
-}
-
-sub replace_comments{
-    local($_) = @_;
-    $_ =~ s/$comment_mark(\d+)\n?/$verbatim{$1}/go;
-    $_ =~ s/$comment_mark\d*\n/%\n/go;
-    $_;
-}
-
-sub remove_verb_marks {
-    # Modifies $_
-    s/($verb_mark|$verbstar_mark)(\d+)$verb_mark//go;
-}
-
-# This is used by revert_to_raw_tex
-sub revert_verbatim_marks {
-    # Modifies $_
-#    s/$verbatim_mark(verbatim)(\d+)#/\\begin{verbatim}$verbatim{$2}\\end{verbatim}\n/go;
-    s/$verbatim_mark(\w*[Vv]erbatim)(\d+)#/\\begin{$1}\n$verbatim{$2}\\end{$1}\n/go;
-    s/$verbatim_mark(rawhtml)(\d+)#/\\begin{rawhtml}\n$verbatim{$2}\\end{rawhtml}\n/go;
-    s/$verbatim_mark(imagesonly|tex2html_code)(\d+)#\n?/$verbatim{$2}/go;
-    s/$verbatim_mark$image_env_rx(\d+)#/\\begin{$1}\n$verbatim{$2}\\end{$1}\n/go;
-    s/($math_verbatim_rx|$mathend_verbatim_rx)//go;
-}
-
-sub revert_verb_marks {
-    # Modifies $_
-    s/$verbstar_mark(\d+)$verb_mark/\\verb*$verb_delim{$1}$verb{$1}$verb_delim{$1}/go;
-    s/$verb_mark(\d+)$verb_mark/\\verb$verb_delim{$1}$verb{$1}$verb_delim{$1}/go;
-}
-
-sub replace_cross_ref_marks {
-    # Modifies $_
-    local($label,$id,$ref_label,$ref_mark,$after,$name);
-    local($invis) = "<tex2html_anchor_invisible_mark></A>";
-#    s/$cross_ref_mark#([^#]+)#([^>]+)>$cross_ref_mark/
-    s/$cross_ref_mark#([^#]+)#([^>]+)>$cross_ref_mark<\/A>(\s*<A( NAME=\"\d+)\">$invis)?/
-       do {($label,$id) = ($1,$2); $name = $4;
-           $ref_label = $external_labels{$label} unless
-               ($ref_label = $ref_files{$label});
-           print "\nXLINK<: $label : $id :$name " if ($VERBOSITY > 3);
-           $ref_label = '' if ($ref_label eq $CURRENT_FILE);
-           $ref_mark = &get_ref_mark($label,$id);
-           &extend_ref if ($name); $name = '';
-           print "\nXLINK: $label : $ref_label : $ref_mark " if ($VERBOSITY > 3);
-           '"' . "$ref_label#$label" . "\">" . $ref_mark . "<\/A>"
-       }/geo;
-
-    # This is for pagerefs which cannot have symbolic labels ??? 
-#    s/$cross_ref_mark#(\w+)#\w+>/
-    s/$cross_ref_mark#([^#]+)#[^>]+>/
-       do {$label = $1;
-           $ref_label = $external_labels{$label} unless
-               ($ref_label = $ref_files{$label});
-           $ref_label = '' if ($ref_label eq $CURRENT_FILE);
-           print "\nXLINKP: $label : $ref_label" if ($VERBOSITY > 3);
-           '"' . "$ref_files{$label}#$label" . "\">"
-       }/geo;
-}
-
-#RRM: this simply absorbs the name from the invisible anchor following, 
-#     when the anchor itself is not already named.
-sub extend_ref {
-    if ($ref_label !=~ /NAME=/) { $label .= "\"\n".$name  }
-}
-
-sub remove_cross_ref_marks {
-    # Modifies $_
-#    s/$cross_ref_mark#(\w+)#(\w+)>$cross_ref_mark/
-    s/$cross_ref_mark#([^#]+)#([^>]+)>$cross_ref_mark/
-       print "\nLOST XREF: $1 : $2" if ($VERBOSITY > 3);''/ego;
-#    s/$cross_ref_mark#(\w+)#\w+>//go;
-    s/$cross_ref_mark#([^#]+)#[^#>]+>//go;
-}
-
-sub replace_external_ref_marks {
-    # Modifies $_
-    local($label, $link);
-#    s/$external_ref_mark#(\w+)#(\w+)>$external_ref_mark/
-    s/$external_ref_mark#([^#]+)#([^>]+)>$external_ref_mark/
-       do {($label,$id) = ($1,$2); 
-           $link = $external_labels{$label};
-           print "\nLINK: $label : $link" if ($VERBOSITY > 3);
-           '"'. "$link#$label" . "\">\n"
-              . &get_ref_mark("userdefined$label",$id)
-       }
-    /geo;
-}
-
-sub remove_external_ref_marks {
-    # Modifies $_
-#    s/$external_ref_mark#(\w+)#(\w+)>$external_ref_mark/
-    s/$external_ref_mark#([^#]+)#([^>]+)>$external_ref_mark/
-       print "\nLOST LINK: $1 : $2" if ($VERBOSITY > 3);''/ego;
-}
-
-sub get_ref_mark {
-    local($label,$id) = @_;
-    ( ( $SHOW_SECTION_NUMBERS && $symbolic_labels{"$label$id"}) ||
-     $latex_labels{"userdefined$label$id"} ||
-     $symbolic_labels{"$label$id"} ||
-     $latex_labels{$label} ||
-     $external_latex_labels{$label} ||
-     $cross_ref_visible_mark );
-}
-
-sub replace_bbl_marks {
-    # Modifies $_
-    s/$bbl_mark#([^#]+)#/$citations{$1}/go;
-}
-
-sub remove_bbl_marks {
-    # Modifies $_
-    s/$bbl_mark#([^#]+)#//go;
-}
-
-sub replace_image_marks {
-    # Modifies $_
-    s/$image_mark#([^#]+)#([\.,;:\)\]])?(\001)?([ \t]*\n?)(\001)?/
-       "$id_map{$1}$2$4"/ego;
-#      "$id_map{$1}$2".(($4)?"\n":'')/ego;
-}
-
-sub remove_image_marks {
-    # Modifies $_
-    s/$image_mark#([^#]+)#//go;
-}
-
-sub replace_icon_marks {
-    # Modifies $_
-    if ($HTML_VERSION < 2.2 ) {
-       local($icon);
-       s/$icon_mark_rx/$icon = &img_tag($1);
-           $icon =~ s| BORDER="?\d+"?||;$icon/ego;
-    } else {
-       s/$icon_mark_rx/&img_tag($1)/ego;
-    }
-}
-
-sub remove_icon_marks {
-    # Modifies $_
-    s/$icon_mark_rx//go;
-}
-
-sub replace_cite_marks {
-    local($key,$label,$text,$file);
-    # Modifies $_
-    # Uses $citefile set by the thebibliography environment
-    local($citefile) = $citefile;
-    $citefile =~ s/\#.*$//;
-    
-    s/#([^#]+)#$cite_mark#([^#]+)#((($OP\d+$CP)|[^#])*)#$cite_mark#/
-       $text = $3; $label= $1; $file='';
-       $text = $cite_info{$1} unless $text;
-       if ($checking_caption){
-           "$label"
-       } elsif ($citefiles{$2}){
-           $file = $citefiles{$2}; $file =~ s:\#.*$::;
-           &make_named_href('', "$file#$label","$text");
-       } elsif ($PREAMBLE) {
-           $text || "\#!$1!\#" ;
-       } elsif ($simplifying) {
-           $text
-       } else {
-            &write_warnings("\nno reference for citation: $1");
-            "\#!$1!\#"
-       }/sge ;
-    #
-    #RRM: Associate the cite_key with  $citefile , for use by other segments.
-    if ($citefile) {
-       local($cite_key, $cite_ref);
-       while (($cite_key, $cite_ref) = each %cite_info) {
-           if ($ref_files{'cite_'."$cite_key"} ne $citefile) {
-               $ref_files{'cite_'."$cite_key"} = $citefile;
-               $changed = 1; }
-       }
-    }
-}
-
-sub remove_cite_marks {
-    # Modifies $_
-    s/#([^#]+)#$cite_mark#([^#]+)#([^#]*)#$cite_mark#//go;
-}
-
-sub remove_anchors {
-# modifies $_
-    s/<A[^>]*>//g;
-    s/<\/A>//g;
-}
-
-
-# We need two matching keys to determine section/figure/etc. numbers.
-# The "keys" are the name of the section/figure/etc. and its
-# equivalent in the .aux file (also carrying the number we desire).
-# But both keys might have been translated slightly different,
-# depending on the usage of math, labels, special characters such
-# as umlauts, or simply spacing!
-#
-# This routine tries to squeeze the HTML translated keys such
-# that they match (hopefully very often). -- JCL
-#
-sub sanitize {
-    local($_,$mode) = @_;
-    &remove_markers;
-    &remove_anchors;
-    &text_cleanup;
-    s/(\&|;SPM)nbsp;//g;            # HWS - LaTeX changes ~ in its .aux files
-    #strip unwanted HTML constructs
-    s/<\/?(P|BR|H)[^>]*>//g;
-    s/\s+//g; #collapse white space
-    $_;
-}
-
-# This one removes any HTML markup, so that pure
-# plain text remains. (perhaps with <SUP>/<SUB> tags)
-# As the result will be part of the HTML file, it will be
-# &text_cleanup'd later together with its context.
-#
-sub purify {
-    local($_,$strict) = @_;
-    &remove_markers;
-    #strip unwanted HTML constructs
-#    s/<[^>]*>/ /g;
-    s/<(\/?SU[BP])>/>$1>/g unless ($strict);  # keep sup/subscripts ...
-    s/<[^>]*>//g;                             # remove all other tags
-    s/>(\/?SU[BP])>/<$1>/g unless ($strict);  # ...reinsert them
-    s/^\s+|\001//g; s/\s\s+/ /g;              #collapse white space
-    $_;
-}
-
-# This one is not as strict as &sanitize.
-# It is chosen to strip section names etc. a bit from
-# constructs so that it better fits a table of contents,
-# label files, etc.
-# As the result will be part of the HTML file, it will be
-# &text_cleanup'd later together with its context.
-#
-sub simplify {
-    local($_) = @_;
-    local($simplifying) = 1;
-    s/$tex2html_envs_rx//g;
-    if (/\\/) {
-       local($USING_STYLES) = 0;
-       $_ = &translate_commands($_);
-       undef $USING_STYLES;
-    }
-    &replace_external_ref_marks if /$external_ref_mark/;
-    &replace_cross_ref_marks if /$cross_ref_mark||$cross_ref_visible_mark/;
-    &replace_cite_marks if /$cite_mark/;
-    # strip unwanted HTML constructs
-#    s/<\/?H[^>]*>/ /g;
-    s/<\/?(H)[^>]*>//g;
-    s/<\#\d+\#>//g;
-    s/^\s+//;
-    $_;
-}
-
-#RRM: This extracts $anchor_mark portions from a given chunk of text,
-#     so they can be positioned separately by the calling subroutine.
-# added for v97.2: 
-#  search within the immediately following text also; so that 
-#  \index and \label after section-headings work as expected.
-#
-sub extract_anchors {
-    local($search_text, $start_only) = @_; 
-    local($anchors) = '';
-    local($untranslated_anchors) = '';
-
-    do {
-       while ($search_text =~ s/<A[^>]*>($anchor_mark|$anchor_invisible_mark)<\/A>//) {
-           $anchors .= $&;
-       }
-    } unless ($start_only);
-    
-    $search_text =~ s/\s*(\\protect)?\\(label|index|markright|markboth\s*(($O|$OP)\d+($C|$CP))[^<]*\3)\s*(($O|$OP)\d+($C|$CP))[^<]*\6/
-       $anchors .= $&;''/eg unless ($start_only);
-
-    while ( s/^\s*<A[^>]*>($anchor_mark|$anchor_invisible_mark)<\/A>//m) {
-       $untranslated_anchors .= $&;
-    }
-    while ( s/^\s*(\\protect)?\\(label|index|markright|markboth\s*(($O|$OP)\d+($C|$CP))[^<]*\3)\s*(($O|$OP)\d+($C|$CP))[^<]*\6//) {
-       $untranslated_anchors .= $&;
-    }
-    if ($TITLE||$start_only) {
-       $anchors .= &translate_commands($untranslated_anchors);
-       $untranslated_anchors = '';
-    }
-    ($anchors.$untranslated_anchors,$search_text); 
-}
-
-# This routine must be called once on the text only,
-# else it will "eat up" sensitive constructs.
-sub text_cleanup {
-    # MRO: replaced $* with /m
-    s/(\s*\n){3,}/\n\n/gom;    # Replace consecutive blank lines with one
-    s/<(\/?)P>\s*(\w)/<$1P>\n$2/gom;      # clean up paragraph starts and ends
-    s/$O\d+$C//go;             # Get rid of bracket id's
-    s/$OP\d+$CP//go;           # Get rid of processed bracket id's
-    s/(<!)?--?(>)?/(length($1) || length($2)) ? "$1--$2" : "-"/ge;
-    # Spacing commands
-    s/\\( |$)/ /go;
-    #JKR: There should be no more comments in the source now.
-    #s/([^\\]?)%/$1/go;        # Remove the comment character
-    # Cannot treat \, as a command because , is a delimiter ...
-    s/\\,/ /go;
-    # Replace tilde's with non-breaking spaces
-    s/ *~/&nbsp;/g;
-
-    ### DANGEROUS ?? ###
-    # remove redundant (not <P></P>) empty tags, incl. with attributes
-    s/\n?<([^PD >][^>]*)>\s*<\/\1>//g;
-    s/\n?<([^PD >][^>]*)>\s*<\/\1>//g;
-    # remove redundant empty tags (not </P><P> or <TD> or <TH>)
-    s/<\/(TT|[^PTH][A-Z]+)><\1>//g;
-    s/<([^PD ]+)(\s[^>]*)?>\n*<\/\1>//g;
-
-    
-#JCL(jcl-hex)
-# Replace ^^ special chars (according to p.47 of the TeX book)
-# Useful when coming from the .aux file (german umlauts, etc.)
-    s/\^\^([^0-9a-f])/chr((64+ord($1))&127)/ge;
-    s/\^\^([0-9a-f][0-9a-f])/chr(hex($1))/ge;
-}
-
-# This is useful for getting words from a title which are not cluttered
-# with tex2html markers or HTML constructs
-sub extract_pure_text {
-    local($mode) = @_;
-    &text_cleanup;             # Remove marking brackets
-#
-# HWS <hswan@perc.Arco.com>:  Conditionally doing the following
-#     permits equations in section headings.
-#
-    if ($mode eq "strict") {
-       s/$image_mark#[^#]*#//g;        # Remove image marker
-       s/$bbl_mark#[^#]*#//g;          # Remove citations marker
-        s/<tex2html_percent_mark>/%/g;  # BMcM: Retain % signs...
-        s/<tex2html_ampersand_mark>/\&amp;/g;
-       s/tex2html[\w\d]*//g;   # Remove other markers
-       }
-
-#
-# HWS <hswan@perc.Arco.com>:  Replace next statement with the following two
-#    to permit symbolic links and images to appear in section headings.
-
-#   s/<[^>]*>//go;                     # Remove HTML constructs
-    s/$OP[^#]*$CP//go;                 # Remove <# * #> constructs
-    s/<\s*>//go;                       # Remove embedded whitespace
-}
-
-############################ Misc ####################################
-
-# MRO: Print standardized header
-sub banner {
-    print <<"EOF";
-This is LaTeX2HTML Version $TEX2HTMLVERSION
-by Nikos Drakos, Computer Based Learning Unit, University of Leeds.
-
-EOF
-}
-
-# MRO: Extract usage information from POD
-sub usage {
-    my $start  = 0;
-    my $usage  = 'Usage: ';
-    my $indent = '';
-
-    print (@_, "\n") if @_;
-
-    my $perldoc = "/usr/bin${dd}perldoc";
-    my $script = $SCRIPT || $0;
-    open(PIPE, "$perldoc -t $script |")
-        || die "Fatal: can't open pipe: $!";
-    while (<PIPE>) {
-        if (/^\s*$/) {
-            next;
-        } elsif (/^SYNOPSIS/) {
-            $start = 1;
-        } elsif (/^\w/) {
-            $start = 0;
-        } elsif ($start == 1) {
-            ($indent) = /^(\s*)/;
-            s/^$indent/$usage/;
-            $usage =~ s/./ /g;
-            $start = 2;
-            print $_;
-        } elsif ($start == 2) {
-            s/^$indent/$usage/;
-            print $_;
-        }
-    }
-    close PIPE;
-    1;
-}
-
-# The bibliographic references, the appendices, the lists of figures and tables
-# etc. must appear in the contents table at the same level as the outermost
-# sectioning command. This subroutine finds what is the outermost level and
-# sets the above to the same level;
-sub set_depth_levels {
-    # Sets $outermost_level
-    local($level);
-    # scan the document body, not the preamble, for use of sectioning commands
-    my ($contents) = $_;
-    if ($contents =~ /\\begin\s*((?:$O|$OP)\d+(?:$C|$CP))document\1|\\startdocument/s) {
-       $contents = $';
-    }
-    #RRM:  do not alter user-set value for  $MAX_SPLIT_DEPTH
-    foreach $level ("part", "chapter", "section", "subsection",
-                   "subsubsection", "paragraph") {
-       last if (($outermost_level) = $contents =~ /\\($level)$delimiter_rx/);
-       last if (($outermost_level) = $contents =~ /\\endsegment\s*\[\s*($level)\s*\]/s);
-       if ($contents =~ /\\segment\s*($O\d+$C)[^<]+\1\s*($O\d+$C)\s*($level)\s*\2/s)
-               { $outermost_level = $3; last };
-    }
-    $level = ($outermost_level ? $section_commands{$outermost_level} :
-             do {$outermost_level = 'section'; 3;});
-
-    #RRM:  but calculate value for $MAX_SPLIT_DEPTH when a $REL_DEPTH was given
-    if ($REL_DEPTH && $MAX_SPLIT_DEPTH) { 
-       $MAX_SPLIT_DEPTH = $level + $MAX_SPLIT_DEPTH;
-    } elsif (!($MAX_SPLIT_DEPTH)) { $MAX_SPLIT_DEPTH = 1 };
-
-    %unnumbered_section_commands = (
-          'tableofcontents', $level
-       , 'listoffigures', $level
-       , 'listoftables', $level
-       , 'bibliography', $level
-       , 'textohtmlindex', $level
-        , %unnumbered_section_commands
-        );
-
-    %section_commands = ( 
-         %unnumbered_section_commands
-        , %section_commands
-        );
-}
-
-# Now ignores accents which cannot be translated to ISO-LATIN-1 characters
-# Also replaces ?' and !' ....
-sub replace_strange_accents { 
-    &real_replace_strange_accents(@_); # if ($CHARSET =~ /8859[_\-]1$/);
-}
-sub real_replace_strange_accents {
-    # Modifies $_;
-    s/\?`/&iso_map("iquest", "")/geo;
-    s/!`/&iso_map("iexcl", "")/geo;
-    s/\\\^\\i /&iso_map("icirc", "")/geo;
-    my ($charset) = "${CHARSET}_character_map_inv";
-    $charset =~ s/-/_/g;
-    # convert upper 8-bit characters
-    if (defined %$charset &&($CHARSET =~ /8859[_\-]1$/)) {
-       s/([\200-\377])/
-           $tmp = $$charset{'&#'.ord($1).';'};
-           &mark_string($tmp) if ($tmp =~ m!\{!);
-           &translate_commands($tmp)
-       /egos
-    }
-};
-
-# Creates a new directory or reuses old, perhaps after deleting its contents
-sub new_dir {
-    local($this_dir,$mode) = @_;
-    local(@files)=();
-    $this_dir = '.' unless $this_dir;
-    $this_dir =~ s/[$dd$dd]+$//o;
-    local($print_dir) = $this_dir.$dd;
-    (!$mode && mkdir($this_dir, 0755)) ||
-       do {
-           print "\nCannot create directory $print_dir: $!" unless ($mode);
-           if ($REUSE) {
-               print ", reusing it.\n" unless ($mode);
-               &reuse($this_dir,$print_dir);
-           } else {
-               print "\n" unless ($mode);
-               while (! ($answer =~ /^[dqr]$/)) {
-                   if ($mode) {
-                       $answer = $mode;
-                   } else { 
-                       print "(r) Reuse the images in the old directory OR\n"
-                           . (($this_dir eq '.') ?
-               "(d) *** DELETE *** the images in $print_dir  OR\n"
-               : "(d) *** DELETE *** THE CONTENTS OF $print_dir  OR\n" )
-                           . "(q) Quit ?\n:";
-                       $answer = scalar(<STDIN>);
-                   };
-                   if ($answer =~ /^d$/) {
-                        @files = ();
-                       if(opendir(DIR,$this_dir)) {
-                           @files = readdir DIR;
-                           closedir DIR;
-                        } else {
-                            print "\nError: Cannot read dir '$this_dir': $!\n";
-                        }
-                       foreach (@files) {
-                           next if /^\.+$/;
-                           if (-d "$this_dir$dd$_") {
-                               &new_dir("$this_dir$dd$_",'d');
-                           } elsif ($this_dir eq '.') {
-                               L2hos->Unlink($_) if (/\.(pl|gif|png)$/) 
-                           } else {
-                               L2hos->Unlink("$this_dir$dd$_"); 
-                           };
-                       }
-                       return(1) if ($this_dir eq '.');
-                       if($mode) {
-                         rmdir($this_dir);
-                         rmdir($print_dir);
-                        }
-                       if (!$mode) { &new_dir($this_dir,'r')};
-                       return(1);
-                   } elsif ($answer =~ /^q$/) {
-                       die "Bye!\n";
-                   } elsif ($answer =~ /^r$/) {
-                       &reuse($this_dir,$print_dir);
-                       return(1);
-                   } else {print "Please answer r d or q!\n";};
-               }
-           };
-       };
-    1;
-}
-
-sub reuse {
-    local($this_dir,$print_dir) = @_;
-    $print_dir = $this_dir.$dd unless ($print_dir);
-    if (-f "$this_dir$dd${PREFIX}images.pl") {
-       print STDOUT "Reusing directory $print_dir:\n";
-       local($key);
-       require("$this_dir$dd${PREFIX}images.pl");
-    }
-}
-
-
-# JCL(jcl-del) - use $CD rather than a space as delimiter.
-# The commands might take white space, or not, depending on
-# their definition. Eg. \relax takes white space, because it's a
-# letter command, but \/ won't.
-# TeX seems to have an internal separator: If \x is " x",
-# and \y is "y", then \expandafter\y \x expands to "y x", TeX
-# hasn't gobbled the space, meaning that spaces are gobbled once
-# when the \y token is consumed, but then never again after \y.
-#
-# The actions below ensure to insert exactly one space after
-# the command name.    # what happens to  `\ '  ?
-# The substition is done twice to handle \one\delimits\another
-# cases.
-# The internal shortcut $CD is then turned into the single
-# space we desire.
-#
-sub tokenize {
-    # Modifies $_;
-    local($rx) = @_;
-    # $rx must be specially constructed, see &make_new_cmd_rx.
-    if (length($rx)) {
-       # $1: non-letter cmd, or $2: letter cmd
-       s/$rx/\\$1$2$CD$4/g;
-       s/$rx/\\$1$2$CD$4/g;
-       s/$CD+/ /g;     # puts space after each command name
-    }
-}
-
-# When part of the input text contains special perl characters and the text
-# is to be used as a pattern then these specials must be escaped.
-sub escape_rx_chars {
-    my($rx) = @_; # must use a copy of the string
-    $rx =~ s:([\\(){}[\]\^\$*+?.|]):\\$1:g; $rx; }
-
-# Does not do much but may need it later ...
-# The document environment has to be removed because it spans
-# more than one sections (the translator can only deal with
-# environments wholly contained with sections).
-
-# (Does a little more now ... the end of the preamble is now marked
-# with an internally-generated command which causes all output
-# erroneously generated from unrecognized commands in the preamble
-# to vanish --- rst).
-
-sub remove_document_env {
-#    s/\\begin$match_br_rx[d]ocument$match_br_rx/\\latextohtmlditchpreceding /o;
-    if (/\\begin\s*${match_br_rx}document$match_br_rx/) { 
-        s/\\begin\s*$match_br_rx[d]ocument$match_br_rx/\\latextohtmlditchpreceding /
-    }
-#   s/\\end$match_br_rx[d]ocument$match_br_rx(.|\n)*//o;
-    if (/\\end\s*${match_br_rx}document$match_br_rx/) { $_ = $` }
-}
-
-# And here's the code to handle the marker ...
-
-sub do_cmd_latextohtmlditchpreceding {
-    local($_) = @_;
-    $ref_before = '';
-    $_;
-}
-
-print "\n"; # flushes a cache? This helps, for some unknown reason!!
-
-sub do_AtBeginDocument{
-    local($_) = @_;
-    eval $AtBeginDocument_hook;
-    $_;
-}
-
-sub cleanup {
-    local($explicit) = @_;
-    return unless $explicit || !$DEBUG;
-
-    if (opendir(DIR, '.')) {
-       while (defined($_ = readdir(DIR))) {
-           L2hos->Unlink($_)
-               if /\.ppm$/ || /^${PREFIX}images\.dvi$/ || /^(TMP[-._]|$$\_(image)?)/;
-       }
-       closedir (DIR);
-    }
-
-    L2hos->Unlink("WARNINGS") if ($explicit &&(-f "WARNINGS"));
-
-    if ($TMPDIR && opendir(DIR, $TMPDIR)) {
-       local(@files) = grep(!/^\.\.?$/,readdir(DIR));
-       local($busy);
-       foreach (@files) {
-           $busy .= $_." " unless (L2hos->Unlink("$TMPDIR$dd$_"));
-       }
-       closedir (DIR);
-       if ($busy) {
-           print "\n\nFiles: $busy  are still in use.\n\n" if ($DEBUG);
-       } else {
-           &write_warnings("\n\n Couldn't remove $TMPDIR : $!")
-               unless (rmdir $TMPDIR);
-       }
-    }
-    if (opendir(DIR, $TMP_)) {
-       local(@files) = grep(!/^\.\.?$/,readdir(DIR));
-       $busy = '';
-       foreach (@files) {
-           $busy .= "$_ " unless (L2hos->Unlink("$TMP_$dd$_"));
-       }
-       closedir (DIR);
-       local($full_dir) = L2hos->Make_directory_absolute($TMP_);
-       if ($busy) {
-           print "\n\nFiles: $busy in $full_dir are still in use.\n\n"
-               if ($DEBUG);
-       } else {
-           &write_warnings("\n\nCouldn't remove directory '$full_dir': $!")
-               unless (rmdir $full_dir);
-       }
-    }
-}
-
-sub handler {
-    print "\nLaTeX2HTML shutting down.\n";
-    kill ('INT', $child_pid) if ($child_pid);
-    &close_dbm_database;
-    &cleanup();
-    exit(-1);
-}
-
-# Given a filename or a directory it returns the file and the full pathname
-# relative to the current directory.
-sub get_full_path {
-    local($file) = @_;
-    local($path,$dir);
-    if (-d $file) {    # $file is a directory
-       $path = L2hos->Make_directory_absolute($file);
-       $file = '';
-
-# JCL(jcl-dir)
-    } elsif ($file =~ s|\Q$dd\E([^$dd$dd]*)$||o ) {
-       $path = $file;
-       $file = $1;
-       $path = L2hos->Make_directory_absolute($path);
-
-#RRM: check within $TEXINPUTS directories
-    } elsif (!($TEXINPUTS =~ /^\.$envkey$/)) {
-       #check along directories in the $TEXINPUTS variable
-       foreach $dir (split(/$envkey/,$TEXINPUTS)) {
-           $dir =~ s/[$dd$dd]$//o;
-           if (-f $dir.$dd.$file) {
-               $path = L2hos->Make_directory_absolute($dir);
-               last;
-           }
-       }
-    } else {
-       $path = L2hos->Cwd();
-    }
-    ($path, $file);
-}
-
-
-# Given a directory name in either relative or absolute form, returns
-# the absolute form.
-# Note: The argument *must* be a directory name.
-# The whole function has been moved to override.pm
-
-
-
-# Given a relative filename from the directory in which the original
-# latex document lives, it tries to expand it to the full pathname.
-sub fulltexpath {
-    # Uses $texfilepath defined in sub driver
-    local($file) = @_;
-    $file =~ s/\s//g;
-    $file = "$texfilepath$dd$file"
-      unless (L2hos->is_absolute_path($file));
-    $file;
-}
-
-#RRM  Extended to allow customised filenames, set $CUSTOM_TITLES
-#     or long title from the section-name, set $LONG_TITLES
-#
-sub make_name {
-    local($sec_name, $packed_curr_sec_id) = @_;
-    local($title,$making_name,$saved) = ('',1,'');
-    if ($LONG_TITLES) {
-       $saved = $_;
-       &process_command($sections_rx, $_) if /^$sections_rx/;
-       $title = &make_long_title($TITLE)
-           unless ((! $TITLE) || ($TITLE eq $default_title));
-       $_ = $saved;
-    } elsif ($CUSTOM_TITLES) {
-       $saved = $_;
-       &process_command($sections_rx, $_) if /^$sections_rx/;
-       $title = &custom_title_hook($TITLE)
-           unless ((! $TITLE) || ($TITLE eq $default_title));
-       $_ = $saved;
-    }
-    if ($title) {
-       #ensure no more than 32 characters, including .html extension
-       $title =~ s/^(.{1,27}).*$/$1/;
-       ++$OUT_NODE;
-       join("", ${PREFIX}, $title, $EXTN);
-    } else {
-    # Remove 0's from the end of $packed_curr_sec_id
-       $packed_curr_sec_id =~ s/(_0)*$//;
-       $packed_curr_sec_id =~ s/^\d+$//o; # Top level file
-       join("",($packed_curr_sec_id ? 
-           "${PREFIX}$NODE_NAME". ++$OUT_NODE : $sec_name), $EXTN);
-    }
-}
-
-#RRM: redefine this subroutine, to create customised file-names
-#     based upon the actual section title.
-#     The default is empty, so reverts to:  node1, node2, ...
-#
-sub custom_title_hook {
-    local($_)= @_;
-    "";
-}
-
-
-sub make_long_title {
-    local($_)= @_;
-    local($num_words) = $LONG_TITLES;
-    #RRM:  scan twice for short words, due to the $4 overlap
-    #      Cannot use \b , else words break at accented letters
-    $_ =~ s/(^|\s)\s*($GENERIC_WORDS)(\'|(\s))/$4/ig;
-    $_ =~ s/(^|\s)\s*($GENERIC_WORDS)(\'|(\s))/$4/ig;
-    #remove leading numbering, unless that's all there is.
-    local($sec_num);
-    if (!(/^\d+(\.\d*)*\s*$/)&&(s/^\s*(\d+(\.\d*)*)\s*/$sec_num=$1;''/e))
-       { $num_words-- };
-    &remove_markers; s/<[^>]*>//g; #remove tags
-    #revert entities, etc. to TeX-form...
-    s/([\200-\377])/"\&#".ord($1).";"/eg;
-    $_ = &revert_to_raw_tex($_);
-
-    # get $LONG_TITLES number of words from what remains
-    $_ = &get_first_words($_, $num_words) if ($num_words);
-    # ...and cleanup accents, spaces and punctuation
-    $_ = join('', ($SHOW_SECTION_NUMBERS ? $sec_num : ''), $_);
-    s/\\\W\{?|\}//g; s/\s/_/g; s/\W/_/g; s/__+/_/g; s/_+$//;
-    $_;
-}
-
-
-sub make_first_key {
-    local($_);
-    $_ = ('0 ' x keys %section_commands);
-    s/^0/$THIS_FILE/ if ($MULTIPLE_FILES);  
-    chop;
-    $_;
-}
-
-# This copies the preamble into the variable $preamble.
-# It also sets the LaTeX font size, if $FONT_SIZE is set.
-sub add_preamble_head {
-    $preamble = join("\n", $preamble, @preamble);
-    $preamble = &revert_to_raw_tex($preamble);
-    $preamble = join ("\n", &revert_to_raw_tex(/$preamble_rx/o),
-                               $preamble);
-    local($savedRS) = $/; undef $/;
-    # MRO: replaced $* with /m
-    $preamble =~ /(\\document(style|class))\s*(\[[^]]*\])?\s*\{/sm;
-    local($before,$after) = ($`.$1, '{'.$');
-    $/ = $savedRS;
-    local ($options) = $3;
-    if ($FONT_SIZE) {
-       $options =~ s/(1\dpt)\b//;
-       $options =~ s/(\[|\])//g;
-       $options = "[$FONT_SIZE".($options ? ",$options" : '').']';
-       $preamble = join('', $before, $options, $after );
-       &write_mydb_simple("preamble", $preamble);
-       @preamble = split(/\n/, $preamble);
-       $LATEX_FONT_SIZE = $FONT_SIZE;
-    }
-    if (($options =~ /(1\dpt)\b/)&&(!$LATEX_FONT_SIZE)) {
-       $LATEX_FONT_SIZE = $1;
-    }
-    #RRM: need to know the font-size before the .aux file is read
-    $LATEX_FONT_SIZE = '10pt' unless ($LATEX_FONT_SIZE);
-}
-
-# It is necessary to filter some parts of the document back to raw
-# tex before passing them to latex for processing.
-sub revert_to_raw_tex {
-    local($_) = @_;
-    local($character_map) = "";
-    if ( $CHARSET && $HTML_VERSION ge "2.1" ) {
-       $character_map = $CHARSET;
-       $character_map =~ tr/-/_/; }
-    while (s/$O\s*\d+\s*$C/\{/o) { s/$&/\}/;}
-    while (s/$O\s*\d+\s*$C/\{/o) { s/$&/\}/;} #repeat this.
-    # The same for processed markers ...
-    while ( s/$OP\s*\d+\s*$CP/\{/o ) { s/$&/\}/; }
-    while ( s/$OP\s*\d+\s*$CP/\{/o ) { s/$&/\}/;} #repeat this.
-
-    s/<BR>/\\\\/g; # restores the \\ from \parbox's
-
-    # revert any math-entities
-    s/\&\w+#(\w+);/\\$1/g;
-    s/\&limits;/\\limits/g;
-    s/\\underscore/\\_/g;
-    s/\\circflex/\\^/g;
-    s/\\space/\\ /g;
-    s/;SPMthinsp;/\\,/g;
-    s/;SPMnegsp;/\\!/g;
-    s/;SPMsp;/\\:/g;
-    s/;SPMthicksp;/\\;/g;
-    s/;SPMgg;/\\gg /g;
-    s/;SPMll;/\\ll /g;
-    s/;SPMquot;/"/g;
-
-    # revert any super/sub-scripts
-    s/<SUP>/\^\{/g;
-    s/<SUB>/\_\{/g;
-    s/<\/SU(B|P)>/\}/g;
-
-
-#    #revert common character entities  ??
-#    s/&#92;/\\/g;
-
-#    # revert special marks
-#    s/$percent_mark/\\%/go;
-##    s/$comment_mark(\d+)\n/%$comments{$1}\n/go;
-    local($tmp,$tmp2);
-#    s/$comment_mark(\d+)\n/$tmp=$verbatim{$1};chomp($tmp);$tmp."\n"/ego;
-    s/$comment_mark(\d+)(\n|$|(\$))/$tmp=$verbatim{$1};$tmp2 = $3;
-        ($tmp=~m!^\%!s ? '':'%').$tmp.(($tmp=~ m!\n\s*$!s)?'':"\n").$tmp2/sego;
-    s/${verbatim_mark}tex2html_code(\d+)\#/$verbatim{$1}/go;
-    s/^($file_mark|$endfile_mark).*\#\n//gmo;
-    s/$comment_mark(\d*)\s*\n/%\n/go;
-    s/$dol_mark/\$/go;
-    s/$caption_mark//go;
-
-    # From &pre_process.
-    # MRO: replaced $* with /m
-    s/\\\\[ \t]*(\n)?/\\\\$1/gm;
-
-    # revert any array-cell delimiters
-    s/$array_col_mark/\&/g;
-    s/$array_row_mark/\\\\/g;
-    s/$array_text_mark/\\text/g;
-    s/$array_mbox_mark/\\mbox/g;
-
-    # Replace any verbatim and image markers ...
-    &revert_verbatim_marks;
-    &revert_verb_marks;
-
-
-#    &replace_image_marks;
-    s/$image_mark\#([^\#]+)\#/&recover_image_code($1)/eg;
-
-    # remove artificial environments and commands
-
-    s/(\n*)\\(begin|end)(($O|$OP)\d+($C|$CP))tex2html_b(egin)?group\3\n?/
-       ($1? "\n":'')."\\".($6? $2:(($2 =~ m|end|)? 'e':'b'))."group\n"
-    /gem;
-    s/\\(begin|end)(\{|(($O|$OP)\d+($C|$CP|\})))(tex2html|verbatim)_code(\}|\3)\n?//gm;
-
-    #take care not to concatenate \<cmd> with following letters
-    local($tmp);
-    s/(\\\w+)?$tex2html_wrap_rx([^\\\n])?/$tmp=$2;
-        ((($tmp eq 'end')&&($1)&&!($5)&&($6))? "$1 $6":"$1$5$6")/egs;
-    undef $tmp;
-    s/\s*\\newedcommand\s*{/"%\n\\providecommand{\\"/gem;
-    s/\\newedcommand\s*{/\\providecommand{\\/gom;
-#    s/(\n*)\\renewedcommand{/($1? "\n":'')."\\renewcommand{\\"/geo;
-    s/\s*\\providedcommand\s*{/"%\n\\providecommand{\\"/gem;
-#    s/\\providedcommand{/\\providecommand{\\/go;
-    s/\\renewedenvironment\s*/\\renewenvironment/gom;
-    s/\\newedboolean\s*{/\\newboolean{/gom;
-    s/\\newedcounter\s*{/\\newcounter{/gom;
-    s/\\newedtheorem\s*{/\\newtheorem{/gom;
-    s/\\xystar/\\xy\*/gom; # the * has a special meaning in Xy-pic
-
-    #fix-up the star'd environment names
-    s/(\\(begin|end)(($O|$OP)\d+($C|$CP))[^<]*)star\3/$1\*$3/gm;
-    s/(\\(begin|end)\{[^\}]*)star\}/$1\*\}/gm;
-    s/\\(begin|end)\{[^\}]*begin(group)\}/\\$1$2/gm;
-    s/\\(b|e)(egin|end)\{[^\}]*b(group)\}/\\$1$3/gm;
-
-    s/(\\(\w+)TeX)/($language_translations{$2}? "\\selectlanguage{$2}": $1)/egom;
-
-    if ($PREPROCESS_IMAGES) {
-      while (/$pre_processor_env_rx/m) {
-       $done .= $`; $pre_env = $5; $which =$1; $_ = $';
-        if (($which =~ /begin/)&&($pre_env =~ /indica/)) {
-           ($indic, $dum) = &get_next_optional_argument;
-           $done .= "\#$indic";
-        } elsif (($which =~ /begin/)&&($pre_env =~ /itrans/)) {
-           ($indic, $dum) = &get_next_optional_argument;
-           $done .= "\#$indic";
-        } elsif (($which =~ /end/)&&($pre_env =~ /indica/)) {
-           $done .= '\#NIL';
-        } elsif (($which =~ /end/)&&($pre_env =~ /itrans/)) {
-           $done .= "\#end$indic";
-       } elsif ($which =~ /begin/) {
-           $done .= (($which =~ /end/)? $end_preprocessor{$pre_env}
-                         : $begin_preprocessor{$pre_env} )
-       }
-       $_ = $done . $_;
-      }
-    }
-    s/\\ITRANSinfo\{(\w+)\}\{([^}]*)\}/\#$1=$2/gm if $itrans_loaded;
-
-    s/\n{3,}/\n\n/gm; # remove multiple (3+) new-lines 
-    s/^\n+$//gs; # ...especially if that is all there is!
-    if ($PREAMBLE) {
-       s/$comment_mark(\d+\n?)?//g;
-#      $preamble =~ s/\\par\n?/\n/g;
-       s/\\par\b/\n/g;
-       s/^\s*$//g; #remove blank lines in the preamble
-    };
-
-    s/($html_specials_inv_rx)/$html_specials_inv{$1}/geo;
-    # revert entities to TeX code, except if in {rawhtml} environments
-    if (!($env =~ /rawhtml/)) {
-        s/$character_entity_rx/( $character_map ?
-         eval "\$${character_map}_character_map_inv\{\"$1\"\}" :
-           $iso_8859_1_character_map_inv{$1} ||
-             $iso_10646_character_map_inv{$1})/geo;
-        s/$named_entity_rx/( $character_map ? 
-         eval "\$${character_map}_character_map_inv\{\$${character_map}_character_map{'$1'}}" :
-           $iso_8859_1_character_map_inv{$iso_8859_1_character_map{$1}} ||
-             $iso_10646_character_map_inv{$iso_10646_character_map{$1}})/geo;
-
-    } else {
-        #RRM: check for invalid named entities in {rawhtml} environments
-       s/($named_entity_rx)/&write_warnings(
-           "An unknown named entity ($1) appears in the source text.") unless (
-                $character_map && eval 
-         "\$${character_map}_character_map_inv\{\$${character_map}_character_map{'$2'}}");
-                    ";SPM$2;"/ego;
-    }
-
-    #RRM: check for numbered character entity out-of-range
-    if ($HTML_VERSION < 4.0) {
-       s/$character_entity_rx/&write_warnings(
-           "An invalid character entity ($1) appears in the source text.")
-            if ($2 > 255);
-       $1/ego; }
-
-    #RRM: check for invalid named entities outside {rawhtml} environments
-    # --- these should have been caught already, but check again
-    s/$named_entity_rx/&write_warnings(
-           "An unknown named entity ($1) appears in the source text.") unless (
-       $character_map && eval 
-         "\$${character_map}_character_map_inv\{\$${character_map}_character_map{'$1'}}");
-                    $1/ego;
-
-    &revert_to_raw_tex_hook if (defined &revert_to_raw_tex_hook);
-    $_;
-}
-
-sub next_wrapper {
-    local($dollar) = @_;
-    local($_,$id);
-    $wrap_toggle = (($wrap_toggle eq 'end') ? 'begin' : 'end');
-    $id = ++$global{'max_id'};
-    $_ = "\\$wrap_toggle$O$id$C"."tex2html_wrap$O$id$C";
-    $_ = (($wrap_toggle eq 'end') ? $dollar.$_ : $_.$dollar);
-    $_;
-}
-
-sub make_wrapper {
-    &make_any_wrapper($_[0], '', "tex2html_wrap");
-}
-
-sub make_nowrapper {
-    &make_any_wrapper($_[0], 1, "tex2html_nowrap");
-}
-
-sub make_inline_wrapper {
-    &make_any_wrapper($_[0], '', "tex2html_wrap_inline");
-}
-
-sub make_deferred_wrapper {
-    &make_any_wrapper($_[0], 1, "tex2html_deferred");
-}
-
-sub make_nomath_wrapper {
-    &make_any_wrapper($_[0], '', "tex2html_nomath_inline");
-}
-
-sub make_any_wrapper {
-    local($toggle,$break,$kind) = @_;
-    local($max_id) = ++$global{'max_id'};
-    '\\'. (($toggle) ? 'begin' : 'end')
-       . "$O$max_id$C"."$kind$O$max_id$C"
-       . (($toggle || !$break) ? '' : '');
-}
-
-sub get_last_word {
-    # Returns the last word in multi-line strings
-    local($_) = @_;
-    local ($word,$lastbit,$which);
-#JCL(jcl-tcl)
-# also remove anchors and other awkward HTML markup
-#    &extract_pure_text("strict");
-##    $_ = &purify($_);  ## No. what if it is a verbatim string or image?
-#
-#    while (/\s(\S+)\s*$/g) { $word = $lastbit = $1;}
-
-    if (!$_ && (defined $keep)) {
-       # inside mathematics !
-       $_ = $keep . $pre ;
-    }
-    if (!$_ && $ref_before) { $_ = $ref_before; }
-    elsif (!$_) {
-       # get it from last thing before the current environment
-       $which = $#processedE;
-       $_ = $processedE[$which];
-    }
-
-    while (/((($O|$OP)\d+($C|$CP))[.\n]*\2|\s(\S+))\s*$/g)
-       { $word = $lastbit = $1 }
-    if (($lastbit =~ s/\$\s*$//)||(defined $keep)) {
-       local($br_idA) = ++$global{'max_id'};
-       local($br_idB) = ++$global{'max_id'};
-       $lastbit = join('', "\\begin $O$br_idA${C}tex2html_wrap_inline$O$br_idA$C\$"
-               , $lastbit, "\$\\end $O$br_idB${C}tex2html_wrap_inline$O$br_idB$C");
-       $lastbit = &translate_environments($lastbit);
-       $lastbit = &translate_commands($lastbit);
-       return ($lastbit);
-    }
-    if ($lastbit =~ s/($O|$OP)\d+($C|$CP)//g) { return ($lastbit); }
-    elsif ($lastbit eq '') { return ($_) }
-
-    local($pre_bit);
-    if ($lastbit =~/>([^>]*)$/) { 
-       $word = $1; $pre_bit = $`.'>';
-       if ($pre_bit =~ /($verb_mark|$verbstar_mark)$/) {
-           $word = $lastbit;
-       } elsif ($pre_bit =~ /<\w+_mark>$/) {
-           $word = $& . $word;
-       } elsif (!($word)) {
-           if ($lastbit =~ s/<([^\/][^>]*)>$//o)
-               { $word=$1; $pre_bit = $`; }
-           elsif ($lastbit =~ s/>([^<]*)<\/[^>]*>//o)
-               { $word=$1; $pre_bit = $`.'>' }
-           else { $word = ";SPMnbsp;"; }
-       }
-#      if ($pre_bit =~ /<\w+_mark>$/) { $word = $& . $word }
-     } else { $word = $lastbit };
-    $word;
-}
-
-#JCL(jcl-tcl)
-# changed completely
-#
-# We take the first real words specified by $min from the string.
-# Allow for simple HTML constructs like <I>...</I> (but not <H*>
-# or <P*> and the like), math, or images to remain in the result,
-# not counting as words.
-# Take care that eg. <I>...</I> grouping tags are not broken.
-# This is achieved by lifting the markup, removing superfluous
-# words, re-inserting the markup, and throw empty markup away.
-# In later versions images could be modified such that they become
-# thumbnail sized.
-#
-# rawhtml or verbatim environments might introduce lots of awkward
-# stuff, but yet we leave the according tex2html markers in.
-#
-sub get_first_words {
-    local($_, $min) = @_;
-    local($words,$i);
-    local($id,%markup);
-    #no limit if $min is negative
-    $min = 1000 if ($min < 0);
-
-    &remove_anchors;
-    #strip unwanted HTML constructs
-    s/<\/?(P|BR|H)[^>]*>/ /g;
-    #remove leading white space and \001 characters
-    s/^\s+|\001//g;
-    #lift html markup, numbered for recovery
-    s/(<[^>]*>(#[^#]*#)?)/$markup{++$id}=$1; "\000$id\000"/ge;
-
-    foreach (split /\s+|\-{3,}/) {
-        # count words (incl. HTML markup as part of the word)
-        ++$i; 
-#      $words .= $_ . " " if (/\000/ || ($i <= $min));
-       $words .= $_ . " " if ($i <= $min);
-    }
-    $_ = $words;
-    chop;
-
-    #re-insert markup
-    s/\000(\d+)\000/$markup{$1}/g;
-    # remove empty markup
-    # it's normalized, because generated by LaTeX2HTML only
-    s/<([A-Z]+)[^>]*>\s*<\/\1>\s*//g;
-    $_;
-}
-
-sub replace_word {
-    # Replaces the LAST occurrence of $old with $new in $str;
-    local($str, $old, $new) = @_;
-    substr($str,rindex($str,$old),length($old)) = $new;
-    $str;
-}
-
-# Returns the recognised sectioning commands as a string of alternatives
-# for use in regular expressions;
-sub get_current_sections {
-    local($_, $key);
-    foreach $key (keys %section_commands) {
-       if ($key =~ /star/) {
-           $_ = $key . "|" . $_}
-       else {
-           $_ .= "$key" . '[*]?|';
-       }
-    }
-    chop;                      # Remove the last "|".
-    $_;
-}
-
-sub numerically {
-    local(@x) = split(' ',$a);
-    local(@y) = split(' ',$b);
-    local($i, $result);
-    for($i=0;$i<$#x;$i++) {
-       last if ($result = ($x[$i] <=> $y[$i]));
-    }
-    $result
-}
-
-# Assumes that the files to be sorted are of the form
-# <NAME><NUMBER>
-sub file_sort {
-    local($i,$j) = ($a,$b);
-    $i =~ s/^[^\d]*(\d+)$/$1/;
-    $j =~ s/^[^\d]*(\d+)$/$1/;
-    $i <=> $j
-}
-
-# If a normalized command name exists, return it.
-sub normalize {
-    # MRO: modified to use $_[1]
-    # local($cmd,*after) = @_;
-    my $cmd =$_[0];
-    my $ncmd;
-    # Escaped special LaTeX characters
-    if ($cmd =~ /^($latex_specials_rx)/) {
-#      $cmd =~ s/&(.*)$/&amp;$1/o;
-       $cmd =~ s/&(.*)$/$ampersand_mark$1/o;
-        $cmd =~ s/%/$percent_mark/o;
-       $_[1] = join('', $cmd, $_[1]);
-       $cmd = ""}
-    elsif ($ncmd = $normalize{$cmd}) {
-       $ncmd;
-    }
-    else {
-       $cmd =~ s/[*]$/star/;
-       $cmd =~ s/\@/_at_/g;
-       $cmd;
-    }
-}
-
-sub normalize_sections {
-    my $dummy = '';
-    # MRO: s/$sections_rx/'\\' . &normalize($1.$2,*after) . $4/ge;
-    s/$sections_rx/'\\' . &normalize($1.$2,$dummy) . $4/ge;
-}
-
-sub embed_image {
-    my ($url,$name,$external,$altst,$thumbnail,$map,$align,
-       $usemap,$exscale,$exstr) = @_;
-    my $imgID = '';
-    my $urlimg = $url;
-    my $ismap = $map ? " ISMAP" : '';
-    print "\nembedding $url for $name, with $altst\n" if ($VERBOSITY > 1);
-
-    if (! ($NO_IMAGES || $PS_IMAGES)) {
-       # for over-scaled GIFs with pre-determined sizes        # RRM 11-9-96
-        my $size;
-       if (($width{$name})&&(($exscale)||($EXTRA_IMAGE_SCALE))) {
-           $exscale = $EXTRA_IMAGE_SCALE unless ($exscale);
-           if ($name =~ /inline|indisplay|entity|equation|math|eqn|makeimage/){
-               ($size, $imgID) = &get_image_size($url, $exscale);
-           } else {
-               ($size, $imgID) = &get_image_size($url,'');
-           }
-       } else {
-           ($size,$imgID) = &get_image_size($url,'');
-       }
-       $image_size{$url} = $size 
-           unless ((! $size) || ($size eq "WIDTH=\"0\" HEIGHT=\"0\""));
-       $url = &find_unique($url);
-    }
-
-    $urlimg = $url;
-    $urlimg =~ s/\.$IMAGE_TYPE$/.html/ if ($map);
-    if ($exstr =~ s/align\s*=\s*(\"?)(\w+)\1($|\s|,)//io) { $align = $2; }
-    my $usersize = '';
-    if ($exstr =~ s/width\s*=\s*(\"?)([^\s,]+)\1($|\s|,)//io) {
-       my ($pxs,$len) = &convert_length($2);
-       $usersize = " WIDTH=\"$pxs\"";
-    }
-    if ($exstr =~ s/height\s*=\s*(\"?)([^\s,]+)\1($|\s|,)//io) { 
-       my ($pxs,$len) = &convert_length($2);
-       $usersize .= " HEIGHT=\"$pxs\"";
-    }
-
-    my $border = '';
-    $border = "\" BORDER=\"0"
-       unless (($HTML_VERSION < 2.2 )||($exstr =~ /BORDER/i));
-
-    my $aalign;
-    if (($name =~ /figure|table|displaymath\d+|eqnarraystar/)&&(!$align)) {
-    } elsif ($name =~ /displaymath_/) {
-       $aalign = "MIDDLE".$border;
-    } elsif (($name =~ /(equation|eqnarray)($|\d)/)&&(!$align)) {
-       if ($HTML_VERSION >= 3.2) {
-           $aalign =  ($EQN_TAGS eq "L") ? "RIGHT" : "LEFT";
-       }
-    } elsif ($name =~ /inline|display|entity|xy|diagram/ && $depth{$name} != 0) {
-       $aalign = "MIDDLE".$border;
-    } elsif ($name =~ /inpar/m) {
-       $aalign = "TOP".$border;
-    } else {  $aalign = "BOTTOM".$border }
-
-    $aalign = "\U$align" if $align;
-    my $ausemp = $usemap ? "\UUSEMAP=$usemap" : '';
-
-    #append any extra valid options 
-    $ismap .= &parse_keyvalues ($exstr, ("IMG")) if ($exstr);
-
-    $altst = '' if ($ismap =~ /(^|\s+)ALT\s*=/);
-    if ($altst) {
-       if ($altst =~ /\s*ALT="?([^\"]+)"?\s*/io) { $altst=$1 }
-       $altst =~ s/[<>"&]/'&'.$html_special_entities{$&}.';'/eg;
-       $altst = "\n ALT=\"$altst\"";
-    }
-
-    my ($extern_image_mark,$imagesize);
-    if ($thumbnail) {
-       print "\nmaking thumbnail" if ($VERBOSITY > 1);
-       if (($image_size{$thumbnail}) = &get_image_size($thumbnail,'')) {
-           $thumbnail = &find_unique($thumbnail);
-           $imagesize = " ".$image_size{$thumbnail};
-           if ($HTML_VERSION < 2.2 ) {
-               # put the WIDTH/HEIGHT information into the ALT string
-               # first removing the quotes
-               my ($noquotes) = $imagesize;
-               $noquotes =~ s/\"//g;
-               $altst =~ s/"$/\% $noquotes "/m;
-               $imagesize = '';
-           }
-           $extern_image_mark = join('',"<IMG"
-               , "\n$imagesize" 
-               , (($aalign) ? " ALIGN=\"$aalign\"" : '')
-               , ("$aalign$imagesize" ? "\n" : '' )
-               , " SRC=\"$thumbnail\"$altst>");
-       }
-       $extern_image_mark =~ s/\s?BORDER="?\d+"?//
-            unless ($exstr =~ /BORDER/i);
-    } else { 
-        # MRO: dubious (&extern_image_mark takes only one arg)
-        $extern_image_mark = &extern_image_mark($IMAGE_TYPE,$altst);
-    }
-
-    my ($anch1,$anch2) = ('','');
-    my $result;
-    if ($external || $thumbnail || $EXTERNAL_IMAGES) {
-       if ( $extern_image_mark ) {
-           $result = &make_href_noexpand($urlimg, $name , $extern_image_mark);
-           &save_image_map($url, $urlimg, $map, $name, $altst, $ausemp) if $map;
-       }
-    } else {
-       if ($map) {
-           $anch1 = "<A HREF=\"$map\">";
-           $anch2 = "</A>";
-       }
-#      if ($aalign eq "CENTER") {
-#          if ($HTML_VERSION eq "2.0") {
-#              $anch1 .= "\n<P ALIGN=\"CENTER\">";
-#              $anch2 .= "</P>";
-#          } else {
-#              $anch1 .= "\n<DIV ALIGN=\"CENTER\">";
-#              $anch2 .= "</DIV>";
-#          }
-#      }
-
-       $imagesize = $image_size{$url};
-       $imagesize = $usersize if (($usersize)&&($HTML_VERSION > 2.1 ));
-       if ($HTML_VERSION < 2.2 ) {
-           # put the WIDTH/HEIGHT information into the ALT string
-           # first removing the quotes
-           my ($noquotes) = $imagesize;
-           $noquotes =~ s/\"//g;
-           $altst =~ s/"$/\% $noquotes "/m;
-       }
-
-       # include a stylesheet entry for each included image
-       if ($USING_STYLES && $SCALABLE_IMAGES &&(!$imgID)) {
-           if ($url =~ /($dd|^)([^$dd$dd]+)\.$IMAGE_TYPE$/) {
-               my $img_name = $2;
-               $imgID = $img_name . ($img_name =~ /img/ ? '' : $IMAGE_TYPE);
-               $img_style{"$imgID"} = ' ' unless $img_style{"$imgID"};
-               $imgID = join('', ' CLASS="', $imgID, '"') if $imgID;
-           }
-       }
-
-       ### MEH Add width and height to IMG
-       ### Patched by <hswan@perc.Arco.com>:  Fixed \htmladdimg 
-       if ( $imagesize || $name eq "external image" || $NO_IMAGES || $PS_IMAGES) {
-           $imagesize = '' if ($HTML_VERSION < 2.2 );
-           if ($border =~ s/^"//) { $border .= '"' };
-           $result = join(''
-                  , "<IMG$imgID"
-                  , "\n", ($imagesize ? " $imagesize" : '')
-                  , (($aalign)? " ALIGN=\"$aalign\"" : $border)
-                  , $ismap );
-           if ($ausemp) { $result .= " $ausemp" }
-           $result .= "\n" unless (($result =~ /\n *$/m)|| !$imagesize);
-           $result .= " SRC=\"$url\"";
-           if ($altst) { $result .= $altst }
-           $result .= ">";
-       }
-    }
-    join('',$anch1, $result, $anch2);
-}
-
-# MRO: added PNG support
-sub get_image_size { # clean
-    my ($imagefile, $scale) = @_;
-
-    $scale = '' if ($scale == 1);
-    my ($imgID,$size) = ('','');
-    if (open(IMAGE, "<$imagefile")) {
-        my ($buffer,$magic,$dummy,$width,$height) = ('','','',0,0);
-       binmode(IMAGE); # not harmful un UNIX
-        if ($IMAGE_TYPE =~ /gif/) {
-           read(IMAGE,$buffer,10);
-           ($magic,$width,$height) = unpack('a6vv',$buffer);
-            # is this image sane?
-           unless($magic =~ /^GIF8[79]a$/ && ($width * $height) > 0) {
-                $width = $height = 0;
-           }
-        }
-        elsif ($IMAGE_TYPE =~ /png/) {
-            read(IMAGE,$buffer,24);
-           ($magic,$dummy,$width,$height) = unpack('a4a12NN',$buffer);
-           unless($magic eq "\x89PNG" && ($width * $height) > 0) {
-                $width = $height = 0;
-            }
-       }
-       close(IMAGE);
-
-       # adjust for non-trivial $scale factor.
-        my ($img_w,$img_h) = ($width,$height);
-       if ($scale && ($width * $height) > 0) {
-            $img_w = int($width / $scale + .5);
-            $img_h = int($height / $scale + .5);
-       }
-       $size = qq{WIDTH="$img_w" HEIGHT="$img_h"};
-
-       # allow height/width to be stored in the stylesheet
-       my ($img_name,$imgID);
-       if ($SCALABLE_IMAGES && $USING_STYLES) {
-           if ($imagefile =~ /(^|[$dd$dd])([^$dd$dd]+)\.(\Q$IMAGE_TYPE\E|old)$/o) {
-               $img_name = $2;
-               $imgID = $img_name . ($img_name =~ /img/ ? '' : $IMAGE_TYPE);
-           }
-           if ($imgID) {
-               $width = $width/$LATEX_FONT_SIZE/$MATH_SCALE_FACTOR;
-               $height = 1.8 * $height/$LATEX_FONT_SIZE/$MATH_SCALE_FACTOR;
-               # How wide is an em in the most likely browser font ?
-               if ($scale) {
-               # How high is an ex in the most likely browser font ?
-                   $width = $width/$scale; $height = $height/$scale;
-               }
-               $width = int(100*$width + .5)/100;
-               $height = int(100*$height + .5)/100;
-               $img_style{$imgID} = qq(width:${width}em ; height:${height}ex );
-               #join('','width:',$width,'em ; height:',$height,'ex ');
-               $imgID = qq{ CLASS="$imgID"};
-           }
-       }
-    }
-    ($size, $imgID);
-}
-
-sub find_unique { # clean
-    my ($image1) = @_;
-    local($/) = undef; # slurp in complete files
-
-    my $imagedata;
-    if(open(IMG1,"<$image1")) {
-       binmode(IMG1); # needed with .png under DOS
-        $imagedata = <IMG1>;
-        close(IMG1);
-    } else {
-        print "\nError: Cannot read '$image1': $!\n"
-           unless ($image1 =~ /^\s*$HTTP_start/i);
-        return $image1;
-    }
-
-    my ($image2,$result);
-    foreach $image2 (keys(%image_size)) {
-       if ( $image1 ne $image2 &&
-           $image_size{$image1} eq $image_size{$image2} ) {
-           if(open(IMG2,$image2)) {
-               binmode(IMG2); # needed with .png under DOS
-               $result = ($imagedata eq <IMG2>);
-               close(IMG2);
-            } else {
-                print "\nWarning: Cannot read '$image2': $!\n"
-                   unless ($image2 =~ /^\s*$HTTP_start/i);
-            }
-#
-#  If we've found a match, rename the new image to a temporary one.
-#  Then try to link the new name to the old image.
-#  If the link fails, restore the temporary image.
-#
-           if ( $result ) {
-               my $tmp = "temporary.$IMAGE_TYPE";
-               L2hos->Unlink($tmp);
-               L2hos->Rename($image1, $tmp);
-               if (L2hos->Link($image2, $image1)) {
-                    L2hos->Unlink($tmp);
-                } else {
-                    L2hos->Rename($tmp, $image1);
-                }
-               return $image1;
-           }
-       }
-    }
-    $image1;
-}
-
-sub save_image_map { # clean
-    my ($url, $urlimg, $map, $name, $altst, $ausemp) = @_;
-    unless(open(IMAGE_MAP, ">$urlimg")) {
-        print "\nError: Cannot write '$urlimg': $!\n";
-        return;
-    }
-    ### HWS  Pass server map unchanged from user
-    print IMAGE_MAP "<HTML>\n<BODY>\n<A HREF=\"$map\">\n";
-    print IMAGE_MAP "<IMG\n SRC=\"$url\" ISMAP $ausemp $altst> </A>";
-    print IMAGE_MAP "</BODY>\n</HTML>\n";
-    close IMAGE_MAP;
-}
-
-#  Subroutine used mainly to rename an old image file about to recycled.
-#  But for active image maps, we must edit the auxiliary HTML file to point
-#     to the newly renames image.
-sub rename_html {
-    local ($from, $to) = @_;
-    local ($from_prefix, $to_prefix, $suffix);
-    ($from_prefix, $suffix) = split(/\./, $from);
-    ($to_prefix, $suffix) = split(/\./, $to);
-    if ($EXTN =~ /$suffix$/) {
-       if (open(FROM, "<$from") && open(HTMP, ">HTML_tmp")) {
-           while (<FROM>) {
-               s/$from_prefix\.$IMAGE_TYPE/$to_prefix.$IMAGE_TYPE/g;
-               print HTMP;
-           }
-           close (FROM);
-           close (HTMP);
-           L2hos->Rename ("HTML_tmp", $to);
-           L2hos->Unlink($from) unless ($from eq $to);
-       }
-       else {
-           &write_warnings("File $from is missing!\n");
-       }
-    }
-    L2hos->Rename("$from_prefix.old", "$to_prefix.$IMAGE_TYPE");
-    $to;
-}
-
-sub save_captions_in_file {
-    local ($type, $_) = @_;
-    if ($_) {
-       s/^\n//om;
-       &replace_markers;
-       &add_dir_to_href if ($DESTDIR);
-       if(open(CAPTIONS, ">${PREFIX}$type.pl")) {
-           print CAPTIONS $_;
-           close (CAPTIONS);
-        } else {
-            print "\nError: Cannot write '${PREFIX}$type.pl': $!\n";
-        }
-    }
-}
-
-sub add_dir_to_href {
-    $_ =~ s/'/\\'/g;
-    $_ =~ s/(<LI><A )(NAME\=\"tex2html\d+\")?\s*(HREF=\")/$1$3\'.\$dir.\'/og;
-    $_ = join('', "\'", $_, "\'\n");
-}
-
-sub save_array_in_file {
-    local ($type, $array_name, $append, %array) = @_;
-    local ($uutxt,$file,$prefix,$suffix,$done_file,$depth,$title);
-    $prefix = $suffix = "";
-    my $filespec = ($append ? '>>' : '>') . "${PREFIX}$type.pl";
-    $prefix = q("$URL/" . )
-       if ($type eq "labels") && !($array_name eq "external\_latex\_labels");
-    $suffix = " unless (\$$array_name\{\$key\})"
-       if (($type =~ /(sections|contents)/)||($array_name eq "printable\_key"));
-    if ((%array)||($type eq "labels")) {
-       print "\nSAVE_ARRAY:$array_name in FILE: ${PREFIX}$type.pl"
-           if ($VERBOSITY > 1);
-       unless(open(FILE,$filespec)) {
-            print "\nError: Cannot write '${PREFIX}$type.pl': $!\n";
-            return;
-        }
-       if (($array_name eq "sub\_index") || ($array_name eq "printable\_key")) {
-           print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n";
-           print FILE "# Printable index-keys from $array_name array.\n\n";
-       } elsif ($array_name eq "index\_labels") {
-           print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n";
-           print FILE "# labels from $array_name array.\n\n";
-       } elsif ($array_name eq "index\_segment") {
-           print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n";
-           print FILE "# segment identifier from $array_name array.\n\n";
-       } elsif ($array_name eq "external\_latex\_labels") {
-           print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n";
-           print FILE "# labels from $array_name array.\n\n";
-       } else {
-           print FILE "# LaTeX2HTML $TEX2HTMLVERSION\n";
-           print FILE "# Associate $type original text with physical files.\n\n";
-       }
-       while (($uutxt,$file) = each %array) {
-           $uutxt =~ s|/|\\/|g;
-           $uutxt =~ s|\\\\/|\\/|g;
-
-           if (!($array_name =~/images/)&&($file =~ /</)) {
-               do { local $_ = $file;
-                    &replace_markers;
-                    $file = $_; undef $_;
-                    $file =~ s/(\G|[^q])[\\\|]\|/$1\\Vert/sg;
-                    $file =~ s/(\G|[^q])\|/$1\\vert/sg;
-               };
-           }
-
-           local ($nosave);    
-           if ($MULTIPLE_FILES && $ROOTED && 
-                   $type =~ /(sections|contents)/) {
-               #RRM: save from $THIS_FILE only
-               if ( $uutxt =~ /^$THIS_FILE /) {
-                   #RRM: save from $THIS_FILE only
-                   $nosave = ''
-               } else { $nosave = 1 }
-           } else {
-               #RRM: suppress info from other segments
-               $nosave = $noresave{$uutxt}; 
-           }
-
-           if (!$nosave && ($file ne ''))  {
-               print FILE "\n\$key = q/$uutxt/;\n";
-
-               $file =~ s/\|/\\\|/g; # RRM:  escape any occurrences of |
-               $file =~ s/\\\\\|/\\\|/g; # unless already escaped as \|
-               $file =~ s|\\\\|\\\\\\\\|g;
-               $file =~ s/(SRC=")($HTTP_start)?/$1.($2 ? '' :"|.\"\$dir\".q|").$2/seg;
-#
-#
-# added code for  $dir  with segmented docs;  RRM  15/3/96
-#
-               if ($type eq "contents") {
-                   ($depth, $done_file) = split($delim, $file, 2 );
-                   next if ($depth > $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH);
-                   print FILE 
-    "\$$array_name\{\$key\} = '$depth$delim'.\"\$dir\".q|$done_file|$suffix; \n";
-
-               } elsif ($type eq "sections") {
-                   ($depth, $done_file) = split($delim, $file, 2 );
-                   next if ($depth > $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH);
-                   print FILE 
-    "\$$array_name\{\$key\} = '$depth$delim'.\"\$dir\".q|$done_file|$suffix; \n";
-
-               } elsif ($type eq "internals") {
-                   print FILE 
-    "\$$array_name\{\$key\} = \"\$dir\".q|$file|$suffix; \n";
-
-               } elsif ($array_name eq "sub_index") {
-                   print FILE
-    "\$$array_name\{\$key\} .= q|$file|$suffix; \n";
-
-               } elsif ($array_name eq "index") {
-                   local($tmp_file) = '';
-                   ($depth, $done_file) = split('HREF=\"', $file, 2 );
-                   if ($done_file) {
-                       while ($done_file) {
-                           $depth =~ s/\s*$/ / if ($depth);
-                           $tmp_file .= "q|${depth}HREF=\"|.\"\$dir\".";
-                           ($depth, $done_file) = split('HREF=\"', $done_file, 2 );
-                       }
-                       print FILE
-    "\$$array_name\{\$key\} .= ${tmp_file}q|$depth|$suffix; \n";
-
-                   } else {
-                       print FILE
-    "\$$array_name\{\$key\} .= q|$file|$suffix; \n";
-                   }
-               } elsif ($array_name eq "printable_key") {
-                   print FILE
-    "\$$array_name\{\$key\} = q|$file|$suffix; \n";
-
-               } else {
-                   print FILE
-    "\$$array_name\{\$key\} = ${prefix}q|$file|$suffix; \n";
-               }
-
-               if ($type =~ /(figure|table|images)/) {} else {
-                   print FILE "\$noresave\{\$key\} = \"\$nosave\";\n";
-               }
-
-               if ($type eq "sections") {
-                   ($depth, $done_file, $title) = split($delim, $file);
-                   print FILE "\$done\{\"\$\{dir\}$done_file\"\} = 1;\n";
-               }
-           }
-       }
-       print FILE "\n1;\n\n"  unless  ( $array_name =~ /index/ );
-       close (FILE);
-    } else {
-       print "\nSAVE_FILE:$array_name: ${PREFIX}$type.pl  EMPTY " if ($VERBOSITY > 1);
-    }
-}
-
-# returns true if $AUTO_NAVIGATION is on and there are more words in $_
-# than $WORDS_IN_PAGE
-sub auto_navigation {
-    # Uses $_;
-    local(@tmp) = split(/\W*\s+\W*/, $_);
-    ($AUTO_NAVIGATION && ( (scalar @tmp) > $WORDS_IN_PAGE));
-}
-
-# Returns true if $f1 is newer than $f2
-sub newer {
-    ($f1,$f2) = @_;
-    local(@f1s) = stat($f1);
-    local(@f2s) = stat($f2);
-    ($f1s[9] > $f2s[9]);
-};
-
-sub iso_map {
-    local($char, $kind, $quiet) = @_;
-    my($character_map,$enc);
-    local ($this);
-
-    if ( $CHARSET && $HTML_VERSION ge "2.1" ) {
-       # see if it is a character in the charset
-       $character_map = ((($charset =~ /utf/)&&!$NO_UTF)?
-                         'iso_10646' : $CHARSET );
-       $character_map =~ tr/-/_/;
-       eval "\$enc = \$${character_map}_character_map\{\"$char$kind\"\}";
-       print "\n no support for $CHARSET: $@ " if ($@);
-    }
-    if ($USE_ENTITY_NAMES && $enc) { return(";SPM$char$kind;") }
-
-    if ($enc) {
-       $enc =~ /^\&\#(\d{3});$/;
-       # maybe convert it to an 8-bit character
-       if ($NO_UTF && !$USE_UTF && ($1<=255)) { $enc = chr($1) }
-#      elsif (!$USE_UTF &&($1>127)&&($1<160)) { $enc = chr($1) }
-       elsif ($character_map !~ /^iso_(8859_1|10646)/) {
-       # get its latin1 or unicode entity encoding
-           $enc = $iso_8859_1_character_map{"$char$kind"}
-               ||$iso_8859_1A_character_map{"$char$kind"}
-               ||$iso_10646_character_map{"$char$kind"}
-       }
-     } else {
-       # get its latin1 or unicode entity encoding, if available
-       $enc = $iso_8859_1_character_map{"$char$kind"}
-           ||$iso_8859_1A_character_map{"$char$kind"}
-           ||$iso_10646_character_map{"$char$kind"};
-    }
-
-    if ($enc) {
-       $ISOLATIN_CHARS = 1; $enc;
-    } elsif (!$image_made{"$char$kind"}) {
-       print "\ncouldn't convert character $char$kind into available encodings"
-           if (!quiet &&($VERBOSITY > 1));
-       &write_warnings(
-           "couldn't convert character $char$kind into available encodings"
-           . ($ACCENT_IMAGES ? ', using image' : '')) unless ($quiet);
-       $image_made{"$char$kind"} = 1;
-       '';
-    } else {''}
-}
-
-sub titles_language {
-    local($_) = @_;
-    local($lang) = $_ . "_titles";
-    if (defined(&$lang)) { &$lang }
-    else {
-       &english_titles;
-       &write_warnings(
-           "\nThere is currently no support for the $tmp language." .
-           "\nSee the file $CONFIG_FILE for examples on how to add it\n\n");
-    }
-}
-
-sub translate_titles {
-    $toc_title = &translate_commands($toc_title) if ($toc_title =~ /\\/);
-    $lof_title = &translate_commands($lof_title) if ($lof_title =~ /\\/);
-    $lot_title = &translate_commands($lot_title) if ($lot_title =~ /\\/);
-    $idx_title = &translate_commands($idx_title) if ($idx_title =~ /\\/);
-    $ref_title = &translate_commands($ref_title) if ($ref_title =~ /\\/);
-    $bib_title = &translate_commands($bib_title) if ($bib_title =~ /\\/);
-    $abs_title = &translate_commands($abs_title) if ($abs_title =~ /\\/);
-    $app_title = &translate_commands($app_title) if ($app_title =~ /\\/);
-    $pre_title = &translate_commands($pre_title) if ($pre_title =~ /\\/);
-    $foot_title = &translate_commands($foot_title) if ($foot_title =~ /\\/);
-    $fig_name = &translate_commands($fig_name) if ($fig_name =~ /\\/);
-    $tab_name = &translate_commands($tab_name) if ($tab_name =~ /\\/);
-    $prf_name = &translate_commands($prf_name) if ($prf_name =~ /\\/);
-    $page_name = &translate_commands($page_name) if ($page_name =~ /\\/);
-    $child_name = &translate_commands($child_name) if ($child_name =~ /\\/);
-    $info_title = &translate_commands($info_title) if ($info_title =~ /\\/);
-    $part_name = &translate_commands($part_name) if ($part_name =~ /\\/);
-    $chapter_name = &translate_commands($chapter_name)
-       if ($chapter_name =~ /\\/);
-    $section_name = &translate_commands($section_name)
-       if ($section_name =~ /\\/);
-    $subsection_name = &translate_commands($subsection_name)
-       if ($subsection_name =~ /\\/);
-    $subsubsection_name = &translate_commands($subsubsection_name)
-       if ($subsubsection_name =~ /\\/);
-    $paragraph_name = &translate_commands($paragraph_name)
-       if ($paragraph_name =~ /\\/);
-    $see_name = &translate_commands($see_name) if ($see_name =~ /\\/);
-    $also_name = &translate_commands($also_name) if ($also_name =~ /\\/);
-    $next_name = &translate_commands($next_name) if ($next_name =~ /\\/);
-    $prev_name = &translate_commands($prev_name) if ($prev_name =~ /\\/);
-    $up_name = &translate_commands($up_name) if ($up_name =~ /\\/);
-    $group_name = &translate_commands($group_name) if ($group_name =~ /\\/);
-    $encl_name = &translate_commands($encl_name) if ($encl_name =~ /\\/);
-    $headto_name = &translate_commands($headto_name) if ($headto_name =~ /\\/);
-    $cc_name = &translate_commands($cc_name) if ($cc_name =~ /\\/);
-    $default_title = &translate_commands($default_title)
-       if ($default_title =~ /\\/);
-}
-####################### Code Generation Subroutines ############################
-# This takes a string of commands followed by optional or compulsory
-# argument markers and generates a subroutine for each command that will
-# ignore the command and its arguments.
-# The commands are separated by newlines and have the format:
-##      <cmd_name>#{}# []# {}# [] etc.
-# {} marks a compulsory argument and [] an  optional one.
-sub ignore_commands {
-    local($_) = @_;
-    foreach (/.*\n?/g) {
-       s/\n//g;
-       # For each line
-       local($cmd, @args) = split('\s*#\s*',$_);
-       next unless $cmd;
-       $cmd =~ s/ //;
-       ++$ignore{$cmd};
-       local ($body, $code, $thisone) = ("", "");
-       
-       # alter the pattern here to debug particular commands
-       $thisone = 1 if ($cmd =~ /let/);
-
-       if (@args) {
-           print "\n$cmd: ".scalar(@args)." arguments" if ($thisone);
-           # Replace the argument markers with appropriate patterns
-           foreach $arg (@args) {
-               print "\nARG: $arg" if ($thisone);
-               if ($arg =~ /\{\}/) {
-                   $body .= 'local($cmd) = '."\"$cmd\"".";\n";
-                   $body .= '$args .= &missing_braces'."\n ".'unless (';
-                   $body .= '(s/$next_pair_pr_rx/$args .= $2;\'\'/eo)'."\n";
-                   $body .= '  ||(s/$next_pair_rx/$args .= $2;\'\'/eo));'."\n";
-                   print "\nAFTER:$'" if (($thisone)&&($'));
-                   $body .= $' if ($');
-               } elsif ($arg =~ /\[\]/) {
-                   $body .= '($dummy, $pat) = &get_next_optional_argument;'
-                       . '$args .= $pat;'."\n";
-                   print "\nAFTER:$'" if (($thisone)&&($'));
-                   $body .= $' if ($');
-               } elsif ($arg =~ /^\s*\\/) {                
-                   $body .= '($dummy, $pat) = &get_next_tex_cmd;'
-                       . '$args .= $pat;'."\n";
-                   print "\nAFTER:$'" if (($thisone)&&($'));
-                   $body .= $' if ($');
-               } elsif ($arg =~ /<<\s*([^>]*)[\b\s]*>>/) {
-                   local($endcmd, $after) = ($1,$');
-                   $after =~ s/(^\s*|\s*$)//g;
-                   $endcmd = &escape_rx_chars($endcmd);
-                   $body .= 'if (/'.$endcmd.'/o) { $args .= $`; $_ = $\' };'."\n";
-                   print "\nAFTER:$after" if (($thisone)&&($after));
-                   $body .= "$after" if ($after);
-               } else {
-                   print "\nAFTER:$'" if (($thisone)&&($arg));
-                   $body .= $arg ;
-               }
-           }
-           # Generate a new subroutine
-#          $code = "sub do_cmd_$cmd {\n".'local($_) = @_;'. join('',@args) .'$_}';
-           $code = "sub do_cmd_$cmd {\n"
-               . 'local($_,$ot) = @_; '
-               . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R; '
-               . 'local($args); '
-               . "\n" . $body . (($body)? ";\n" : '')
-               . (($thisone)? "print \"\\n$cmd:\".\$args.\"\\n\";\n" : '')
-               . (($arg)? $arg : '$_') . "}";
-           print STDOUT "\n$code\n" if ($thisone); # for error-checking
-           eval ($code); # unless ($thisone);
-           print STDERR "\n\n*** sub do_cmd_$cmd failed: $@\n" if ($@);
-       } else {
-           $code = "sub do_cmd_$cmd {\n".'$_[0]}';
-           print "\n$code\n" if ($thisone); # for error-checking
-           eval ($code); # unless ($thisone);
-           print STDERR "\n\n*** sub do_cmd_$cmd failed: $@\n" if ($@);
-        }
-    }
-}
-
-
-sub ignore_numeric_argument {
-    # Chop this off
-    #RRM: 2001/11/8: beware of taking too much, when  <num> <num> 
-    local($num) = '(^|width|height|plus|minus)\s*[+-]?[\d\.]+(cm|em|ex|in|pc|pt|mm)?\s*';
-    do { s/^\s*=?\s*//so; s/^($num)*//so } unless (/^(\s*\<\<\d+\>\>|$)/);
-}
-
-sub get_numeric_argument {
-    my ($num_rx,$num) = ('','');
-    # Collect the numeric part
-    #RRM: 2001/11/8: beware of taking too much, when  <num> <num> 
-    $num_rx = '(^|width|height|plus|minus)\s*[+-]?[\d\.]+(cm|em|ex|in|pc|pt|mm)?\s*';
-    do { s/^\s*=?\s*//so; s/($num_rx)*/$num=$&;''/soe } unless (/^(\s*\<\<\d+\>\>|$)/);
-    $num;
-}
-
-sub process_in_latex_helper {
-    local($ctr,$val,$cmd) = @_;
-    ($ASCII_MODE ? "[$cmd]" : 
-       &process_in_latex("\\setcounter{$ctr}{$val}\\$cmd"))
-}
-
-sub do_cmd_catcode {
-    local($_) = @_;
-    s/^\s*[^=]+(=?\s*\d+\s|\\active)\s?//;
-    $_;
-}
-
-sub do_cmd_string {
-    local($_) = @_;
-    local($tok);
-    s/^\s*(\\([a-zA-Z]+|.)|[&;]\w+;(#\w+;)?|.)/$tok=$1;''/e;
-    if ($2) {$tok = "\&#92;$2"};
-    "$tok".$_
-}
-
-sub do_cmd_boldmath {
-    local($_) = @_;
-    $BOLD_MATH = 1;
-    $_;
-}
-
-sub do_cmd_unboldmath {
-    local($_) = @_;
-    $BOLD_MATH = 0;
-    $_;
-}
-
-sub do_cmd_lq {
-    local($_) = @_ ;
-    local($lquote);
-    # check for double quotes
-    if (s/^\s*\\lq(\b|$|[^A-Za-z])/$1/) {
-       $lquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? '``'
-               : &do_leftquotes($_));
-    } else {
-       $lquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? '`'
-               : &do_leftquote($_));
-    }
-    $lquote . $_;
-}
-
-sub do_leftquote {
-    # MRO: use $_[0] : local(*_) = @_;
-    local($quote,$lquo) = ('',($HTML_VERSION<5)? '&#8216;' : ';SPMlsquo;');
-    # select whole quotation, if \lq matches \rq
-    if ($_[0] =~ /^(.*)((\\rq\\rq|'')*)(\\rq)/) {
-       $quote = $1.$2; $_[0] = $';
-       local($rquo) = &do_rightquote();
-       &process_quote($lquo,$quote,$rquo);
-    } else { $lquo; }
-}
-
-sub do_leftquotes {
-    # MRO: use $_[0] : local(*_) = @_;
-    local($quote,$lquo) = ('',($HTML_VERSION<5)? '&#8220;' : ';SPMldquo;');
-    # select whole quotation, if \lq\lq matches \rq\rq or ''
-    if ($_[0] =~ /^(.*)(\\rq\\rq|'')/) {
-       $quote = $1; $_[0] = $';
-       local($rquo) = &do_rightquotes();
-       &process_quote($lquo,$quote,$rquo);
-    } else { $lquo; }
-}
-
-# RRM: By default this just concatenates the strings; e.g. ` <quote> '
-# This can be overridden in a html-version file
-sub process_quote { join ('', @_) }
-
-sub do_cmd_rq {
-    local($_) = @_ ;
-    local($rquote);
-    if ($_ =~ s/^\s*\\rq\b//) {
-       $rquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? "''"
-               : &do_rightquotes());
-    } else { 
-       $rquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? "'"
-               : &do_rightquote());
-    }
-    $rquote . $_;
-}
-
-sub do_rightquote { (($HTML_VERSION < 5)? '&#8217;' : ';SPMrsquo;') }
-sub do_rightquotes { (($HTML_VERSION < 5)? '&#8221;' : ';SPMrdquo;') }
-
-sub do_cmd_parbox {
-    local($_) = @_;
-    local($args, $contents, $dum, $pat);
-    $* = 1;                    # Multiline matching ON
-    ($dum,$pat) = &get_next_optional_argument; # discard this
-    ($dum,$pat) = &get_next_optional_argument; # discard this
-    ($dum,$pat) = &get_next_optional_argument; # discard this
-    $args .= $pat if ($pat);
-    $pat = &missing_braces unless (
-       (s/$next_pair_pr_rx/$pat=$2;''/eo)
-       ||(s/$next_pair_rx/$pat=$2;''/eo));
-    $args .= "{".$`.$pat."}";
-    $contents = &missing_braces unless (
-       (s/$next_pair_pr_rx/$contents=$2;''/eo)
-       ||(s/$next_pair_rx/$contents=$2;''/eo));
-    $* = 0;                    # Multiline matching OFF
-    $args .= "{".$`.$contents."}";
-    if ($NO_PARBOX_IMAGES) {
-       $contents = join ('', &do_cmd_par(), $contents, '</P>' );
-    } else {
-       $contents = &process_math_in_latex('','text',0,"\\parbox$args")
-           if ($contents);
-    }
-    $contents . $_;
-}
-
-
-sub do_cmd_mbox {
-    local($_) = @_;
-    local($text,$after)=('','');
-    $text = &missing_braces unless (
-       (s/$next_pair_pr_rx/$text = $2;''/eo)
-       ||(s/$next_pair_rx/$text = $2;''/eo));
-    $after = $_;
-
-    # incomplete macro replacement
-    if ($text =~ /(^|[^\\<])#\d/) { return($after) }
-
-    if ($text =~ /(tex2html_wrap_inline|\$$OP(\d+)$CP$OP\2$CP\$|\$$O(\d+)$C$O\2$C\$)/) {
-       if ($text =~ 
-           /$image_mark#([^#]+)#([\.,;:\)\]])?(\001)?([ \t]*\n?)(\001)?/) {
-           local($mbefore, $mtext, $mafter) = ($`, $&, $');
-           $mbefore = &translate_commands($mbefore) if ($mbefore =~ /\\/);
-           $mafter = &translate_commands($mafter) if ($mafter =~ /\\/);
-           join('', $mbefore, $mtext, $mafter, $after);
-       } else {
-           join ('', &process_math_in_latex('','','',"\\hbox{$text}"), $after )
-       }
-    } else {
-       $text = &translate_environments($text);
-       $text = &translate_commands($text);
-       join('', $text, $after);
-    }
-}
-
-
-
-# *Generates* subroutines to handle each of the declarations
-# like \em, \quote etc., in case they appear with the begin-end
-# syntax.
-sub generate_declaration_subs {
-    local($key, $val, $pre, $post, $code );
-    print "\n *** processing declarations ***\n";
-    while ( ($key, $val) = each %declarations) {
-       if ($val) {
-           ($pre,$post) = ('','');
-           $val =~ m|</.*$|;
-           do {$pre = $`; $post = $& } unless ($` =~ /^<>/);
-           $pre =~ s/"/\\"/g; $post =~ s/"/\\"/g;
-           $code = "sub do_env_$key {"
-#              . 'local($_) = @_;' . "\n"
-#              . 'push(@$open_tags_R, $key);'. "\n"
-#              . '$_ = &translate_environments($_);'. "\n"
-#              . '$_ = &translate_commands($_);'. "\n"
-#              . "join('',\"$pre\",\"\\n\"," .'$_' .",\"$post\");\n};";
-               . '&declared_env('.$key.',@_)};';
-           eval $code;
-           if ($@) {print "\n *** $key ".  $@ };
-       }
-    }
-}
-
-# *Generates* subroutines to handle each of the sectioning commands.
-sub generate_sectioning_subs {
-    local($key, $val, $cmd, $body);
-    while ( ($key, $val) = each %standard_section_headings) {
-       $numbered_section{$key} = 0;
-       eval "sub do_cmd_$key {"
-           . 'local($after,$ot) = @_;'
-           . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'
-            . '&reset_dependents('. $key . ');'
-            . '&do_cmd_section_helper('.$val.','.$key.');}';
-       print STDERR "\n*** sub do_cmd_$key failed:\n$@\n" if ($@);
-       # Now define the *-form of the same commands. The difference is that the
-       # $key is not passed as an argument.
-       eval "sub do_cmd_$key" . "star {"
-           . 'local($after,$ot) = @_;'
-           . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'
-           . '&do_cmd_section_helper(' . $val . ');}';
-       print STDERR "\n*** sub do_cmd_${key}star failed:\n$@\n" if ($@);
-       # Now define the macro  \the$key  
-       &process_commands_wrap_deferred("the$key \# {}\n");
-###    local($_) = "<<1>>$key<<1>>";
-       $body = "<<1>>$key<<1>>";
-       &make_unique($body);
-       $cmd = "the$key";
-       eval "sub do_cmd_$cmd {"
-           . 'local($after,$ot) = @_;'
-           . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'
-           . '&do_cmd_arabic(' . "\"$body\"" . ").\$after;};";
-       print STDERR "\n*** sub do_cmd_$cmd failed:\n$@\n" if ($@);
-       $raw_arg_cmds{$cmd} = 1;
-    }
-    &addto_dependents('chapter','section');
-    &addto_dependents('section','subsection');
-    &addto_dependents('subsection','subsubsection');
-    &addto_dependents('subsubsection','paragraph');
-    &addto_dependents('paragraph','subparagraph');
-}
-
-sub addto_dependents {
-    local($ctr, $dep) = @_;
-    local($tmp, $depends);
-    if ($depends = $depends_on{$dep}) {
-       &remove_dependency($depends, $dep) }
-    $depends_on{$dep} = $ctr;
-
-    $tmp = $dependent{$ctr};
-    if ($tmp) { 
-       $dependent{$ctr} = join($delim, $tmp, $dep);
-    } else { $dependent{$ctr} = $dep }
-}
-
-sub remove_dependency {
-    local($ctr, $dep) = @_;
-    local(@tmp, $tmp, $dtmp);
-    print "\nremoving dependency of counter {$dep} from {$ctr}\n";
-    foreach $dtmp (split($delim, $dependent{$ctr})) {
-       push(@tmp, $dtmp) unless ($dtmp =~ /$dep/);
-    }
-    $dependent{$ctr} = join($delim, @tmp);
-}
-
-
-# Uses $after which is defined in the caller (the caller is a generated subroutine)
-# Also uses @curr_sec_id
-#
-#JCL(jcl-tcl) (changed almost everything)
-#
-sub do_cmd_section_helper {
-    local($H,$key) = @_;
-    local($section_number, $titletext, $title_key, @tmp, $align, $dummy);
-    local($anchors,$pre,$run_title,$_) = ('', "\n", '', $after);
-    local($open_tags_R) = [];
-
-    # if we have a $key the current section is not of the *-form, so we need
-    # to update the counters.
-    &do_cmd_stepcounter("${O}0$C$key${O}0$C")
-#      if ($key && !$making_name);
-#      if ($key && !($unnumbered_section_commands{$key}) && !$making_name);
-       if ($key && !($unnumbered_section_commands{$key}));
-#   $latex_body .= "\\stepcounter{$key}\n" if $key;
-#   &reset_dependents($key) if ($dependent{$key});
-
-    local($br_id);
-#    if ($USING_STYLES) {
-#      $txt_style{"H$H.$key"} = " " unless $txt_style{"H$H.$key"}; 
-#      $H .= " CLASS=\"$key\"; 
-#    };
-
-    local ($align, $dummy)=&get_next_optional_argument;
-    if (($align =~/^(left|right|center)$/i)&&($HTML_VERSION > 2.0)) {
-        $align = "ALIGN=\"$1\"";
-    } elsif ($align) {
-       # data was meant to be a running-head !
-       $br_id = ++$global{'max_id'};
-       $run_title = &translate_environments("$O$br_id$C$align$O$br_id$C");
-       $run_title = &translate_commands($run_title) if ($run_title =~ /\\/);
-       $run_title =~ s/($O|$OP)\d+($C|$CP)//g;
-       $align = '';
-    } else {
-    }
-    $titletext = &missing_braces 
-       unless s/$next_pair_rx/$titletext=$2;''/eo;
-    $br_id = ++$global{'max_id'};
-    $titletext = &translate_environments("$O$br_id$C$titletext$O$br_id$C");
-
-    $title_key = $run_title || $titletext;
-    $title_key =~ s/$image_mark\#([^\#]+)\#(\\space)?/&purify_caption($1)/e;
-    # This should reduce to the same information as contained in the .aux file.
-    $title_key = &sanitize(&simplify($title_key));
-
-    # RRM: collect all anchors from \label and \index commands
-    ($anchors,$titletext) = &extract_anchors($titletext);
-    local($saved_title) = $titletext;
-    do {
-        # to ensure a style ID is not saved and re-used in (mini-)TOCs
-       local($USING_STYLES) = 0;
-       $titletext = &translate_environments($titletext);
-       $titletext = &translate_commands($titletext) 
-           if ($titletext =~/\\/);
-    };
-    # but the style ID can be used for the title on the HTML page
-    if (!($titletext eq $saved_title)) {
-       $saved_title = &translate_environments($saved_title);
-       $saved_title = &translate_commands($saved_title) 
-           if ($saved_title =~/\\/);
-       $saved_title = &simplify($saved_title);
-    }
-    local($closures) = &close_all_tags();
-    $saved_title .= $closures;
-    $title_text .= $closures;
-
-    # This is the LaTeX section number read from the $FILE.aux file
-    @tmp = split(/$;/,$encoded_section_number{$title_key});
-    $section_number = shift(@tmp);
-    $section_number = "" if ($section_number eq "-1");
-    $encoded_section_number{$title_key} = join($;, @tmp)
-#      unless (defined $title);
-       unless ($title);
-
-    # need to check also &{wrap_cmd_... also, if \renewcommand has been used; 
-    # thanks Bruce Miller
-    local($thehead,$whead) = ("do_cmd_the$key","wrap_cmd_the$key");
-#    $thehead = ((defined &$thehead)? 
-#      &translate_commands("\\the$key") : '');
-    $thehead = ((defined &$thehead)||(defined &$whead)
-       ? &translate_commands("\\the$key") : '');
-    $thehead .= $SECNUM_PUNCT
-       if ($SECNUM_PUNCT &&($thehead)&& !($thehead =~ /\./));
-    $section_number = $thehead if (($thehead)&&($SHOW_SECTION_NUMBERS));
-
-    #JKR: Don't prepend whitespace 
-    if ($section_number) {
-       $titletext = "$section_number " . $titletext;
-       $saved_title = "$section_number " . $saved_title;
-       $run_title = "$section_number " . $run_title if $run_title;
-    }
-
-#    $toc_sec_title = $titletext;
-#    $toc_sec_title = &purify($titletext);
-    $toc_sec_title = &simplify($titletext);
-    $titletext = &simplify($titletext);
-#    $TITLE = &purify($titletext);
-    local($after) = $_;
-    do {
-       local($_) = $titletext; &remove_anchors; 
-       if ($run_title) {
-           $TITLE = $run_title;
-       } elsif ($_) {
-           $TITLE = $_
-       } else { $TITLE = '.' };
-    };
-    $global{$key}-- if ($key && $making_name);
-    return ($TITLE) if (defined $title);
-
-    #RRM: no preceding \n when this is the first section-head on the page.
-    if (! $key || $key < $MAX_SPLIT_DEPTH) { $pre = '' };
-    if ( defined &make_pre_title) {
-       $pre = &make_pre_title($saved_title, $H);
-    }
-
-    undef $open_tags_R;
-    $open_tags_R = [ @save_open_tags ];
-    
-    join('', $pre, &make_section_heading($saved_title, $H, $align.$anchors)
-       , $open_all, $_);
-}
-
-sub do_cmd_documentclass {
-    local($_) = @_;
-    local ($docclass)=('');
-    local ($cloptions,$dum)=&get_next_optional_argument;
-    $docclass = &missing_braces unless (
-       (s/$next_pair_pr_rx/$docclass = $2;''/eo)
-       ||(s/$next_pair_rx/$docclass = $2;''/eo));
-    local($rest) = $';
-    &do_require_package($docclass);
-    if (! $styles_loaded{$docclass}) {
-       &no_implementation("document class",$docclass);
-    } else {
-       if($cloptions =~ /\S+/) { # are there any options?
-           &do_package_options($docclass,$cloptions);
-       }
-    }
-    $rest;
-}
-sub do_cmd_documentstyle { &do_cmd_documentclass($_[0]); }
-
-sub do_cmd_usepackage {
-    local($_) = @_;
-    # RRM:  allow lists of packages and options
-    local ($package, $packages)=('','');
-    local ($options,$dum)=&get_next_optional_argument;
-    $packages = &missing_braces unless (
-       (s/$next_pair_pr_rx/$packages = $2;''/eo)
-       ||(s/$next_pair_rx/$packages = $2;''/eo));
-    local($rest) = $_;
-    # MRO: The files should have already been loaded by
-    #      TMP_styles, but we better make it sure.
-    foreach $package (split (',',$packages)) { # allow multiple packages
-       $package =~ s/\s|\%|$comment_mark\d*//g; # remove whitespace 
-       $package =~ s/\W/_/g; # replace non-alphanumerics
-       &do_require_package($package);
-       if (! $styles_loaded{$package}) {
-           &no_implementation("package",$package);
-       } else {
-           if($options =~ /\S+/) { # are there any options?
-               &do_package_options($package,$options);
-           }
-       }
-    }
-    $rest;
-}
-
-
-sub no_implementation {
-    local($what,$which)= @_;
-    print STDERR "\nWarning: No implementation found for $what: $which";
-}
-
-sub do_cmd_RequirePackage {
-    local($_)= @_;
-    local($file);
-    local($options,$dum)=&get_next_optional_argument;
-    $file = &missing_braces unless (
-       (s/$next_pair_pr_rx/$file = $2;''/eo)
-       ||(s/$next_pair_rx/$file = $2;''/eo));
-    local($rest) = $_;
-    $file =~ s/^[\s\t\n]*//o;
-    $file =~ s/[\s\t\n]*$//o;
-    # load the package, unless that has already been done
-    &do_require_package($file) unless ($styles_loaded{$file});
-    # process any options
-    if (! $styles_loaded{$file}) {
-           &no_implementation("style",$file);
-    } else {
-       # process any options
-       &do_package_options($file,$options) if ($options);
-    }
-    $_ = $rest;
-    # ignore trailing optional argument
-    local($date,$dum)=&get_next_optional_argument;
-    $_;
-}
-
-sub do_cmd_PassOptionsToPackage {
-    local($_) = @_;
-    local($options,$file);
-    $options = &missing_braces unless (
-        (s/$next_pair_pr_rx/$options = $2;''/eo)
-        ||(s/$next_pair_rx/$options = $2;''/eo));
-    $file = &missing_braces unless (
-        (s/$next_pair_pr_rx/$file = $2;''/eo)
-        ||(s/$next_pair_rx/$file = $2;''/eo));
-    $passedOptions{$file} = $options;
-    $_;
-}
-sub do_cmd_PassOptionsToClass{ &do_cmd_PassOptionsToPackage(@_)}
-
-sub do_package_options {
-    local($package,$options)=@_;
-    local($option);
-    if ($passedOptions{$package}) { $options = $passedOptions{$package}.'.'.$options };
-    foreach $option (split (',',$options)) {
-        $option =~ s/^[\s\t\n]*//o;
-        $option =~ s/[\s\t\n]*$//o;
-       $option =~ s/\W/_/g; # replace non-alphanumerics
-       next unless ($option);
-        if (!($styles_loaded{$package."_$option"})) {
-            &do_require_packageoption($package."_$option");
-            if (!($styles_loaded{$package."_$option"})) {
-               &no_implementation("option","\`$option\' for \`$package\' package\n");
-           }
-       }
-    }
-    $rest;
-}
-
-sub do_class_options {
-    local($class,$options)=@_;
-    local($option);
-    if ($passedOptions{$class}) { $options = $passedOptions{$class}.'.'.$options };
-    foreach $option (split (',',$options)) {
-        $option =~ s/^[\s\t\n]*//o;
-        $option =~ s/[\s\t\n]*$//o;
-       $option =~ s/\W/_/g; # replace non-alphanumerics
-       next unless ($option);
-        &do_require_package($option);
-        if (!($styles_loaded{$class."_$option"})) {
-            &do_require_packageoption($class."_$option");
-            if (!($styles_loaded{$class."_$option"})) {
-               &no_implementation("option","\`$option\' for document-class \`$class\'\n");
-           }
-       }
-    }
-    $rest;
-}
-
-sub do_require_package {
-    local($file)= @_;
-    local($dir);
-    #RRM: make common ps/eps-packages use  epsfig.perl
-    $file = 'epsfig' if ($file =~ /^(psfig|epsf)$/);
-
-    if ($file =~ /^graphicx$/) {
-       # work-around the CVS repository bug: use graphixx , not graphicx
-       foreach $dir (split(/$envkey/,$LATEX2HTMLSTYLES)) {
-           if (-f "$dir${dd}graphixx.perl") {
-               $file = 'graphixx';
-               last;
-           }
-       }
-    }
-
-    
-    if (! $styles_loaded{$file}) {
-       # look for a file named ${file}.perl
-       # MRO: use $texfilepath instead of `..'
-       if ((-f "$texfilepath$dd${file}.perl") && ! $styles_loaded{$file}){
-           print STDOUT "\nPackage: loading $texfilepath$dd${file}.perl";
-           require("$texfilepath$dd${file}.perl");
-           $styles_loaded{$file} = 1;
-       } else {
-           foreach $dir (split(/$envkey/,$LATEX2HTMLSTYLES)) {
-               if ((-f "$dir$dd${file}.perl") && ! $styles_loaded{$file}){
-                   print STDOUT "\nPackage: loading $dir$dd${file}.perl";
-                   require("$dir$dd${file}.perl");
-                   $styles_loaded{$file} = 1;
-                   last;
-               }
-           }
-       }
-    }
-}
-
-sub do_require_extension {
-    local($file)= @_;
-    local($dir);
-
-    if (! $styles_loaded{$file}) {
-       # look for a file named ${file}.pl
-       # MRO: use $texfilepath instead of `..'
-       if (-f "$texfilepath$dd${file}.pl") {
-           print STDOUT "\nExtension: loading $texfilepath$dd${file}.pl";
-           require("$texfilepath$dd${file}.pl");
-           ++$styles_loaded{$file};
-           $NO_UTF = 1 if (($file =~ /latin/)&&($charset =~/utf/));
-       } else {
-           foreach $dir (split(/$envkey/,$LATEX2HTMLVERSIONS)) {
-               if (-f "$dir$dd${file}.pl"){
-                   print STDOUT "\nExtension: loading $dir$dd${file}.pl";
-                   require("$dir$dd${file}.pl");
-                   ++$styles_loaded{$file};
-                   $NO_UTF = 1 if (($file =~ /latin/)&&($charset =~/utf/));
-                   last;
-               }
-           }
-       }
-    } else {
-       if (($file =~ /latin|hebrew/)&&($charset =~/utf|10646/)
-                       && $loading_extensions) {
-           $NO_UTF = 1;
-           $USE_UTF = 0;
-           print STDOUT "\n\n ...producing $CHARSET output\n";
-           $charset = $CHARSET;
-       } 
-    }
-}
-
-sub do_require_packageoption {
-    local($option)= @_;
-    local($do_option);
-    # first look for a file named ${option}.perl
-    &do_require_package($option) unless ($styles_loaded{$option});
-    # next look for a subroutine named  do_$option
-    $do_option = "do_$option";
-    if (!($styles_loaded{$option}) && defined(&$do_option)) {
-       &$do_option();
-       $styles_loaded{$option} = 1;
-    }
-}
-
-############################ Environments ################################
-
-# This is a dummy environment used to synchronise the expansion
-# of order-sensitive macros.
-sub do_env_tex2html_deferred {
-    local($_) = @_;
-    local($tex2html_deferred) = 1;
-    $_ = &process_command($single_cmd_rx,$_);
-}
-
-# catch wrapped commands that need not have been
-sub do_env_tex2html_nomath_inline {
-    local($_) = @_;
-    s/^\s+|\s+$//gs;
-    my($cmd) = $_;
-    if ($cmd=~s/^\\([a-zA-Z]+)//s) { $cmd = $1 };
-    return (&translate_commands($_)) if ($raw_arg_cmds{$cmd}<1);
-    &process_undefined_environment($env, $id, $_);
-}
-
-# The following list environment subroutines still do not handle
-# correctly the case where the list counters are modified (e.g. \alph{enumi})
-# and the cases where user defined bullets are mixed with the default ones.
-# e.g. \begin{enumerate} \item[(1)] one \item two \end{enumerate} will
-# not produce the same bullets as in the dvi output.
-sub do_env_itemize {
-    local($_) = @_;
-    $itemize_level++;
-    #RRM - catch nested lists
-    &protect_useritems($_);
-    $_ = &translate_environments($_);
-
-    local($bullet,$bulletx)=('&nbsp;','');
-    SWITCH: {
-       if ($itemize_level==1) { $bulletx = "\\bullet"; last SWITCH; }
-       if ($itemize_level==2) { $bulletx = "\\mathbf{\\circ}"; last SWITCH; }
-       if ($itemize_level==3) { $bulletx = "\\mathbf{\\ast}"; last SWITCH; }
-    }
-    $itemize_level--;
-
-    if (/\s*$item_description_rx/) {
-       # Contains user defined optional labels
-       $bulletx = &do_cmd_mbox("${O}1$C\$$bulletx\$${O}1$C") if $bulletx;
-       &do_env_description($_, " COMPACT", $bullet.$bulletx)
-    } else { &list_helper($_,'UL'); }
-}
-
-sub do_env_enumerate {
-    local($_) = @_;
-# Reiner Miericke provided the main code; integrated by RRM: 14/1/97
-# works currently only with 'enumerate' and derived environments
-# explicit styled labels are computed for each \item
-# ultimately the environment is done as:  &do_env_description($_, " COMPACT")
-    ++$enum_level;
-    local(%enum) = %enum;              # to allow local changes
-# Reiner: \begin{enumerate}[<standard_label>]
-    local($standard_label) = "";
-    local(@label_fields);
-    local($label_func, $preitems, $enum_type);
-    local($rlevel) = &froman($enum_level); # e.g. 3 => iii
-
-    # \begin{enumerate}[$standard_label]
-    if (s/^$standard_label_rx//s) {            # multiline on/off ?
-       # standard label should be used later to modify
-       # entries in %enum
-       $standard_label = $1;           # save the standard label
-#      s/^$standard_label_rx//;        # and cut it off
-       $standard_label =~ s/([\\\[\]\(\)])/\\$1/g; # protect special chars
-
-       # Search for [aAiI1] which is not between a pair of { }
-       # Other cases like "\theenumi" are not handled
-       @label_fields = $standard_label =~ /$enum_label_rx/;
-       if (($standard_label =~ /^[aAiI1]$/)&&(not(/item\s*\[/))) {
-           $enum_type = ' TYPE="'.$standard_label.'"';
-           $standard_label = '';
-       } else {
-           $label_func = $enum_label_funcs{$label_fields[$#label_fields-1]} . 
-               "(\'enum" . $rlevel . "\')";
-           $enum{'theenum' . $rlevel} = "\&$label_func";
-#      local($thislabel) = "\&$label_func";
-#      do { local($_) = $thislabel; &make_unique($_);
-#           $enum{'theenum' . $rlevel} = $_; };
-           $standard_label = 
-               "\"$label_fields[0]\" . eval(\$enum{\"theenum$rlevel\"})"
-               . ".\"$label_fields[$#label_fields]\"";
-           $enum{'labelenum' . $rlevel} = $standard_label;
-       }
-    }  elsif (s/^((.|\n)+?)\\item/$preitems=$1;"\\item"/es) {
-       my $pre_preitems; local($cmd); $label_part;
-       my $num_styles = join('|', values %enum_label_funcs );
-       while ($preitems =~
-           /\s*\\renew(ed)?command\s*(($O|$OP)\d+($C|$CP))\\?((label|the)enum(\w+))\s*\2/) {
-           # this catches one  \renewcommand{\labelenum}{....} 
-           $pre_preitems .= $`; $preitems = $'; $cmd = $5;
-           &missing_braces unless (
-               ($preitems=~s/$next_pair_pr_rx\s*/$label_part=$2;''/oe)
-               ||($preitems=~s/$next_pair_rx\s*/$label_part=$2;''/oe));
-           $cmd =~ s/^label/the/;
-           $label_part=~s/\\($num_styles)\s*(($O|$OP)\d+($C|$CP))(\w+)\2/".\&$1\(\'$5\'\)."/g;
-           $label_part = '"'.$label_part.'"';
-           $enum{$cmd} = $label_part;
-        }
-       $standard_label = 
-           "\"$label_fields[0]\" . eval(\$enum{\"theenum$rlevel\"})"
-           . ".\"$label_fields[$#label_fields]\"" if ($cmd);
-       $_ = $pre_preitems . $preitems . $_ if ($pre_preitems||$preitems);
-    } else {
-       @enum_default_type = ('A', '1', 'a', 'i', 'A') unless (@enum_default_type);
-       $enum_type = $enum_level%4;
-       $enum_type = ' Type="'.@enum_default_type[$enum_type].'"';
-    }
-
-    # enclose contents of user-defined labels within a group,
-    # in case of style-change commands, which could bleed outside the label.
-    &protect_useritems($_);
-    $_ = &translate_environments($_);  #catch nested lists
-
-    local($enum_result);
-    if (($standard_label)||(/\\item\[/)) {
-       # split it into items
-       @items = split(/\\item\b/,$_);
-       # save anything (non-blank) before the items actually start
-       $preitems = shift(@items);
-       $preitems =~ s/^\s*$//;
-       local($enum_label);
-       # prepend each item with an item label: \item => \item[<label>]
-       foreach $item (@items) {
-#        unless ( $item =~ /^\s*$/ ) { # first line may be empty
-           $enum{"enum" . $rlevel}++;  # increase enumi
-           $enum_label = eval("$enum{'labelenum' . $rlevel}");
-           # insert a label, removing preceding space, BUT...
-           # do NOT handle items with existing labels
-           $item =~ s/^\s*//;
-           if ($item =~ s/^\s*\[([^]]*)\]//) {
-               $enum{"enum" . $rlevel}--;
-               $enum_label = "$1";
-               local($processed) = ($enum_label =~/$OP/);
-               $enum_label = join('',($processed ? "<#0#>" : "<<0>>")
-                   ,$enum_label ,($processed ? "<#0#>" : "<<0>>"))
-                       if ($enum_label =~ /\\/);
-               if ($processed) { &make_unique_p($enum_label) }
-               elsif ($enum_label =~ /$O/) { &make_unique($enum_label) };
-               $item = "[${enum_label}]".$item;
-           } else { 
-               local($processed) = ($enum_label =~/$OP/);
-               $enum_label = join('',($processed ? "<#0#>" : "<<0>>")
-                   ,$enum_label ,($processed ? "<#0#>" : "<<0>>"))
-                       if ($enum_label =~ /\\/);
-               if ($processed) { &make_unique_p($enum_label) }
-               elsif ($enum_label =~ /$O/) { &make_unique($enum_label) };
-               $item = "[$enum_label\]$item";
-               $enum_label =~ s/\.$//;
-           }
-           if ($standard_label) {
-               $item =~ s/(\\labelitem$rlevel|$standard_label)/$enum_label/g
-           } else {
-               $item =~ s/(\\labelitem$rlevel)/$enum_label/g
-           }
-       };
-       $_ = join("\\item ", $preitems, @items);
-
-       # Original, but $enum_result
-       $enum_result = &do_env_description($_, " COMPACT");
-    } else {
-       $enum_result = &list_helper($_, "OL$enum_type", '', '');
-    }
-
-    #clean-up and revert the $enum_level
-    $enum{"enum" . $rlevel} = 0;
-    $enum{"enum" . &froman($enum_level)} = 0;
-    --$enum_level;
-    $enum_result;
-}
-
-sub do_env_list {
-    local ($_) = @_;
-    local ($list_type,$labels,$lengths) = ('UL','','');
-
-    $labels = &missing_braces unless    ( # get the label specifier
-       (s/$next_pair_pr_rx/$labels=$2;''/e)
-       ||(s/$next_pair_rx/$labels=$2;''/e));
-
-    $lengths = &missing_braces unless ( # get the length declarations
-       (s/$next_pair_pr_rx/$lengths=$2;''/e)
-       ||(s/$next_pair_rx/$lengths=$2;''/e));
-    # switch to enumerated style if they include a \usecounter.
-    $list_type = 'OL' if $lengths =~ /\\usecounter/;
-
-    /\\item\b/; local($preitems) = $`;
-       $_ =~ s/^\Q$preamble//s if ($preitems);
-    $preitems =~s/^\s*|\s*$//g;
-    if ($preitems) {
-       $preitems = &translate_environments($preitems);
-       $preitems = &translate_commands($preitems) if ($preitems =~ /\\/);
-#      &write_warnings("\nDiscarding: $preitems before 1st item in list")
-#          if ($preitems);
-    }
-
-    #RRM - catch nested lists
-    #RRM unfortunately any uses of the \\usecounter  within \item s
-    #    may be broken --- sigh.
-    &protect_useritems($_);
-    $_ = &translate_environments($_);
-
-    if (($list_type =~ /OL/)&&($labels)) {
-       local($br_ida,$br_idb,$label,$aft);
-       $br_ida = ++$global{'max_id'};
-       $lengths =~ s/\\usecounter((($O|$OP)\d+($C|$CP))[^<]+\2)/
-               &make_nowrapper(1)."\\stepcounter$1".&make_nowrapper(0)/e;
-       $labels = "$O$br_ida$C$lengths$O$br_ida$C".$labels;
-
-#      s/\\item\b\s*([^\[])/do {
-#              $label = $labels; $aft = $1;
-#              $br_id = ++$global{'max_id'};
-#              $label = &translate_environments(
-#                      "$O$br_id$C$label$O$br_id$C");
-#              join('',"\\item\[" , $label, "\]$aft" );
-#          }/eg;
-#      $labels ='';
-    }
-
-    if (($labels)||(/\\item\[/)) {
-       $_ = &list_helper($_, 'DL', $labels, $lengths)
-    } else {
-       $_ = &list_helper($_, $list_type, '', $lengths)
-    }
-    $_;
-}
-
-sub do_env_trivlist {
-    local($_) = @_;
-    local($compact,$item_sep,$pre_items) = ' COMPACT';
-    &protect_useritems($_);
-
-    # assume no styles initially for this list
-    local($close_tags,$reopens) = &close_all_tags();
-    local($open_tags_R) = [];
-    local(@save_open_tags) = ();
-
-    # include \label anchors from [...] items
-    s/$item_description_rx\s*($labels_rx8)?\s*/
-       (($9)? "<A NAME=\"$9\">$1<\/A>" : $1 ) ."\n"/eg;
-    # remove unwanted space before \item s
-    s/[ \t]*\\item\b/\\item/g;
-    
-    local($this_item,$br_id) = ('','');
-    local($this_sitem,$this_eitem) = ("\n<P>","</P>\n",'');
-
-    # assume no sub-lists, else...  why use {trivlist} ?
-    # extract up to the 1st \item
-    local(@items) = split(/\\item\b/, $_);
-    $pre_items = shift @items;
-    $_ = '';
-    while (@items) {
-       $br_id = ++$global{'max_id'};
-       $this_item = shift @items;
-       $this_item = &translate_environments(
-            "$O$br_id$C".$pre_items.$this_item."$O$br_id$C" );
-       if ($this_item =~ /\\/) {
-           $this_item = &translate_commands($this_item);
-           $_ .= join('' , $this_sitem 
-                      , $this_item
-                      # , $this_eitem
-                      )
-       } else { $_ .= $this_sitem . $this_item }
-    }
-       
-    $_ = &translate_environments($_);
-    $_ = &translate_commands($_);
-
-    join('' , $close_tags , $_ , $reopens);
-
-}
-
-# enclose the contents of any user-defined labels within a group,
-# else any style-change commands may bleed outside the label.
-sub protect_useritems {
-    # MRO: use $_[0] instead: local(*_) = @_;
-    local($preitems, $thisitem);
-    $_[0] =~ s/^$par_rx\s*//s; # discard any \par before 1st item
-
-    # locate \item with optional argument 
-    local($saveRS) = $/; undef $/;
-    local(@preitems);
-    # allow one level of nested []
-    # MRO: Caution! We have a double-wildcarded RX here, this may cause
-    # trouble. Should be re-coded.
-    $_[0] =~ s/\\item[\s\r]*(\b(\[(([^\[\]]|\[[^]]*\])*)\])?|[^a-zA-Z\s])/
-       $thisitem = " $1";
-       if ($2) {
-           $br_id = ++$global{'max_id'};
-           $thisitem = '['.$O.$br_id.$C.$3.$O.$br_id.$C.']';
-       };
-       "\\item".$thisitem
-    /egm;
-
-    $/ = $saveRS;
-    $_[0] = join(@preitems, $_[0]);
-}
-
-sub do_env_description {
-    local($_, $compact, $bullet) = @_;
-    #RRM - catch nested lists
-    &protect_useritems($_);
-    $_ = &translate_environments($_) unless ($bullet);
-
-    # MRO: replaced $* with /m
-    $compact = "" unless $compact;
-    if ($compact) {            # itemize/enumerate with optional labels
-       s/\n?$item_description_rx\s*($labels_rx8)?\s*/"\n<\/DD>\n<DT>". 
-           (($9)? "<A NAME=\"$9\">$1<\/A>" : $1 ) ."<\/DT>\n<DD>"/egm;
-    } else {
-       s/\n?$item_description_rx\s*($labels_rx8)?\s*/"\n<\/DD>\n<DT>". 
-           (($9)? "<A NAME=\"$9\"><STRONG>$1<\/STRONG><\/A>" 
-            : "<STRONG>$1<\/STRONG>") ."<\/DT>\n<DD>"/egm;
-    }
-    # and just in case the description is empty ...
-#JCL(jcl-del) - $delimiter_rx -> ^$letters
-    s/\n?\\item\b\s*([^$letters\\]|)\s*/\n<\/DD>\n<DT>$bullet<\/DT>\n<DD>$1/gm;
-    s/^\s+//m;
-
-    $_ = '<DD>'.$_ unless ($_ =~ s/^\s*<\/D(T|D)>\n?//s);
-    $_ =~ s/\n$//s;
-    "<DL$compact>\n$_\n</DD>\n</DL>";
-}
-
-sub list_helper {
-    local($_, $tag, $labels, $lengths) = @_;
-    local($item_sep,$pre_items,$compact,$etag,$ctag);
-    $ctag = $tag; $ctag =~ s/^(.*)\s.*$/$1/;
-
-    # assume no styles initially for this list
-    local($close_tags,$reopens) = &close_all_tags();
-    local($open_tags_R) = [];
-    local(@save_open_tags) = ();
-
-#    #RRM: cannot have anything before the first <LI>
-#    local($savedRS) = $/; $/='';
-#    $_ =~ /\\item[\b\r]/s;
-#    if ($`) { 
-#      $preitems = $`; $_ = $&.$';
-#      $preitems =~ s/<P( [^>]*)?>//g;
-#      $close_tags .= "\n".$preitems if $preitems;
-#    }
-#    $/ = $savedRS; 
-#
-
-    $* = 1;                    # Multiline matching ON
-    if (($tag =~ /DL/)&&$labels) {
-       local($label,$aft,$br_id);
-       s/\\item\b[\s\r]*([^\[])/do {
-               $label = $labels; $aft = $1;
-               $br_id = ++$global{'max_id'};
-               $label = &translate_environments(
-                       "$O$br_id$C$label$O$br_id$C");
-               join('',"\\item\[" , $label, "\]$aft" );
-           }/eg;
-    }
-    $* = 0;                    # Multiline matching OFF
-
-    # This deals with \item[xxx] ...
-    if ($tag =~ /DL/) {
-       $compact = ' COMPACT';
-       # include \label anchors in the <DT> part
-       # and  $pre_item  tags in the <DD> part:
-       if ($labels && $lengths) { 
-           $item_sep = "\n</DD>\n<DT>";
-       } else {
-           $item_sep = ($labels ? "<DT>$labels\n" : '') ."</DT>\n<DD>";
-       }
-       $etag = "\n</DD>";
-       s/$item_description_rx[\r\s]*($labels_rx8)?[\r\s]*/"<DT>" .
-           (($9)? "<A NAME=\"$9\">$1<\/A>" : $1 ) ."\n<DD>"/egm;
-    } else {
-       $item_sep = "\n</LI>\n<LI>";
-       $etag = "\n</LI>";
-    }
-
-    # remove unwanted space before \item s
-    s/[ \t]*\\item\b/\\item/gm;
-
-    #JCL(jcl-del) - $delimiter_rx -> ^$letters
-    s/\n?\\item\b[\r\s]*/$item_sep/egm;
-
-    #RRM: cannot have anything before the first <LI>
-    local($savedRS) = $/; $/='';
-    $_ =~ /\Q$item_sep\E|<DT>|<LI>/s;
-    #RRM: ...try putting it before the list-open tag
-    if ($`) { 
-       $preitems = $`; $_ = $&.$';
-       $preitems =~ s/<P( [^>]*)?>//gm;
-       $close_tags .= "\n".$preitems if $preitems;
-    }
-    $_ =~ s/^\s*<\/[^>]+>\s*//s;
-
-    # remove \n from end of the last item
-    $_ =~ s/\n$//s;
-    $/ = $savedRS;
-
-    join('' , $close_tags , "\n<$tag$compact>\n" 
-        , $_ , "$etag\n</$ctag>" , $reopens);
-}
-
-
-# RRM:  A figure environment generates a picture UNLESS it contains a 
-# {makeimage} sub-environment; in which case it creates a <DIV>
-# inside which the contents are interpreted as much as is possible.
-# When there are captions, this modifies $before .
-sub do_env_figure {
-    local($_) = @_;
-    local($halign, $anchors) = ('CENTER','');
-    local ($border, $attribs );
-    local($cap_width) = $cap_width;
-    my ($opt, $dummy) = &get_next_optional_argument;
-
-    my $abovedisplay_space = $ABOVE_DISPLAY_SPACE||"<P></P>\n";
-    my $belowdisplay_space = $BELOW_DISPLAY_SPACE||"<P></P>\n";
-
-    ($_,$anchors) = &extract_labels($_); # extract labels
-    # Try to establish the alignment
-    if (/^(\[[^\]]*])?\s*\\begin\s*<<\d*>>(\w*)<<\d*>>|\\(\w*)line/) {
-       $halign = $2.$3;
-       if ($halign =~ /right/i)  { $halign = 'RIGHT' }
-       elsif ($halign =~ /left/i) { $halign = 'LEFT' }
-       elsif ($halign =~ /center/i) { $halign = 'CENTER' }
-       else { $halign = 'CENTER' }
-    }
-
-    # allow caption-alignment to be variable
-    local($cap_align);
-    if ($FIGURE_CAPTION_ALIGN =~ /^(TOP|BOTTOM|LEFT|RIGHT)/i) {
-       $cap_align = join('', ' ALIGN="', $&, $','"')};  
-
-    local($cap_env, $captions,$has_minipage) = ('figure','');
-    if ((/\\begin\s*($O\d+$C)\s*(makeimage|minipage)\s*\1|\\docode/)||
-       (/\\includegraphics/&&(!/$htmlborder_rx|$htmlborder_pr_rx|\\htmlimage/))){
-       $has_minipage = ($2 =~ /minipage/sg );
-       $_ = &translate_environments($_);
-       if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-       elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-       do { local($contents) = $_;
-           &extract_captions($cap_env); $_ = $contents;
-       } if (/\\caption/);
-       $_ = &translate_commands($_);
-       while ($_ =~ s/(^\s*<BR>\s*|\s*<BR>\s*$)//sg){}; # remove unneeded breaks
-    } else {
-       do { local($contents) = $_;
-           # MRO: no effect: &extract_captions($cap_env, *cap_width); $_ = $contents;
-           &extract_captions($cap_env); $_ = $contents;
-       } if (/\\caption/);
-       # Generate picture of the whole environment
-       if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-       elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-       $_ = &process_undefined_environment($env, $id, $_);
-       $_ = &post_latex_do_env_figure($_);
-       $_ =~ s/\s*<BR>\s*$//g;
-    }
-
-    if ($captions) {
-        # MRO: replaced $* with /m
-        $captions =~ s/^\n//m;
-        $captions =~ s/\n$//m;
-    }
-    s/$caption_mark//g;
-
-    local($close_tags) = &close_all_tags;
-    $_ .= $close_tags;
-
-    # place all the pieces inside a TABLE, if available
-    if ($HTML_VERSION > 2.1) {
-       if ($captions) {
-           local($pxs,$len) = &convert_length($cap_width,$MATH_SCALE_FACTOR)
-               if $cap_width;
-           local($table) = "<TABLE$env_id"; # WIDTH="65%"';
-           $table .= " WIDTH=\"$pxs\"" if ($pxs);
-           if ($border) { $table .= " BORDER=\"$border\"" } # no checking !!
-           $table .= ">";
-           s/^\s*|\s*$//g;
-           join (''
-                   , $above_display_space
-                   , "\n<DIV", ($halign ? " ALIGN=\"$halign\"" :'')
-                   , '>', $anchors , $cap_anchors
-                   , "\n$table\n<CAPTION", $cap_align, '>'
-                   , $captions , "</CAPTION>\n<TR><TD>"
-                   , ($cap_width ? '</TD><TD>' : '')
-                   , $_ , '</TD>'
-                   , ($cap_width ? '<TD></TD>' : '')
-                   , "</TR>\n</TABLE>\n</DIV>\n"
-                   , $below_display_space
-           )
-       } elsif ($halign) {
-           if ($border||($attributes)||$env_id) {
-               &make_table( $border, $attribs, $anchors, '', $halign, $_ );
-           } else {
-               join (''
-                       , $above_display_space
-                       , "\n<DIV ALIGN=\"$halign\">\n"
-                       , ($anchors ? "\n<P>$anchors</P>" : '')
-                       , $_
-                       , "\n</DIV>"
-                       , $below_display_space
-               )
-           }
-       } else {
-           if ($border||($attributes)||$env_id) {
-               join (''
-                       , $above_display_space
-                       , "\n<DIV", ($halign ? " ALIGN=\"$halign\"":'')
-                       , '>'
-                       , &make_table( $border, $attribs, $anchors, '', $halign, $_ )
-                       , "\n</DIV><BR"
-                       , (($HTML_VERSION > 3.1)? " CLEAR=\"ALL\"" :'')
-                       , '>'
-                       , $below_display_space
-               );
-           } else {  
-               join (''
-                       , $above_display_space
-                       , "\n<DIV", ($halign ? " ALIGN=\"$halign\"":'')
-                       , ">$anchors\n" , $_ , "\n</DIV><BR"
-                       , (($HTML_VERSION > 3.1)? " CLEAR=\"ALL\"" :'')
-                       , '>'
-                       , $below_display_space
-               );
-           }
-       }
-    } else {
-       # MRO: replaced $* with /m
-        s/^\n//m;
-        s/\n$//m;
-       if ($captions) {
-           join('', "\n<BR>\n", (($anchors) ? "$anchors" : '')
-               , "$cap_anchors\n$captions\n<BR>" 
-               , "\n<P", ($halign ? " ALIGN=\"$halign\"":'')
-               , '>', $_ , "\n</P>");
-       } elsif ($halign) {
-           join ('', "<BR>\n$anchors", $_ , "\n<BR>" )
-       } else {
-           join('', "<BR>\n<P", ($halign ? " ALIGN=\"$halign\"":'')
-               , ">$anchors\n" , $_ , "\n</P><BR>");
-       }
-    }
-}
-
-sub do_env_figurestar { &do_env_figure(@_) }
-
-sub do_env_table {
-    local($_) = @_;
-    local($halign, $anchors) = ('','');
-    local ( $border, $attribs );
-    &get_next_optional_argument;
-
-    # Try to establish the alignment 
-    if (/^(\[[^\]]*])?\s*\\begin\s*<<\d*>>(\w*)<<\d*>>|\\(\w*)line/) {
-       $halign = $2.$3;
-       if ($halign =~ /right/i)  { $halign = 'RIGHT' }
-       elsif ($halign =~ /left/i) { $halign = 'LEFT' }
-       elsif ($halign =~ /center/i) { $halign = 'CENTER' }
-       else { $halign = '' }
-    }
-
-    local($cap_env, $captions) = ('table','');
-
-    # allow caption-alignment to be variable
-    local($cap_align);
-    if ($TABLE_CAPTION_ALIGN =~ /^(TOP|BOTTOM|LEFT|RIGHT)/i) {
-       $cap_align = join('', ' ALIGN="', $&, $','"')};  
-
-    if ((/\\(begin|end)\s*($O\d+$C)\s*makeimage\s*\2/)||
-           ($HTML_VERSION > 2.0 && (
-               /\\begin\s*($O\d+$C)\s*((super)?tabular|longtable)\s*\1/))) {
-       $_ = &translate_environments($_);
-       ($_,$anchors) = &extract_labels($_); # extract labels
-       do { local($contents) = $_;
-           &extract_captions($cap_env); $_ = $contents;
-       } if (/\\caption/);
-       if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-       elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-       $_ = &translate_commands($_);
-       while ($_ =~ s/(^\s*<BR>\s*|\s*<BR>\s*$)//g){};
-    } else {
-       # Make an image of the whole environment.
-       ($_,$anchors) = &extract_labels($_); # extract labels
-       do { local($contents) = $_;
-           &extract_captions($cap_env); $_ = $contents;
-       } if (/\\caption/);
-       if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-       elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-       $_ = &process_undefined_environment($env, $id, $_);
-       $_ = &post_latex_do_env_table($_);
-       $_ =~ s/\s*<BR>\s*$//g;
-    }
-
-    if ($captions) {
-        # MRO: replaced $* with /m
-        $captions =~ s/^\n//m;
-        $captions =~ s/\n$//m;
-    }
-    s/$caption_mark//g;
-
-    local($close_tags) = &close_all_tags;
-    $_ .= $close_tags;
-
-    #  when $captions remain place all the pieces inside a TABLE, if available
-    if ($HTML_VERSION > 2.1) {
-       if ($captions) {
-           $halign = 'CENTER' unless $halign;
-           local($table) = '<TABLE';
-           if ($border) { $table .= " BORDER=\"$border\"" } # no checking !!
-           $table .= ">";
-           join ('', "<BR><P></P>\n<DIV$env_id ALIGN=\"$halign\">"
-               , "$anchors$cap_anchors\n$table\n<CAPTION", $cap_align, '>'
-               , $captions , "</CAPTION>\n<TR><TD>"
-               , $_ , "</TD></TR>\n</TABLE>\n</DIV><P></P><BR>" )
-       } elsif ($halign) {
-           if ($halign) {
-               # MRO: replaced $* with /m
-               s/^\s*(<(P|DIV)$env_id ALIGN=\"\w+[^>]+>)/$1$anchors/m
-                    if ($anchors);
-               join('', "<BR>", $_, "\n<BR>" )
-           } else {
-               join ('', "<BR>\n$anchors", $_ , "\n<BR>" )
-           }
-        } else {
-            join ('', "<BR><P></P>\n<DIV$env_id ALIGN=\"CENTER\">$anchors\n", $_ , "\n</DIV><BR>" )
-        }
-    } else {
-        # MRO: replaced $* with /m
-        s/^\n//m;
-        s/\n$//m;
-        if ($captions) {
-            join('', "<BR>\n", (($anchors) ? "$anchors" : ''), "$cap_anchors\n$captions\n<BR>"
-                , "\n<P ALIGN=\"$halign\">", $_, "\n</P><BR>");
-        } elsif ($halign) {
-            join ('', "<BR><P></P>\n$anchors", $_ , "\n<P></P>" )
-        } else {
-            join('', "<BR>\n<P ALIGN=\"CENTER\">$anchors\n", $_, "\n</P><BR>");
-        }
-    }
-}
-
-sub do_env_tablestar { &do_env_table(@_) }
-
-# RRM:  A makeimage environment generates a picture of its entire contents, 
-#  UNLESS it is empty.
-#
-sub do_env_makeimage {
-    local($_) = @_;
-    local($attribs, $border);
-    s/^\s*//;
-    if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-    elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-    if (/^((\\begin\s*(($O|$OP)\d+($C|$CP))tex2html_deferred\3)?\\par(\\end(($O|$OP)\d+($C|$CP))tex2html_deferred\7)?\%?\s*\n)+$/s) { return("\n<BR>\n") }
-    if (/^(\s\%?\n)+$/s) { return() }
-    $_ = &process_undefined_environment($env, $id, $_);
-    if (($border||($attributes))&&($HTML_VERSION > 2.1 ))
-       { $_ = &make_table( $border, $attribs, '', '', '', $_ ) }
-    $_ . ((!$_=~/^\s*$/)? "\n<BR>\n" :'');
-}
-
-sub do_env_abstract { &make_abstract($_[0]) }
-
-sub do_env_minipage {
-    local($_) = @_;
-    &get_next_optional_argument;
-    local($width);
-    $width = &missing_braces unless (
-       (s/$next_pair_pr_rx/$width=$2;''/e)
-       ||(s/$next_pair_rx/$width=$2;''/e));
-    local($pxs,$len) = &convert_length($width,$MATH_SCALE_FACTOR) if $width;
-    $width = " WIDTH=\"$pxs\"";
-    
-    local ( %mpfootnotes, $mpfootnotes ) unless ($MINIPAGE);
-    local ( $border, $attribs, $footfile);
-    $global{'mpfootnote'} = 0 unless ($MINIPAGE);
-    $MINIPAGE++;
-    print "\n *** doing minipage *** " if ($VERBOSITY > 1);
-    local($open_tags_R) = [ @$open_tags_R ];
-    local($close_tags,$reopens) = &close_all_tags();
-    local(@save_open_tags) = @$open_tags_R;
-   
-    local($minipage_caption) if $cap_env;
-    if ($cap_env &&($HTML_VERSION>2.1)) {
-       do {
-           local($captions);
-           local($contents) = $_;
-           &extract_captions($cap_env) if ($_ =~ /\\caption/m);
-           $minipage_caption = $captions;
-           $_ = $contents;
-           undef $contents; undef $captions;
-       };
-    }
-
-    if (s/^\s*$htmlborder_rx//so) {
-       $attribs = $2; $border = (($4)? "$4" : 1)
-    } elsif (s/^\s*$htmlborder_pr_rx//so) {
-       $attribs = $2; $border = (($4)? "$4" : 1)
-    }
-    if (/^\s*\\/) {
-       local($tmp) = ++$global{'max_id'};
-       $_ = $O.$tmp.$C.$_.$O.$tmp.$C
-    }
-    $_ = &translate_environments($_);
-    if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-    elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-    $_ = &translate_commands($_);
-    $MINIPAGE--; $MINIPAGE='' if ($MINIPAGE==0);
-
-    $_ .= &balance_tags();
-    $attribs .= $width unless ($attribs =~ /WIDTH/i);
-#    if (($border||$attribs)&&$MINIPAGE&&($HTML_VERSION>2.1)) { 
-    if (($border||$attribs||$env_id)&&$MINIPAGE&&($HTML_VERSION>2.1)) { 
-       $_ = &make_table( $border, $attribs, '', '', '', $_ );
-    } elsif ($MINIPAGE) { 
-       $_ = join ('', '<BR><HR>', $_ , '<BR><HR><BR>' );
-    } elsif (($border||($attribs)||$minipage_caption)&&($HTML_VERSION > 2.1 )) {
-       $mpfootnotes = '<DL>'.$mpfootnotes.'</DL>' if $mpfootnotes;
-       $_ = &make_table( $border, $attribs, '', $mpfootnotes, '', $_ );
-       $_ = join('','<BR><HR'
-               , (($HTML_VERSION > 3.0)? ' WIDTH="50\%" ALIGN="CENTER"' : '')
-               , '>', $_ , '<BR><HR'
-               , (($HTML_VERSION > 3.0)? ' WIDTH="50\%" ALIGN="CENTER"' : '')
-               , '><BR>') unless ($border||$attribs||$mpfootnotes);
-    } else {
-       $global{'mpfootnote'} = 0;
-       if ($mpfootnotes) {
-           $mpfootnotes = '<DD>'.$mpfootnotes unless ($mpfootnotes =~ /^\s*<D(T|D)>/);
-           $_ = join('','<BR><HR>', $_ , '<BR><HR'
-               , (($HTML_VERSION > 3.0)? ' WIDTH="200" ALIGN="LEFT"' : '')
-               , '><DL>', $mpfootnotes , '</DL><HR><BR'
-               , (($HTML_VERSION > 3.0)? ' CLEAR="all"' : '')
-               , '>' );
-       } else {
-           $_ = join ('', '<BR><HR><P></P>', $_ , '<BR><HR><BR>' );
-       }
-    }
-    join('', $close_tags, $_, $reopens);
-}
-
-if (($HTML_VERSION > 2.1)&&($HTML_VERSION < 4.0)) {
-    $TABLE_attribs = ",ALIGN,";
-    $TABLE__ALIGN = ",left,right,center,";
-    $TABLE_attribs_rx_list = ",CELLPADDING,BORDER,WIDTH,CELLSPACING,";
-    $TABLE__WIDTH_rx = "\^\\d+%?";
-    $TABLE__BORDER_rx = $TABLE__CELLSPACING_rx = $TABLE__CELLPADDING_rx = "\^\\d+";
-}
-
-sub make_table {
-    local($border, $attribs, $anchors, $extra_cell, $halign, $_) = @_;
-    local($table,$caption,$div,$end,$Tattribs);
-    $caption = join('',"<CAPTION$cap_align>"
-       , $minipage_caption
-       ,'</CAPTION>') if ($minipage_caption);
-    $end = "</TD></TR>\n</TABLE>";
-    $table = join('', "<TABLE$env_id"
-       , ((($caption)&&!($attribs =~/WIDTH/i)) ? " WIDTH=\"100\%\"" : '')
-       , ((($border)&&!($attribs =~/BORDER/i)) ? " BORDER=\"$border\"" : '')
-       );
-    if ($attribs) {
-       if (!($attribs =~ /=/)) {
-           $Tattribs = &parse_valuesonly($attribs,"TABLE");
-       } else {
-           $Tattribs = &parse_keyvalues($attribs,"TABLE");
-       }
-       $table .= " $Tattribs" if ($Tattribs);
-    }
-    print STDOUT "\nTABLE: $table>" if ($VERBOSITY >2 );
-    $table .= ">".$caption."\n<TR><TD>";
-    if ($extra_cell) {
-       local($sep) = "</TD></TR>\n<TR ALIGN=\"LEFT\">\n<TD>";
-       join ('', $div, $anchors, $table, $_ , $sep, $extra_cell, $end );
-    } else {
-       join ('', $div, $anchors, $table, $_ , $end );
-    }
-}
-
-sub do_cmd_etalchar {
-    local($_) = @_;
-    my $etalchar;
-    $etalchar = &missing_braces unless (
-       (s/$next_pair_pr_rx/$etalchar = $2;''/eo)
-       ||(s/$next_pair_rx/$etalchar = $2;''/eo));
-    $etalchar = &translate_commands($etalchar) if ($etalchar =~ /\\/);
-    if ($HTML_VERSION < 3.0) {
-       $etalchar = &process_in_latex("\$^\{$etalchar\}\$");
-    } else {
-       $etalchar = '<SUP>'.$etalchar.'</SUP>';
-    }
-    $etalchar . $_
-}
-
-sub do_env_thebibliography {
-    # Sets $citefile and $citations defined in translate
-    local($_) = @_;
-    $bibitem_counter = 0;
-    $citefile = $CURRENT_FILE;
-    $citefiles{$bbl_nr} = $citefile;
-    local($dummy,$title);
-    $dummy = &missing_braces unless (
-       (s/$next_pair_pr_rx/$dummy=$2;''/e)
-       ||(s/$next_pair_rx/$dummy=$2;''/e));
-    # MRO: replaced $* with /m
-    s/^\s*$//gm; # Remove empty lines (otherwise will have paragraphs!)
-    s/^\s*//m;
-
-    # Replace non-breaking spaces, particularly in author names.
-#    s/([^\\])~/$1 /g; # Replace non-breaking spaces.
-
-    $_ = &translate_environments($_);
-    $_ = &translate_commands($_);
-
-    # RRM: collect all anchors from initial \label and \index commands
-    local($anchors) = &extract_anchors('',1);
-    $_ = '<DD>'.$_ unless ($_ =~ /^\s*<D(T|D)>/);
-    $citations = join('',"<DL COMPACT>", $_, "</DL>");
-    $citations{$bbl_nr} = $citations;
-    local($br_id);
-    if ((defined &do_cmd_bibname)||$new_command{'bibname'}) {
-       $br_id=++$global{'max_id'};
-       $title = &translate_environments("$O$br_id$C\\bibname$O$br_id$C");
-    } else { $title = $bib_title }
-    if (! $title ) {
-       if ((defined &do_cmd_refname)||$new_command{'refname'}) {
-           $br_id=++$global{'max_id'};
-           $title = &translate_environments("$O$br_id$C\\refname$O$br_id$C");
-       } else { $title = $ref_name }
-    }
-    local($closures,$reopens) = &preserve_open_tags();
-    $toc_sec_title = $title ;
-    local $bib_head = $section_headings{'bibliography'};
-    $_ = join('', $closures
-           , &make_section_heading($title, $bib_head, $anchors)
-           , "$bbl_mark#$bbl_nr#" , $reopens );
-    $bbl_nr++ if $bbl_cnt > 1;
-    $_ =~ s/;SPMnbsp;/ /g;  # replace non-breaking spaces with real ones
-    $_;
-}
-
-# IGNORE - We construct our own index
-sub do_env_theindex { "" }
-
-# This is defined in html.sty
-sub do_env_comment { "" }
-
-
-sub do_env_equation{
-    local($_)=@_;  
-    local($attribs, $border, $no_num);
-    if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-    elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-    if (/\\nonumber/) {
-       $no_num = 1;
-       $_ = &process_undefined_environment($env,$id,$_);
-    } else {
-       $latex_body .= join('', "\n\\setcounter{equation}{"
-                       , $global{'eqn_number'}, "}\n");
-
-       #include equation-number into the key, with HTML 2.0
-#      $_ = join("\n", "%EQNO:".$global{'eqn_number'}, $_)
-       $_ .= "%EQNO:".$global{'eqn_number'}."\n" if ($HTML_VERSION < 2.2);
-
-       $_ = &process_undefined_environment($env,$id,$_);
-       $global{'eqn_number'}++;
-       local($save) = $_;
-       $_ = join('', $save, &post_latex_do_env_equation($eqno_prefix));
-    }
-    if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 
-       join('',"<BR>\n<DIV$env_id ALIGN=\"CENTER\">\n"
-           , &make_table( $border, $attribs, '', '', '', $_ )
-           , "\n<BR CLEAR=\"ALL\">");
-    } elsif ($HTML_VERSION < 2.2 ) { 
-       join('', "\n<P>", $_ , "\n<BR></P>" )
-    } elsif ($HTML_VERSION > 2.1 ) { 
-       join('', "\n<P ALIGN="
-           , ((!$no_num &&($EQN_TAGS =~ /L/))?
-               '"LEFT"':($no_num ?'"CENTER"':'"RIGHT"'))
-           , '>', $_ , "\n<BR></P>" )
-    } else { $_ }
-}
-
-sub do_env_eqnarray{
-    local($_)=@_;
-    local($attribs, $border, $no_num);
-    if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-    elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-    local($contents) = $_;
-#    $_ = join("\n", "%EQNO:".$global{'eqn_number'}, $_)
-#      if ($HTML_VERSION < 3.2);  #include equation-number into the key.
-    $_ .= "%EQNO:".$global{'eqn_number'}."\n" if ($HTML_VERSION < 2.2);
-    $_ = &process_undefined_environment($env,$id,$_);
-    $_ .= &post_latex_do_env_eqnarray($eqno_prefix,$contents);
-    if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 
-       join('',"<BR>\n<DIV ALIGN=\"CENTER\">\n"
-            , &make_table( $border, $attribs, '', '', '', $_ )
-           , "\n<BR CLEAR=\"ALL\">");
-    } elsif ($HTML_VERSION < 2.2 ) { 
-       join('', "\n<P>", $_ , "\n<BR></P>" )
-    } elsif ($HTML_VERSION > 3.1 ) { 
-       join('',"<BR>\n<DIV ALIGN=\"CENTER\">\n", $_ 
-            , "\n</DIV><BR CLEAR=\"ALL\">" );
-    } else {
-       join('', "\n<P ALIGN="
-            , (($EQN_TAGS =~ /L/)? '"LEFT"' : '"RIGHT"')
-            , '>' , $_ , "\n<BR></P>" )
-    }
-}
-
-#RRM: these are needed with later versions, when {eqnarray}
-#  environments are split into <TABLE> cells.
-
-sub protect_array_envs {
-    local($_) = @_;
-    local($cnt, $arraybit, $thisbit, $which) = (0,'','','');
-    # MRO: replaced $* with /m
-    while (/\\(begin|end)\s*(<(<|#)\d+(#|>)>)($sub_array_env_rx)(\*|star)?\2/m ) {
-        $thisbit = $` . $&; $_ = $'; $which = $1;
-        do {
-            # mark rows/columns in nested arrays
-            $thisbit =~ s/;SPMamp;/$array_col_mark/g;
-            $thisbit =~ s/\\\\/$array_row_mark/g;
-            $thisbit =~ s/\\text/$array_text_mark/g;
-            $thisbit =~ s/\\mbox/$array_mbox_mark/g;
-        } if ($cnt > 0);
-        $arraybit .= $thisbit;
-        if ($which =~ /begin/) {$cnt++} else {$cnt--};
-    }
-    $_ = $arraybit . $_;
-
-    local($presub,$thisstack) = '';
-    for (;;) {
-      # find \\s needing protection within \substack commands
-      # a while-loop is simpler syntax, but uses longer strings
-      if ( /(\\substack\s*(<(<|#)\d+(#|>)>)(.|\n)*)\\\\((.|\n)*\2)/m ) {
-        $presub .= $`; $thisstack =$1.${array_row_mark}.$6; $_ = $';
-        # convert all \\s in the \substack
-        $thisstack =~ s/\\\\/${array_row_mark}/og;
-        $presub .= $thisstack;
-        } else { last }
-    }
-    $_ = $presub . $_ if ($presub);
-    $_;
-}
-
-sub revert_array_envs {
-    local($array_contents) = @_;
-    $array_contents =~ s/$array_col_mark/$html_specials{'&'}/go;
-    $array_contents =~ s/$array_row_mark/\\\\/go;
-    $array_contents =~ s/$array_text_mark/\\text/go;
-    $array_contents =~ s/$array_mbox_mark/\\mbox/go;
-    $array_contents;
-}
-
-
-
-sub do_env_tabbing {
-    local($_) = @_;
-    local($attribs, $border);
-    if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-    elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
-    $_ = &tabbing_helper($_);
-    if (/$image_mark/) {
-       local($tab_warning) = 
-          "*** Images are not strictly valid within HTML <pre> tags\n"
-          . "Please change your use of {tabbing} to a {tabular} environment.\n\n";
-          &write_warnings("\n".$tab_warning);
-          print "\n\n **** invalid tabbing environment ***\n";
-          print $tab_warning;
-    }
-    if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 
-       join('',"<BR>\n<DIV$env_id ALIGN=\"CENTER\">\n"
-            , &make_table( $border, $attribs, '', '', '', $_ )
-           , "\n</DIV><BR CLEAR=\"ALL\">");
-    } else { $_ }
-}
-
-sub tabbing_helper {
-    local($_) = @_;
-    s/\\=\s*//go;  # cannot alter the tab-stops
-    s/\t/ /g;      # convert any tabs to spaces
-    # MRO: replaced $* with /m
-    s/(^|\n)[^\n]*\\kill *\n/\n/gm;
-    s/( )? *\n/$1/gm; # retain at most 1 space for a \n
-    # replace \\ by \n ... , ignoring any trailing space
-#    s/\\\\ */\n/gm;
-    # ...but make sure successive \\ do not generate a <P> tag
-#    s/\n( *)?\n/\n&nbsp;\n/gm;
-    s/\\\&gt;//go;
-    s/(^| *([^\\]))\\[>]/$2\t\t/go;
-    s/([^\\])\\>/$1\t\t/go;
-    s/\n$//; s/^\n//;           # strip off leading/trailing \n
-    local($inside_tabbing) = 1;
-    $_ = &translate_commands(&translate_environments($_));
-    "<PRE><TT>\n$_\n</TT></PRE>";
-}
-
-################# Post Processing Latex Generated Images ################
-
-# A subroutine of the form post_latex_do_env_<ENV> can be used to
-# format images that have come back from latex
-
-# Do nothing (avoid the paragraph breaks)
-sub post_latex_do_env_figure { $_[0] }
-sub post_latex_do_env_figurestar { &post_latex_do_env_figure(@_) }
-
-sub post_latex_do_env_table { $_[0] }
-sub post_latex_do_env_tablestar { &post_latex_do_env_table(@_) }
-
-sub post_latex_do_env_equation {
-    local($prefix) = @_;
-    $global{'eqn_number'}+=1;
-    # include equation number at the side of the image -- HTML 3.2
-    if ($HTML_VERSION >= 3.2){
-       join('',"<P ALIGN=\"" , (($EQN_TAGS eq "L") ? "left" : "right")
-               , "\">$EQNO_START" , $prefix 
-               , &translate_commands('\theequation')
-               , "$EQNO_END</P>\n<BR CLEAR=\"all\">" );
-    # </P> creates unwanted space in some browsers, but others need it.
-    } else { "" }
-}
-
-sub do_cmd_theequation {
-    if ($USING_STYLES) {
-       $txt_style{'eqn-number'} = " " unless ($txt_style{'eqn-number'});
-       join('', "<SPAN CLASS=\"eqn-number\">"
-               ,&get_counter_value('eqn_number'),"</SPAN>", $_[0]);
-    } else { join('',&get_counter_value('eqn_number'), $_[0]); }
-}
-
-sub post_latex_do_env_eqnarray {
-    local($prefix,$body) = @_;
-    local($num_string,$line,@lines) = '';
-    local($side) = (($EQN_TAGS eq "L") ? "\"left\"" : "\"right\"" );
-    # MRO: replaced $* with /m
-    @lines = split(/\\\\\\\\/m, $body);
-    $line = pop(@lines);
-    if (!($line=~/^\s*$/)&&!($line =~/\\nonumber/)) {
-       $global{'eqn_number'}++;
-       $num_string .= join('', "<BR><BR>\n" , $EQNO_START , $prefix
-           , &translate_commands('\theequation')
-           , $EQNO_END);
-    }
-    foreach $line (@lines) {
-       next if ($line=~/^\s*$/);
-       $num_string .= "\n<BR>". (($MATH_SCALE_FACTOR > 1.3)? '<BR>' : '')
-                       . "<BR CLEAR=$side>";
-       if (!($line =~/\\(nonumber|(no)?tag)/)) {
-           $global{'eqn_number'}+=1;
-           $num_string .= join('', $EQNO_START , $prefix
-               , &translate_commands('\theequation')
-               , $EQNO_END);
-        }
-    }
-    # include equation numbers at the side of the image -- HTML 3.2
-    if ($HTML_VERSION >= 3.2){
-       "<P ALIGN=\"" . (($EQN_TAGS eq "L") ? "left" : "right")
-           . "\">" . (($DISP_SCALE_FACTOR >= 1.2 ) ? '<BIG>' : '')
-           . ${num_string}
-           . (($DISP_SCALE_FACTOR >= 1.2 ) ? '</BIG>' : '')
-           . "</P>\n<BR CLEAR=\"all\">"
-    # </P> creates unwanted space in some browsers, but others need it.
-    } else { "" };
-}
-
-sub post_latex_do_env_eqnarraystar {
-    local($_) = @_;
-    if (($HTML_VERSION >= 3.2)&&(!$NO_SIMPLE_MATH)){
-       join('', "<BR>\n<DIV ALIGN=\"CENTER\">\n"
-           , $_ , "\n<BR CLEAR=\"ALL\">\n<P>");
-    } elsif (($HTML_VERSION >= 2.2)&&(!$NO_SIMPLE_MATH)) {
-       join('', "\n<BR><P ALIGN=\"CENTER\">\n", $_ , "\n<BR></P>\n<P>");
-    } else {
-       join('', "\n<BR><P>\n", $_ , "\n<BR></P>\n<P>");
-    }
-}
-
-############################ Grouping ###################################
-
-sub do_cmd_begingroup { $latex_body .= "\n\\begingroup\n"; $_[0] }
-sub do_cmd_endgroup { $latex_body .= "\\endgroup\n\n"; $_[0] }
-sub do_cmd_bgroup { $latex_body .= "\n\\bgroup\n"; $_[0] }
-sub do_cmd_egroup { $latex_body .= "\\egroup\n\n"; $_[0] }
-
-sub do_env_tex2html_begingroup {
-    local($_) = @_;
-    $latex_body .= "\\begingroup ";
-    $_ = &translate_environments($_);
-    $_ = &translate_commands($_);
-    $latex_body .= "\\endgroup\n";
-    $_;
-}
-
-sub do_env_tex2html_bgroup {
-    local($_) = @_;
-    $latex_body .= "\\bgroup ";
-    $_ = &translate_environments($_);
-    $_ = &translate_commands($_);
-    $latex_body .= "\\egroup\n";
-    $_;
-}
-
-
-############################ Commands ###################################
-
-# Capitalizes what follows the \sc declaration
-# *** POTENTIAL ERROR ****
-# (This is NOT the correct meaning of \sc in the cases when it
-# is followed by another declaration (e.g. \em).
-# The scope of \sc should be limited to the next occurence of a
-# declaration.
-#sub do_cmd_sc {
-#    local($_) = @_;
-#    local(@words) = split(" ");
-# Capitalize the words which are not commands and do not contain any markers
-#   grep (do {tr/a-z/A-Z/ unless /(^\\)|(tex2html)/}, @words);
-#    grep (do {s/([a-z]+)/<small>\U$1\E<\/small>/g unless /(^\\)|(tex2html)/}, @words);
-#    join(" ", @words);
-#}
-sub do_cmd_sc { &process_smallcaps(@_) }
-sub do_cmd_scshape { &do_cmd_sc(@_) }
-
-# This is supposed to put the font back into roman.
-# Since there is no HTML equivalent for reverting
-# to roman we keep track of the open font tags in
-# the current context and close them.
-# *** POTENTIAL ERROR ****#
-# This will produce incorrect results in the exceptional
-# case where \rm is followed by another context
-# containing font tags of the type we are trying to close
-# e.g. {a \bf b \rm c {\bf d} e} will produce
-#       a <b> b </b> c   <b> d   e</b>
-# i.e. it should move closing tags from the end
-sub do_cmd_rm { # clean
-    my ($str, $ot) = @_;
-    $ot = $open_tags_R unless(defined $ot);
-    return("<\#rm\#>".$str) if ($inside_tabular);
-
-    my ($size,$color,$tags);
-    while (@$ot) {
-       my $next = pop (@$ot);
-       print STDOUT "\n</$next>" if $VERBOSITY > 2;
-       if ($next =~ /$sizechange_rx/) {
-           $size = $next unless ($size);
-       }
-#      if ($next =~ /$colorchange_rx/) {
-#          $color = $next unless ($color);
-#      }
-       $declarations{$next} =~ m|</.*$|;
-       $tags .= $& unless ($` =~ /^<>/);
-    }
-    if ($size) {
-       $declarations{$size} =~ m|</.*$|;
-       $tags .= $` unless ($` =~ /^<>/);
-       push (@$ot,$size);
-       print STDOUT "\n<$size>" if $VERBOSITY > 2;
-    }
-    $tags.$str;
-}
-
-sub do_cmd_rmfamily{ &do_cmd_rm(@_) }
-
-sub do_cmd_textrm { 
-    local($_) = @_;
-    local($text,$br_id)=('','0');
-    $text = &missing_braces unless (
-       (s/$next_pair_pr_rx/$text=$2;$br_id=$1;''/eo)
-       ||(s/$next_pair_rx/$text=$2;$br_id=$1;''/eo));
-    join ('' ,
-         &translate_environments("$O$br_id$C\\rm $text$O$br_id$C")
-         , $_ );
-}
-
-sub do_cmd_emph { 
-    local($_) = @_;
-    local($ifstyle,$join_tags) = ('',join(',',@$open_tags_R));
-    $join_tags =~ s/(^|,)(text)?(it|rm|normalfont)/$if_style=$3;''/eg; 
-    if ($if_style =~ /it/) {
-       ($ifstyle,$join_tags) = ('',join(',',@$open_tags_R));
-       $join_tags =~ s/(^|,)(text)?(bf|rm|normalfont)/$if_style=$3;''/eg; 
-       if ($if_style =~ /bf/) { &do_cmd_textrm(@_) }
-       else { &do_cmd_textbf(@_) }
-    } else { &do_cmd_textit(@_) }
-}
-
-#RRM: These cope with declared commands for which one cannot
-#     simply open a HTML single tag.
-#     The do_cmd_... gets found before the $declaration .
-
-sub do_cmd_upshape{&declared_env('upshape',$_[0],$tex2html_deferred)}
-sub do_cmd_mdseries{&declared_env('mdseries',$_[0],$tex2html_deferred)}
-sub do_cmd_normalfont{&declared_env('normalfont',$_[0],$tex2html_deferred)}
-
-
-# This is supposed to put the font back into normalsize.
-# Since there is no HTML equivalent for reverting
-# to normalsize we keep track of the open size tags in
-# the current context and close them.
-sub do_cmd_normalsize { # clean
-    my ($str, $ot) = @_;
-    $ot = $open_tags_R unless(defined $ot);
-
-    my ($font,$fontwt,$closures,$reopens,@tags);
-
-    while (@$ot) {
-       my $next = pop @$ot;
-       $declarations{$next} =~ m|</.*$|;
-       my ($pre,$post) = ($`,$&);
-       if ($post =~ /$block_close_rx|$all_close_rx/ ) {
-           push (@$ot, $next);
-           last;
-       }
-       $closures .= $post unless ($pre =~ /^<>/);
-       print STDOUT "\n</$next>" if $VERBOSITY > 2;
-
-       if ($next =~ /$fontchange_rx/) {
-           $font = $next unless ($font);
-       } elsif ($next =~ /$fontweight_rx/) {
-           $fontwt = $next unless ($fontwt);
-       } elsif ($next =~ /$sizechange_rx/) {
-           # discard it
-       } else {
-           unshift (@tags, $next);
-           print STDOUT "\n<<$next>" if $VERBOSITY > 2;
-           $reopens .= $pre unless ($pre =~ /^<>/);
-       }
-    }
-    push (@$ot, @tags);
-    if ($font) {
-       $declarations{$font} =~ m|</.*$|;
-       $reopens .= $` unless ($` =~ /^<>/);
-       push (@$ot,$font);
-       print STDOUT "\n<$font>" if $VERBOSITY > 2;
-    }
-    if ($fontwt) {
-       $declarations{$fontwt} =~ m|</.*$|;
-       $reopens .= $` unless ($` =~ /^<>/);
-       push (@$ot,$fontwt);
-       print STDOUT "\n<$fontwt>" if $VERBOSITY > 2;
-    }
-    join('', $closures, $reopens, $str);
-}
-
-
-
-#JCL(jcl-tcl)
-# changed everything
-#
-sub do_cmd_title {
-    local($_) = @_;
-    &get_next_optional_argument;
-    local($making_title,$next) = (1,'');
-    $next = &missing_braces unless (
-       (s/$next_pair_pr_rx/$next = $2;''/eo)
-       ||(s/$next_pair_rx/$next = $2;''/eo));
-    $t_title = &translate_environments($next);
-    $t_title = &translate_commands($t_title);
-#    $toc_sec_title = &simplify(&translate_commands($next));
-    $toc_sec_title = &purify(&translate_commands($next));
-    $TITLE = (($toc_sec_title)? $toc_sec_title : $default_title)
-       unless ($TITLE && !($TITLE =~ /^($default_title|\Q$FILE\E)$/));
-#    $TITLE = &purify($TITLE);
-
-    #RRM: remove superscripts inserted due to \thanks
-    $TITLE =~ s/<A[^>]*><SUP>\d+<\/SUP><\/A>/$1/g;
-    $_;
-}
-
-sub do_cmd_author {
-    local($_) = @_;
-    &get_next_optional_argument;
-    my $next;
-    $next = &missing_braces unless (
-       (s/$next_pair_pr_rx/$next = $2;''/seo)
-       ||(s/$next_pair_rx/$next = $2;''/seo));
-    local($after) = $_;
-    if ($next =~ /\\and/) {
-       my @author_list = split(/\s*\\and\s*/, $next);
-       my $t_author, $t_affil, $t_address;
-       foreach (@author_list) {
-           $t_author = &translate_environments($_);
-           $t_author =~ s/\s+/ /g;
-           $t_author = &simplify(&translate_commands($t_author));
-           ($t_author,$t_affil,$t_address) = split (/\s*<BR>s*/, $t_author);
-           push @authors, $t_author;
-           push @affils, $t_affil;
-           push @addresses, $t_address;
-       }
-    } else {
-       $_ = &translate_environments($next);
-       $next = &translate_commands($_);
-       ($t_author) = &simplify($next);
-       ($t_author,$t_affil,$t_address) = split (/\s*<BR>s*/, $t_author);
-       push @authors, $t_author;
-       push @affils, $t_affil if $t_affil;
-       push @addresses, $t_address if $t_address;
-    }
-    $after;
-}
-
-sub do_cmd_address {
-    local($_) = @_;
-    &get_next_optional_argument;
-    local($next);
-    $next = &missing_braces unless (
-       (s/$next_pair_pr_rx/$next = $&;''/eo)
-       ||(s/$next_pair_rx/$next = $&;''/eo));
-    ($t_address) = &simplify(&translate_commands($next));
-    push @addresses, $t_address;
-    $_;
-}
-
-sub do_cmd_institute {
-    local($_) = @_;
-    &get_next_optional_argument;
-    local($next);
-    $next = &missing_braces unless (
-       (s/$next_pair_pr_rx/$next = $&;''/eo)
-       ||(s/$next_pair_rx/$next = $&;''/eo));
-    ($t_institute) = &simplify(&translate_commands($next));
-    push @affils, $t_institute;
-    $_;
-}
-
-sub do_cmd_dedicatory {
-    local($_) = @_;
-    &get_next_optional_argument;
-    local($next);
-    $next = &missing_braces unless (
-       (s/$next_pair_pr_rx/$next = $&;''/eo)
-       ||(s/$next_pair_rx/$next = $&;''/eo));
-    ($t_affil) = &simplify(&translate_commands($next));
-    push @affils, $t_affil;
-    $_;
-}
-
-sub do_cmd_email {
-    local($_) = @_;
-    local($next,$target)=('','notarget');
-    $next = &missing_braces unless (
-       (s/$next_pair_pr_rx/$next = $2;''/eo)
-       ||(s/$next_pair_rx/$next = $2;''/eo));
-    local($mail) = &translate_commands($next);
-    ($t_email) = &make_href("mailto:$mail","$mail");
-    push @emails, $t_email;
-    $_;
-}
-
-sub do_cmd_authorURL {
-    local($_) = @_;
-    local($next);
-    $next = &missing_braces unless (
-       (s/$next_pair_pr_rx/$next = $2;''/eo)
-       ||(s/$next_pair_rx/$next = $2;''/eo));
-    ($t_authorURL) =  &translate_commands($next);
-    push @authorURLs, $t_authorURL;
-    $_;
-}
-
-sub do_cmd_date {
-    local($_) = @_;
-    local($next);
-    $next = &missing_braces unless (
-       (s/$next_pair_pr_rx/$next = $&;''/eo)
-       ||(s/$next_pair_rx/$next = $&;''/eo));
-    ($t_date) = &translate_commands($next);
-    $_;
-}
-
-sub make_multipleauthors_title {
-    local($alignc, $alignl) = (@_);
-    local($t_author,$t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL)
-       = ('','','','','','','');
-    local ($t_title,$auth_cnt) = ('',0);
-    if ($MULTIPLE_AUTHOR_TABLE) {
-       $t_title = '<TABLE' .($USING_STYLES? ' CLASS="author_info_table"' : '')
-               .' WIDTH="90%" ALIGN="CENTER" CELLSPACING=15>'
-               ."\n<TR VALIGN=\"top\">";
-    }
-    foreach $t_author (@authors) {
-       $t_affil = shift @affils;
-       $t_institute = ''; # shift @institutes;
-       $t_address = shift @addresses;
-       $t_email = shift @emails;
-       $t_authorURL = shift @authorURLs;
-       if ($MULTIPLE_AUTHOR_TABLE) {
-           if ($auth_cnt == $MAX_AUTHOR_COLS) {
-               $t_title .= join("\n", '</TR><TR>', '');
-               $auth_cnt -= $MAX_AUTHOR_COLS;
-           }
-           $t_title .= join("\n"
-               , '<TD>'
-               , &make_singleauthor_title($alignc, $alignl ,$t_author
-                   , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL)
-               , '</TD>' );
-           ++$auth_cnt;
-       } else {
-           $t_title .= &make_singleauthor_title($alignc, $alignl ,$t_author
-               , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL);
-       }
-    }
-    if ($MULTIPLE_AUTHOR_TABLE) {
-       $t_title .= "\n</TR></TABLE>\n";
-    }
-    $t_title;
-}
-
-sub do_cmd_maketitle {
-    local($_) = @_;
-    local($the_title) = '';
-    local($alignc, $alignl);
-    if ($HTML_VERSION > 2.1) {
-       $alignc = " ALIGN=\"CENTER\""; 
-       $alignl = " ALIGN=\"LEFT\""; 
-       $alignl = $alignc if ($MULTIPLE_AUTHOR_TABLE);
-    }
-    if ($t_title) {
-       $the_title .= "<H1$alignc>$t_title</H1>";
-    } else { &write_warnings("\nThis document has no title."); }
-    if (($#authors >= 1)||$MULTIPLE_AUTHOR_TABLE) {
-       $the_title .= &make_multipleauthors_title($alignc,$alignl);
-       if ($t_date&&!($t_date=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) {
-           $the_title .= "\n<P$alignc><STRONG>$t_date</STRONG></P>";}
-    } else {
-       $the_title .= &make_singleauthor_title($alignc,$alignl ,$t_author
-           , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL);
-    }
-    $the_title . $_ ;
-}
-
-sub make_singleauthor_title {
-    local($alignc, $alignl , $t_author
-       , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL) = (@_);
-    my $t_title = '';
-    my ($s_author_info, $e_author_info) = ('<DIV','</DIV>');
-    $s_author_info .= ($USING_STYLES ? ' CLASS="author_info"' : '').'>';
-
-    if ($t_author) {
-       if ($t_authorURL) {
-           local($href) = &translate_commands($t_authorURL);
-           $href = &make_named_href('author'
-                       , $href, "<STRONG>${t_author}</STRONG>");
-           $t_title .= "\n<P$alignc>$href</P>";
-       } else {
-           $t_title .= "\n<P$alignc><STRONG>$t_author</STRONG></P>";
-       }
-    } else { &write_warnings("\nThere is no author for this document."); }
-
-    if ($t_institute&&!($t_institute=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) {
-       $t_title .= "\n<P$alignc><SMALL>$t_institute</SMALL></P>";}
-    if ($t_affil&&!($t_affil=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) {
-       $t_title .= "\n<P$alignc><I>$t_affil</I></P>";}
-    if ($t_date&&!($t_date=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) {
-       $t_title .= "\n<P$alignc><STRONG>$t_date</STRONG></P>";}
-    if ($t_address&&!($t_address=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) {
-       $t_title .= "\n<P$alignl><SMALL>$t_address</SMALL></P>";
-    }  # else { $t_title .= "\n<P$alignl>"}
-    if ($t_email&&!($t_email=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) {
-       $t_title .= "\n<P$alignl><SMALL>$t_email</SMALL></P>";
-    }  # else { $t_title .= "</P>" }
-    join("\n", $s_author_info, $t_title, $e_author_info);
-}
-
-sub do_cmd_abstract {
-    local($_) = @_;
-    local($abstract);
-    $abstract = &missing_braces unless (
-       (s/$next_pair_pr_rx/$abstract = $&;''/eo)
-       ||(s/$next_pair_rx/$abstract = $&;''/eo));
-    join('', &make_abstract($abstract), $_);
-}
-
-sub make_abstract {
-    local($_) = @_;
-    # HWS  Removed emphasis (hard to read)        
-    $_ = &translate_environments($_);
-    $_ = &translate_commands($_);
-    local($title);
-    if ((defined &do_cmd_abstractname)||$new_command{'abstractname'}) {
-       local($br_id)=++$global{'max_id'};
-       $title = &translate_environments("$O$br_id$C\\abstractname$O$br_id$C");
-    } else { $title = $abs_title }
-    local($env_id) = " CLASS=\"ABSTRACT\"" if ($USING_STYLES);
-    join('',"\n<H3>", $title, ":</H3>\n"
-       , (($HTML_VERSION > 3)? "<DIV$env_id>" : "<P>"), $_ 
-       , (($HTML_VERSION > 3)? "</DIV>" : "</P>"), "\n<P>");
-}
-
-sub set_default_language {
-    # MRO: local($lang,*_) = @_;
-    my $lang = shift;
-    push(@language_stack, $default_language);
-    $default_language = $lang;
-    $_[0] .= '\popHtmlLanguage';
-}
-
-sub do_cmd_popHtmlLanguage {
-    $default_language = pop(@language_stack);
-    $_[0];
-}
-
-sub do_cmd_today {
-    local($lang);
-    if ($PREAMBLE) {
-       $lang = $TITLES_LANGUAGE || $default_language ;
-    } else {
-       $lang = $current_language || $default_language ;
-    }
-    local($today) = $lang . '_today';
-    if (defined &$today) { join('', eval "&$today()", $_[0]) }
-    else { join('', &default_today(), $_[0]) }
-}
-
-sub default_today {
-    #JKR: Make it more similar to LaTeX
-    ## AYS: moved french-case to styles/french.perl
-    my $today = &get_date();
-
-    $today =~ s|(\d+)/0?(\d+)/|$Month[$1] $2, |;
-    join('',$today,$_[0]);
-}
-
-sub do_cmd_textbackslash { join('','&#92;', $_[0]);}
-sub do_cmd_textbar { join('','|', $_[0]);}
-sub do_cmd_textless { join('',';SPMlt;', $_[0]);}
-sub do_cmd_textgreater { join('',';SPMgt;', $_[0]);}
-sub do_cmd_textasciicircum { join('','&#94;', $_[0]);}
-sub do_cmd_textasciitilde { join('','&#126;', $_[0]);}
-sub do_cmd_textquoteleft { join('','&#96;', $_[0]);}
-sub do_cmd_textquoteright { join('','&#39;', $_[0]);}
-
-sub do_cmd_textcompwordmark { join('','', $_[0]);}
-sub do_cmd_texttrademark { join('','<SUP><SMALL>TM</SMALL></SUP>', $_[0]);}
-
-sub do_cmd_textsubscript   { &make_text_supsubscript('SUB',$_[0]);} 
-sub do_cmd_textsuperscript { &make_text_supsubscript('SUP',$_[0]);}
-
-sub make_text_supsubscript { 
-    local ($supsub, $_) = (@_);
-    my $arg = '';
-    $arg = &missing_braces unless (
-       (s/$next_pair_pr_rx/$arg = $&;''/eo)
-       ||(s/$next_pair_rx/$arg = $&;''/eo));
-    $arg = &translate_commands($arg) if ($arg =~ m!\\!);
-    join('', "<$supsub>", $arg, "</$supsub>", $_);
-}
-
-sub do_cmd_textcircled { 
-    local ($_) = (@_);
-    my $arg = '';
-    $arg = &missing_braces unless (
-       (s/$next_pair_pr_rx/$arg = $&;''/eo)
-       ||(s/$next_pair_rx/$arg = $&;''/eo));
-    my $after = $_;
-    join('', &process_undefined_environment("tex2html_nomath_inline"
-          , ++$global{'max_id'}
-          , "\\vbox{\\kern3pt\\textcircled{$arg}}" )
-       , $after );
-}
-
-# these can be overridded in charset (.pl) extension files:
-sub do_cmd_textemdash { join('','---', $_[0]);}
-sub do_cmd_textendash { join('','--', $_[0]);}
-#sub do_cmd_exclamdown { join('','', $_[0]);}
-#sub do_cmd_questiondown { join('','', $_[0]);}
-sub do_cmd_textquotedblleft { join('',"``", $_[0]);}
-sub do_cmd_textquotedblright { join('',"''", $_[0]);}
-sub do_cmd_textbullet { join('','*', $_[0]);}
-sub do_cmd_textvisiblespace { join('','_', $_[0]);}
-
-sub do_cmd_ldots {
-    join('',(($math_mode&&$USE_ENTITY_NAMES) ? ";SPMldots;" : "..."),$_[0]);
-}
-
-sub do_cmd_dots {
-    join('',(($math_mode&&$USE_ENTITY_NAMES) ? ";SPMldots;" : "..."),$_[0]);
-}
-
-sub do_cmd_hrule {
-    local($_) = @_;
-    &ignore_numeric_argument;
-    #JKR: No need for <BR>
-    local($pre,$post) = &minimize_open_tags('<HR>');
-    join('',$pre,$_);
-}
-
-#sub do_cmd_hrulefill {
-#    "<HR ALIGN=\"right\">\n<BR CLEAR=\"right\">";
-#}
-
-sub do_cmd_linebreak {
-    local($num,$dum) = &get_next_optional_argument;
-    if (($num)&&($num<4)) { return $_[0] }
-    join('',"<BR>", $_[0]);
-}
-
-sub do_cmd_pagebreak {
-    local($_) = @_;
-    local($num,$dum) = &get_next_optional_argument;
-    if (($num)&&($num<4)) { return($_) }
-    elsif (/^ *\n *\n/) {
-       local($after) = $';
-       local($pre,$post) = &minimize_open_tags("<BR>\n<P>");
-       join('',$pre, $')
-    } else { $_ }
-}
-
-
-sub do_cmd_newline { join('',"<BR>", $_[0]); }
-# this allows for forced newlines in tables, etc.
-sub do_cmd_endgraf { join('',"<BR>", $_[0]); }
-
-sub do_cmd_space { join(''," ",$_[0]); }
-sub do_cmd_enspace { join('',"\&nbsp;",$_[0]); }
-sub do_cmd_quad { join('',"\&nbsp;"x4,$_[0]); }
-sub do_cmd_qquad { join('',"\&nbsp;"x8,$_[0]); }
-
-sub do_cmd_par {
-    local ($_) = @_;
-    my ($pre,$post) = &preserve_open_tags();
-    my ($spar, $lcode) = ("\n<P", '');
-    if (($USING_STYLES) &&(!($default_language eq $TITLES_LANGUAGE))) {
-       $lcode = &get_current_language();
-       $spar .= $lcode if $lcode;
-    }
-    join('', $pre, $spar, ">\n",$post,$_);
-}
-
-sub do_cmd_medskip {
-    local ($_) = @_;
-    local($pre,$post) = &preserve_open_tags();
-    join('',$pre,"\n<P><BR>\n",$post,$_);
-}
-
-sub do_cmd_smallskip {
-    local ($_) = @_;
-    local($pre,$post) = &preserve_open_tags();
-    join('',$pre,"\n<P></P>\n",$post,$_);
-}
-
-sub do_cmd_bigskip {
-    local ($_) = @_;
-    local($pre,$post) = &preserve_open_tags();
-    join('',$pre,"\n<P><P><BR>\n",$post,$_);
-}
-
-# MEH: Where does the slash command come from?
-# sub do_cmd_slash {
-#    join('',"/",$_[0]);
-#}
-sub do_cmd_esc_slash { $_[0]; }
-sub do_cmd_esc_hash { "\#". $_[0]; }
-sub do_cmd_esc_dollar { "\$". $_[0]; }
-sub do_cmd__at_ { $_[0]; }
-sub do_cmd_lbrace { "\{". $_[0]; }
-sub do_cmd_rbrace { "\}". $_[0]; }
-sub do_cmd_Vert { "||". $_[0]; }
-sub do_cmd_backslash { "\\". $_[0]; }
-
-#RRM: for subscripts outside math-mode
-# e.g. in Chemical formulae
-sub do_cmd__sub {
-    local($_) = @_;
-    local($next);
-    $next = &missing_braces unless (
-        (s/$next_pair_pr_rx/$next = $2;''/e)
-        ||(s/$next_pair_rx/$next = $2;''/e));
-    join('',"<SUB>",$next,"</SUB>",$_);   
-}
-
-#JCL(jcl-del) - the next two ones must only have local effect.
-# Yet, we don't have a mechanism to revert such changes after
-# a group has closed.
-#
-sub do_cmd_makeatletter {
-    $letters =~ s/@//;
-    $letters .= '@';
-    &make_letter_sensitive_rx;
-    $_[0];
-}
-
-sub do_cmd_makeatother {
-    $letters =~ s/@//;
-    &make_letter_sensitive_rx;
-    $_[0];
-}
-
-
-################## Commands to be processed by Latex #################
-#
-# The following commands are passed to Latex for processing.
-# They cannot be processed at the same time as normal commands
-# because their arguments must be left untouched by the translator.
-# (Normally the arguments of a command are translated before the
-# command itself).
-#
-# In fact, it's worse:  it is not correct to process these
-# commands after we process environments, because some of them
-# (for instance, \parbox) may contain unknown or wrapped
-# environments.  If math mode occurs in a parbox, the
-# translate_environments routine should *not* process it, lest
-# we encounter the lossage outlined above.
-#
-# On the other hand, it is not correct to process these commands
-# *before* we process environments, or figures containing
-# parboxes, etc., will be mishandled.
-#
-# RRM: (added for V97.1) 
-#  \parbox now uses the  _wrap_deferred  mechanism, and has a  do_cmd_parbox
-#  subroutine defined. This means that environments where parboxes are
-#  common (.g. within table cells), can detect the \parbox command and
-#  adjust the processing accordingly.
-#
-# So, the only way to handle these commands is to wrap them up
-# in null environments, as for math mode, and let translate_environments
-# (which can handle nesting) figure out which is the outermost.
-#
-# Incidentally, we might as well make these things easier to configure...
-
-sub process_commands_in_tex {
-    local($_) = @_;
-    local($arg,$tmp);
-    foreach (/.*\n?/g) {
-       chop;
-       # For each line
-       local($cmd, @args) = split('#',$_);
-       next unless $cmd;
-       $cmd =~ s/ //g;
-
-       # skip if a proper implementation already exists
-       $tmp = "do_cmd_$cmd";
-       next if (defined &$tmp);
-
-       # Build routine body ...
-       local ($body, $code, $thisone) = ("", "");
-
-       # alter the pattern here to debug particular commands
-#      $thisone = 1 if ($cmd =~ /mathbb/);
-
-       print "\n$cmd: ".scalar(@args)." arguments" if ($thisone);
-       foreach $arg (@args) {
-           print "\nARG: $arg" if ($thisone);
-           print "\nARG: $next_pair_rx" if ($thisone);
-           if ($arg =~ /\{\}/) {
-# RRM: the $` is surely wrong, allowing no error-checking.
-# Use <<...>> for specific patterns
-#              $body .= '$args .= "$`$&" if s/$next_pair_rx//o;'."\n"; 
-               $body .= '$args .= join("","{", &missing_braces, "}") unless ('."\n";
-               $body .= '  (s/$next_pair_pr_rx/$args.=$`.$&;""/es)'."\n";
-               $body .= '  ||(s/$next_pair_rx/$args.=$`.$&;""/es));'."\n";
-               print "\nAFTER:$'" if (($thisone)&&($'));
-               $body .= $' if ($');
-           } elsif ($arg =~ /\[\]/) {
-               $body .= '($dummy, $pat) = &get_next_optional_argument;'
-                   . '$args .= $pat;'."\n";
-               print "\nAFTER:$'" if (($thisone)&&($'));
-               $body .= $' if ($');
-           } elsif ($arg =~ /^\s*\\/) {                    
-               $body .= '($dummy, $pat) = &get_next_tex_cmd;'
-                   . '$args .= $pat;'."\n";
-               print "\nAFTER:$'" if (($thisone)&&($'));
-               $body .= $' if ($');
-           } elsif ($arg =~ /<<\s*/) {
-               $arg = $';
-               if ($arg =~ /\s*>>/) {
-                    # MRO: replaced $* with /m
-                   $body .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n"
-#                  $body .= '$args .= "$`$&" if (/\\\\'.$`.'/);' . "\n"
-                       . "\$_ = \$\';\n";
-                   print "\nAFTER:$'" if (($thisone)&&($'));
-                   $body .= $' if ($');
-               } else { $body .= $arg ; }
-           } else {
-               print "\nAFTER:$'" if (($thisone)&&($arg));
-               $body .= $arg ;
-           }
-       }
-
-       # Generate a new subroutine
-       local($padding) = " ";
-       $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/));
-       $code = "sub wrap_cmd_$cmd {" . "\n"
-           . 'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";' . "\n"
-           . $body
-           . (($thisone)? "print STDERR \"\\n$cmd:\".\$args.\"\\n\";\n" : '')
-           . '(&make_wrapper(1).$cmd'
-           . ($padding ? '"'.$padding.'"' : '')
-           . '.$args.&make_wrapper(0), $_)}'
-           . "\n";
-       print "\nWRAP_CMD: $code " if ($thisone); # for debugging
-       eval $code; # unless ($thisone);
-       print STDERR "\n*** sub wrap_cmd_$cmd  failed: $@" if ($@);
-
-       # And make sure the main loop will catch it ...
-#      $raw_arg_cmds{$cmd} = 1;
-       ++$raw_arg_cmds{$cmd};
-    }
-}
-
-sub process_commands_nowrap_in_tex {
-    local($_) = @_;
-    local($arg);
-    foreach (/.*\n?/g) {
-       chop;
-       local($cmd, @args) = split('#',$_);
-       next unless $cmd;
-       $cmd =~ s/ //g;
-       # Build routine body ...
-       local ($bodyA, $codeA, $bodyB, $codeB, $thisone) = ("", "", "", "");
-
-       # alter the pattern here to debug particular commands
-#      $thisone = 1 if ($cmd =~ /epsf/);
-
-       print "\n$cmd: ".scalar(@args)." arguments" if ($thisone);
-       foreach $arg (@args) {
-           print "\nARG: $arg" if ($thisone);
-           if ($arg =~ /\{\}/) {
-#              $bodyA .= '$args .= "$`"."$&" if (s/$any_next_pair_rx//);'."\n";
-               $bodyA .= 'if (s/$next_pair_rx//s){$args.="$`"."$&"; $_='."\$'};\n";
-               $bodyB .= '$args .= &missing_braces'."\n unless (";
-               $bodyB .= '(s/$any_next_pair_pr_rx/$args.=$`.$&;\'\'/eo)'."\n";
-               $bodyB .= '  ||(s/$any_next_pair_rx/$args.=$`.$&;\'\'/eo));'."\n";
-               print "\nAFTER:$'" if (($thisone)&&($'));
-#              $bodyA .= $'.";\n" if ($');
-               $bodyB .= $'.";\n" if ($');
-           } elsif ($arg =~ /\[\]/) {
-               $bodyA .= '($dummy, $pat) = &get_next_optional_argument;'
-                   . '$args .= $pat;'."\n";
-               print "\nAFTER:$'" if (($thisone)&&($'));
-#              $bodyA .= $'.";\n" if ($');
-               $bodyB .= $'.";\n" if ($');
-           } elsif ($arg =~ /^\s*\\/) {                    
-               $bodyA .= '($dummy, $pat) = &get_next_tex_cmd;'
-                   . '$args .= $pat;'."\n";
-               $bodyB .= '($dummy, $pat) = &get_next_tex_cmd;'
-                   . '$args .= $pat;'."\n";
-               print "\nAFTER:$'" if (($thisone)&&($'));
-               $bodyA .= $'.";\n" if ($');
-               $bodyB .= $'.";\n" if ($');
-           } elsif ($arg =~ /<<\s*/) {
-               $arg = $';
-               if ($arg =~ /\s*>>/) {
-                    # MRO: replaced $* with /m
-                   $bodyA .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n"
-#                  $bodyA .= '$args .= $`.$& if (/\\\\'.$`.'/);' . "\n"
-                       . "\$_ = \$\';\n";
-                   $bodyB .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n"
-                       . "\$_ = \$\';\n";
-                   print "\nAFTER:$'" if (($thisone)&&($'));
-#                  $bodyA .= $'.";\n" if ($');
-                   $bodyB .= $'.";\n" if ($');
-               } else { 
-                   print "\nAFTER:$arg" if (($thisone)&&($arg));
-#                  $bodyA .= $arg.";\n" if ($arg);
-                   $bodyB .= $arg.";\n" if ($arg);
-               }
-           } else { 
-               print "\nAFTER:$arg" if (($thisone)&&($arg));
-               $bodyA .= '$args .= '.$arg.";\n" if ($');
-               $bodyB .= $arg.";\n" if ($'); 
-           }
-       }
-       local($padding) = " ";
-       $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/));
-       # Generate 2 new subroutines
-       $codeA = "sub wrap_cmd_$cmd {" . "\n"
-           .'local($cmd, $_) = @_; local($args, $dummy, $pat) = "";'."\n"
-           . $bodyA
-           . (($thisone)? "print \"\\nwrap $cmd:\\n\".\$args.\"\\n\";\n" : '')
-           . '(&make_nowrapper(1)."\n".$cmd.'."\"$padding\""
-           . '.$args.&make_nowrapper(0)," ".$_)}'
-           ."\n";
-       print "\nWRAP_CMD: $codeA " if ($thisone); # for debugging
-       eval $codeA;
-       print STDERR "\n\n*** sub wrap_cmd_$cmd  failed: $@\n" if ($@);
-       $codeB = "do_cmd_$cmd";
-       do {
-           $bodyB = '"";' if !($bodyB);
-           $codeB = "sub do_cmd_$cmd {" . "\n"
-               . 'local($_,$ot) = @_;'."\n"
-               . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'."\n"
-               . 'local($cmd,$args,$dummy,$pat)=("'.$cmd.'","","","");'."\n"
-               . $bodyB
-               . (($thisone)? "print \"\\ndo $cmd:\".\$args.\"\\n\";\n" : '')
-#              . '$latex_body.="\\n".&revert_to_raw_tex("'."\\\\$cmd$padding".'$args")."\\n\\n";'
-               . "\$_;}\n";
-           print STDOUT "\nDO_CMD: $codeB " if ($thisone); # for debugging
-           eval $codeB;
-           print STDERR "\n\n*** sub do_cmd_$cmd  failed: $@\n" if ($@);
-       } unless (defined &$codeB );
-
-       # And make sure the main loop will catch it ...
-#      $raw_arg_cmds{$cmd} = 1;
-       ++$raw_arg_cmds{$cmd};
-    }
-}
-
-sub process_commands_wrap_deferred {
-    local($_) = @_;
-    local($arg,$thisone);
-    foreach (/.*\n?/g) {
-       chop;
-       local($cmd, @args) = split('#',$_);
-       next unless $cmd;
-       $cmd =~ s/ //g;
-       # Build routine body ...
-       local ($bodyA, $codeA, $bodyB, $codeB, $after, $thisone);
-
-       # alter the pattern here to debug particular commands
-#      $thisone = 1 if ($cmd =~ /selectlanguage/);
-
-       print "\n$cmd: ".scalar(@args)." arguments" if ($thisone);
-       foreach $arg (@args) {
-           print "\nARG: $arg" if ($thisone);
-           if ($arg =~ /\{\}/) {
-#              $bodyA .= '$args .= "$`$&" if (s/$any_next_pair_rx//o);';
-               $bodyA .= '$args .= "$`$&" if (s/$next_pair_rx//so);';
-               $after = $';
-               print "\nAFTER:$'" if (($thisone)&&($'));
-           } elsif ($arg =~ /\[\]/) {
-               $bodyA .= '($dummy, $pat) = &get_next_optional_argument;' .
-                   "\n". '$args .= $pat;';
-               $after = $';
-               print "\nAFTER:$'" if (($thisone)&&($'));
-           } elsif ($arg =~ /^\s*\\/) {                    
-               $bodyA .= '($dummy, $pat) = &get_next_tex_cmd;'
-                   . '$args .= $pat;'."\n";
-               print "\nAFTER:$'" if (($thisone)&&($'));
-               $bodyA .= $'.";\n" if ($');
-           } elsif (/<<\s*([^>]*)[\b\s]*>>/) {
-               local($endcmd, $afterthis) = ($1,$');
-               $afterthis =~ s/(^\s*|\s*$)//g;
-               $endcmd =~ s/\\/\\\\/g;
-               $bodyA .= "\n". 'if (/'.$endcmd.'/) { $args .= $`.$& ; $_ = $\' };';
-               $after .= $afterthis if ($afterthis);
-               print "\nAFTER:$'" if (($thisone)&&($'));
-           } else { 
-               print "\nAFTER:$arg" if (($thisone)&&($arg));
-                $bodyB .= $arg.";\n" ; $after = ''
-            }
-           $after =~ s/(^\s*|\s*$)//g if ($after);
-           $bodyB .= $after . ";" if ($after);
-           $bodyA .= "\$args .= ".$after . ";" if ($after);
-       }
-       local($padding) = " ";
-       $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/));
-       # Generate 2 new subroutines
-       $codeA = "sub wrap_cmd_$cmd {" . "\n"
-           .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";'."\n"
-           . $bodyA #. ($bodyA ? "\n" : '')
-           . (($thisone)? ";print \"\\nwrap $cmd:\".\$args.\"\\n\";\n" : '')
-           .'(&make_deferred_wrapper(1).$cmd.'.$padding
-               .'$args.&make_deferred_wrapper(0),$_)}'
-           ."\n";
-       print STDERR "\nWRAP_CMD: $codeA " if ($thisone); # for debugging
-       eval $codeA;
-       print STDERR "\n\n*** sub wrap_cmd_$cmd  failed: $@\n" if ($@);
-
-       #RRM: currently these commands only go to LaTeX or access counters.
-       #   They could be implemented more generally, as below with  do_dcmd_$cmd
-       #   requiring replacement to be performed before evaluation.
-       $codeB = "sub do_dcmd_$cmd {" . "\n"
-           .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";'."\n"
-           . $bodyA . "\n" 
-            . (($thisone)? ";print \"\\ndo_def $cmd:\".\$args.\"\\n\";\n" : '')
-            . $bodyB . "}" . "\n";
-       print "\nDEF_CMD: $codeB " if ($thisone); # for debugging
-       local($tmp) = "do_cmd_$cmd";
-       eval $codeB unless (defined &$tmp);
-       print STDERR "\n\n*** sub do_dcmd_$cmd  failed: $@\n" if ($@);
-
-       # And make sure the main loop will catch it ...
-#      $raw_arg_cmds{$cmd} = 1;
-       ++$raw_arg_cmds{$cmd};
-    }
-}
-
-sub process_commands_inline_in_tex {
-    local($_) = @_;
-    foreach (/.*\n?/g) {
-       chop;
-       local($cmd, @args) = split('#',$_);
-       next unless $cmd;
-       $cmd =~ s/ //g;
-       # Build routine body ...
-       local ($body, $code, $thisone) = ("", "");
-
-       # uncomment and alter the pattern here to debug particular commands
-#      $thisone = 1 if ($cmd =~ /L/);
-
-       print "\n$cmd: ".scalar(@args)." arguments" if ($thisone);
-       foreach (@args) {
-           print "\nARG: $_" if ($thisone);
-           if (/\{\}/) {
-#              $body .= '$args .= $`.$& if (/$any_next_pair_rx/);' . "\n"
-#                  . "\$_ = \$\';\n";
-               $body .= '$args .= $`.$& if (s/$next_pair_rx//s);' . "\n"
-           } elsif (/\[\]/) {
-               $body .= 'local($dummy, $pat) = &get_next_optional_argument;' .
-                   "\n". '$args .= $pat;';
-           } elsif ($arg =~ /^\s*\\/) {                    
-               $body .= '($dummy, $pat) = &get_next_tex_cmd;'
-                   . '$args .= $pat;'."\n";
-               print "\nAFTER:$'" if (($thisone)&&($'));
-               $body .= $'.";\n" if ($');
-           } elsif (/<<\s*/) {
-               $_ = $';
-               if (/\s*>>/) {
-                    # MRO: replaced $* with /m
-                   $body .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n"
-                       . "\$_ = \$\';\n"
-               } else { $body .= $_.";\n" ; }
-           } else { $body .= $_.";\n" ; }
-       }
-       local($padding) = " ";
-       $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/));
-       # Generate a new subroutine
-       my $itype = ($cmd =~ /^f.*box$/ ? 'inline' : 'nomath');
-       $code = "sub wrap_cmd_$cmd {" . "\n"
-           .'local($cmd, $_) = @_; local ($args) = "";' . "\n"
-           . $body . "\n"
-            . (($thisone)? ";print \"\\ndo $cmd:\".\$args.\"\\n\";\n" : '')
-           .'(&make_'.$itype.'_wrapper(1).$cmd.$padding.$args.'
-           . '&make_'.$itype.'_wrapper(0),$_)}'
-           ."\n";
-       print "\nWRAP_CMD:$raw_arg_cmds{$cmd}: $code "
-               if ($thisone); # for debugging
-       eval $code;
-       print STDERR "\n\n*** sub wrap_cmd_$cmd  failed: $@\n" if ($@);
-       # And make sure the main loop will catch it ...
-#      $raw_arg_cmds{$cmd} = 1;
-       ++$raw_arg_cmds{$cmd};
-    }
-}
-
-
-# Invoked before actual translation; wraps these commands in
-# tex2html_wrap environments, so that they are properly passed to
-# TeX in &translate_environments ...
-# JCL(jcl-del) - new usage of $raw_arg_cmd_rx
-sub wrap_raw_arg_cmds {
-    local ($processed_text, $cmd, $wrapper, $wrap, $after);
-    print "\nwrapping raw arg commands " if ($VERBOSITY>1);
-    local($seg, $par_wrap, $teststar, @processed);
-#   local(@segments) = split(/\\par\b/,$_);
-#   foreach (@segments) {
-#      $par_wrap = join('',&make_deferred_wrapper(1), "\\par"
-#                      , &make_deferred_wrapper(0));
-#     push(@processed, $par_wrap ) if ($seg); ++$seg;
-    if (%renew_command) {
-       local($key);
-       foreach $key (keys %renew_command) {
-           $raw_arg_cmds{$key} = 1;
-           $raw_arg_cmd_rx =~ s/^(\(\)\\\\\()/$1$key\|/;
-       }
-    }
-    print "\n" if (/$raw_arg_cmd_rx/);
-
-    # MRO: replaced $* with /m
-    while (/$raw_arg_cmd_rx/m) {
-       local($star);
-       push (@processed, $`); print "\@";
-       $after = $';
-       #JCL(jcl-del) - status of starred raw arg cmds yet unclear
-       ($cmd, $star) = ($1.$2,$4);
-       if ($star eq '*') { $star = 'star';}
-       else { $after = $star.$after; $star = ''; }
-       $wrapper = "wrap_cmd_$cmd"; $teststar = $wrapper.'star';
-       if ($star && defined &$teststar) { $wrapper = $teststar; $star = '*'; }
-        # MRO: make {\bf**} work
-       elsif($star) { $after = '*'.$after; $star = '' }
-       print "\nWRAPPED: $cmd as $wrapper" if ($VERBOSITY > 5);
-
-       # ensure that the result is separated from following words...
-       my $padding = ($after =~ /^[a-zA-Z]/s)? ($cmd =~ /\W$/ ? '':' '):'';
-
-       if ($raw_arg_cmds{$cmd} && defined &$wrapper) {
-            $* = 1;
-           ($wrap, $_) = &$wrapper("\\$cmd$star", $padding . $after);
-            $* = 0;
-           # ...but don't leave an unwanted space at the beginning
-           $_ =~ s/^ //s if($padding && $wrap !~ /\w$/m
-               && (length($_) == length($after)+1) );
-           push (@processed, $wrap);
-       } elsif ($raw_arg_cmds{$cmd}) {
-           print STDERR "\n*** $wrapper not defined, cannot wrap \\$cmd";
-           &write_warnings("\n*** $wrapper not defined, cannot wrap \\$cmd ");
-           push (@processed, "\\$cmd$padding");
-           $_ = $after;
-       } else {
-           push (@processed, "\\$cmd$padding");
-           $_ = $after;
-       }
-        last unless ($after =~ /\\/);
-    }
-
-    # recombine the pieces
-    $_ = join('',@processed, $_);
-}
-
-#########################################################################
-
-# To make a table of contents, list of figures and list of tables commands
-# create a link to corresponding files which do not yet exist.
-# The binding of the file variable in each case acts as a flag
-# for creating the actual file at the end, after all the information
-# has been gathered.
-
-sub do_cmd_tableofcontents { &do_real_tableofcontents(@_) }
-sub do_real_tableofcontents {
-#    local($_) = @_;
-    if ((defined &do_cmd_contentsname)||$new_command{'contentsname'}) {
-       local($br_id)=++$global{'max_id'};
-       $TITLE = &translate_environments("$O$br_id$C\\contentsname$O$br_id$C");
-    } else { $TITLE = $toc_title }
-    $toc_sec_title = $TITLE;
-    $tocfile = $CURRENT_FILE;  # sets  $tocfile  this globally
-    local $toc_head = $section_headings{'tableofcontents'};
-    if ($toc_style) {
-       $toc_head .= " CLASS=\"$toc_style\"";
-       $env_style{"$toc_head.$toc_style"} = " "
-           unless ($env_style{"$toc_head.$toc_style"});
-    }
-    local($closures,$reopens) = &preserve_open_tags();
-    join('', "<BR>\n", $closures
-       , &make_section_heading($TITLE, $toc_head), $toc_mark
-       , $reopens, @_[0]);
-}
-sub do_cmd_listoffigures {
-    local($_) = @_;
-    local($list_type) = ($SHOW_SECTION_NUMBERS ? 'UL' : 'OL' );
-    if ((defined &do_cmd_listfigurename)||$new_command{'listfigurename'}) {
-       local($br_id)=++$global{'max_id'};
-       $TITLE = &translate_environments("$O$br_id$C\\listfigurename$O$br_id$C");
-    } else { $TITLE = $lof_title }
-    $toc_sec_title = $TITLE;
-    $loffile = $CURRENT_FILE;  # sets  $loffile  this globally
-    local $lof_head = $section_headings{'listoffigures'};
-    local($closures,$reopens) = &preserve_open_tags();
-    join('', "<BR>\n", $closures
-        , &make_section_heading($TITLE, $lof_head)
-        , "<$list_type>", $lof_mark, "</$list_type>"
-        , $reopens, $_);
-}
-sub do_cmd_listoftables {
-    local($_) = @_;
-    local($list_type) = ($SHOW_SECTION_NUMBERS ? 'UL' : 'OL' );
-    if ((defined &do_cmd_listtablename)||$new_command{'listtablename'}) {
-       local($br_id)=++$global{'max_id'};
-       $TITLE = &translate_environments("$O$br_id$C\\listtablename$O$br_id$C");
-    } else { $TITLE = $lot_title }
-    $toc_sec_title = $TITLE;
-    $lotfile = $CURRENT_FILE;  # sets  $lotfile  this globally
-    local $lot_head = $section_headings{'listoftables'};
-    local($closures,$reopens) = &preserve_open_tags();
-    join('', "<BR>\n", $closures
-        , &make_section_heading($TITLE, $lot_head)
-        , "<$list_type>", $lot_mark, "</$list_type>"
-        , $reopens, $_);
-}
-
-# Indicator for where to put the CHILD_LINKS table.
-sub do_cmd_tableofchildlinks {
-    local($_) = @_;
-    local($thismark) = $childlinks_mark;
-    local($option,$dum) = &get_next_optional_argument;
-    $thismark = &check_childlinks_option($option) if ($option);
-    local($pre,$post) = &minimize_open_tags("$thismark\#0\#");
-    join('', "<BR>", $pre, $_);
-}
-
-# leave out the preceding <BR>
-sub do_cmd_tableofchildlinksstar {
-    local($_) = @_;
-    local($thismark) = $childlinks_mark;
-    local($option,$dum) = &get_next_optional_argument;
-    $thismark = &check_childlinks_option($option) if ($option);
-    local($pre,$post) = &minimize_open_tags("$thismark\#1\#");
-    join('', $pre, $_);
-}
-
-sub check_childlinks_option {
-    local($option) = @_;
-    if ($option =~ /none/i) {
-       $childlinks_mark = $childlinks_null_mark;
-       $childlinks_null_mark }
-    elsif ($option =~ /off/i) { $childlinks_null_mark }
-    elsif ($option =~ /all/i) {
-       $childlinks_mark = $childlinks_on_mark;
-       $childlinks_on_mark }
-    elsif ($option =~ /on/i) { $childlinks_on_mark }
-}
-
-sub remove_child_marks {
-    # Modifies $_
-    s/($childlinks_on_mark|$childlinks_null_mark)\#\d\#//go;
-}
-
-
-sub do_cmd_htmlinfo {
-    local($_) = @_;
-    local($option,$dum) = &get_next_optional_argument;
-    if ($option =~ /^(off|none)/i) { $INFO = 0; return ($_) }
-    local($pre,$post) = &minimize_open_tags($info_title_mark.$info_page_mark);
-    join('', "<BR>", $pre, $_);
-}
-sub do_cmd_htmlinfostar {
-    local($_) = @_;
-    local($option,$dum) = &get_next_optional_argument;
-    if ($option =~ /^(off|none)/i) { $INFO = 0; return ($_) }
-    local($pre,$post) = &minimize_open_tags($info_page_mark);
-    join('', $pre, $_);
-}
-
-# $idx_mark will be replaced with the real index at the end
-sub do_cmd_textohtmlindex {
-    local($_) = @_;
-    if ((defined &do_cmd_indexname )||$new_command{'indexname'}) {
-       local($br_id)=++$global{'max_id'};
-       $TITLE = &translate_environments("$O$br_id$C\\indexname$O$br_id$C");
-    } else { $TITLE = $idx_title }
-    $toc_sec_title = $TITLE;
-    $idxfile = $CURRENT_FILE;
-    if (%index_labels) { &make_index_labels(); }
-    if (($SHORT_INDEX) && (%index_segment)) { &make_preindex(); }
-    else { $preindex = ''; }
-    local $idx_head = $section_headings{'textohtmlindex'};
-    local($heading) = join(''
-       , &make_section_heading($TITLE, $idx_head)
-       , $idx_mark );
-    local($pre,$post) = &minimize_open_tags($heading);
-    join('',"<BR>\n" , $pre, $_);
-}
-
-#RRM: added 17 May 1996
-# allows labels within the printable key of index-entries,
-# when using  makeidx.perl
-sub make_index_labels {
-    local($key, @keys);
-    @keys = keys %index_labels;
-    foreach $key (@keys) {
-       if (($ref_files{$key}) && !($ref_files{$key} eq "$idxfile")) {
-           local($tmp) = $ref_files{$key};
-           &write_warnings("\nmultiple label $key , target in $idxfile masks $tmp ");
-       }
-       $ref_files{$key} .= "$idxfile";
-    }
-}
-#RRM: added 17 May 1996
-# constructs a legend for the SHORT_INDEX, with segments
-# when using  makeidx.perl
-sub make_preindex { &make_real_preindex }
-sub make_real_preindex {
-    local($key, @keys, $head, $body);
-    $head = "<HR>\n<H4>Legend:</H4>\n<DL COMPACT>";
-    @keys = keys %index_segment;
-    foreach $key (@keys) {
-       local($tmp) = "segment$key";
-       $tmp = $ref_files{$tmp};
-       $body .= "\n<DT>$key<DD>".&make_named_href('',$tmp,$index_segment{$key});
-#      $body .= "\n<DT>$key<DD>".&make_named_href('',
-#              $tmp."\#CHILD\_LINKS",$index_segment{$key})
-#                   unless ($CHILD_STAR);
-    }
-    $preindex = join('', $head, $body, "\n</DL>") if ($body);
-}
-
-sub do_cmd_printindex { &do_real_printindex(@_); }
-sub do_real_printindex {
-    local($_) = @_;
-    local($which) = &get_next_optional_argument;
-    $idx_name = $index_names{$which}
-       if ($which && $index_names{$which});
-    @_;
-}
-
-sub do_cmd_newindex {
-    local($_) = @_;
-    local($dum,$key,$title);
-    $key = &missing_braces unless (
-       (s/$next_pair_pr_rx/$key=$2;''/eo)
-       ||(s/$next_pair_rx/$key=$2;''/eo));
-    $dum = &missing_braces unless (
-       (s/$next_pair_pr_rx/$dum=$2;''/eo)
-       ||(s/$next_pair_rx/$dum=$2;''/eo));
-    $dum = &missing_braces unless (
-       (s/$next_pair_pr_rx/$dum=$2;''/eo)
-       ||(s/$next_pair_rx/$dum=$2;''/eo));
-    $title = &missing_braces unless (
-       (s/$next_pair_pr_rx/$title=$2;''/eo)
-       ||(s/$next_pair_rx/$title=$2;''/eo));
-    $index_names{$key} = $title if ($key && $title);
-    @_;
-}
-
-# FOOTNOTES , also within Mini-page environments
-# allow easy way to override and inherit; e.g. for frames 
-
-sub do_cmd_footnotestar { &do_real_cmd_footnote(@_) }
-sub do_cmd_footnote { &do_real_cmd_footnote(@_) }
-sub do_real_cmd_footnote {
-    local($_) = @_;
-    local($cnt,$marker,$smark,$emark)=('', $footnote_mark);
-    local($mark,$dum) = &get_next_optional_argument;
-    local($anchor_name);
-
-    $footfile = "${PREFIX}$FOOT_FILENAME$EXTN"
-       unless ($footfile||$MINIPAGE||$NO_FOOTNODE);
-
-    if ($mark) { 
-       $cnt = $mark;
-       if ($MINIPAGE) { $global{'mpfootnote'} = $cnt }
-       else { $global{'footnote'} = $cnt }
-    } else {
-       $cnt = (($MINIPAGE)? ++$global{'mpfootnote'} : ++$global{'footnote'});
-    }
-    local($br_id, $footnote)=(++$global{'max_id'},'');
-    $footnote = &missing_braces unless (
-        (s/$next_pair_pr_rx/${br_id}=$1; $footnote=$2;''/eo)
-       ||(s/$next_pair_rx/${br_id}=$1; $footnote=$2;''/eo));
-    $br_id = "mp".$br_id if ($MINIPAGE);
-    $marker = &get_footnote_mark($MINIPAGE);
-    local($last_word) = &get_last_word();
-    local($href) = &make_href("$footfile#foot$br_id",$marker);
-    if ($href =~ /NAME="([^"]*)"/) { $anchor_name=$1 }
-    $last_word .= $marker unless ($anchor_name);
-    &process_footnote($footnote,$cnt,$br_id,$last_word,$mark
-             ,($MINIPAGE? $marker : '')
-             ,($MINIPAGE? '' : "$marker:$anchor_name") );
-    # this may not work if there is a <BASE> tag and !($file) !!! #
-#   join('',&make_href("$file#foot$br_id",$marker),$_);
-    $href . $_ 
-}
-
-sub process_image_footnote {
-    # MRO: modified to use $_[0]
-    # local(*math) = @_;
-    local($in_image, $keep, $pre, $this_anchor, $out, $foot_counters_recorded, @foot_anchors) = (1,'','');
-    local($image_contents) = $_[0];
-    $image_contents =~ s/\\(begin|end)(($O|$OP)\d+($C|$CP))tex2html_\w+\2//go;
-    $image_contents =~ s!(\\footnote(mark\b\s*(\[[^\]]*\])?|\s*(\[[^\]]*\])?\s*(($O|$OP)\d+($C|$CP))(.*)\5))!
-       $keep = $`; $out = '\footnotemark '.$3.$4;
-        #MRO: $*=1; local($saveRS) = $/; $/='';
-       if ($8) {
-           $this_anchor = &do_cmd_footnote($2);
-       } else {
-           $this_anchor = &do_cmd_footnotemark($3);
-       }
-        #MRO: $*=0; $/ = $saveRS;
-       $foot_counters_recorded = 1;
-       push(@foot_anchors, $this_anchor);
-       $out!oesg;
-    $_[0] = $image_contents;
-    @foot_anchors;
-}
-
-sub do_cmd_thanks { &do_cmd_footnote(@_); }
-
-sub get_footnote_mark {
-    local($mini) = @_;
-    return($footnote_mark) if ($HTML_VERSION < 3.0 );
-    local($cmd,$tmp,@tmp,$marker);
-    $cmd = "the". (($mini)? 'mp' : '') . "footnote";
-    if ($new_command{$cmd}) {
-       $tmp = "do_cmd_$cmd";
-       @tmp = split (':!:', $new_command{$cmd});
-       pop @tmp; $tmp = pop @tmp;
-       if ($tmp =~ /$O/) {
-###        local($_) = &translate_commands($tmp);
-           $marker = &translate_commands(&translate_environments($tmp));
-           &make_unique($marker);
-###        $marker = $_;
-       } else { $marker = &translate_commands(&translate_environments($tmp)); }
-    } elsif ($mini) {
-       $marker = &translate_commands('\thempfootnote');
-    } elsif ((defined &do_cmd_thefootnote)||$new_command{'thefootnote'}) { 
-       local($br_id)=++$global{'max_id'};
-       $marker = &translate_environments("$O$br_id$C\\thefootnote$O$br_id$C");
-    } else { $marker = $footnote_mark; }
-    join('','<SUP>',$marker,'</SUP>');
-}
-
-sub make_numbered_footnotes {
-    eval "sub do_cmd_thefootnote {\&numbered_footnotes}" }
-sub numbered_footnotes { &do_cmd_arabic('<<0>>footnote<<0>>');}
-
-# default numbering style for minipage notes
-sub do_cmd_thempfootnote { &do_cmd_arabic('<<0>>mpfootnote<<0>>'); }
-
-sub do_cmd_footnotemark { &do_real_cmd_footnotemark(@_) }
-sub do_real_cmd_footnotemark {
-    local($_) = @_;
-    local($br_id, $footnote,$marker,$mpnote,$tmp,$smark,$emark);
-    # Don't use ()'s for the optional argument!
-    local($mark,$dum) = &get_next_optional_argument;
-    local ($cnt,$text_known) = ('','');
-    if ($mark) {
-       $cnt = (($mark =~ /\\/)? &translate_commands($mark) : $mark);
-       if (($MINIPAGE)&&($mpfootnotes{$cnt})) {
-           $mpnote = 1;
-           $br_id  = $mpfootnotes{$cnt};
-           $text_known = 1;
-       } else {
-           $global{'footnote'} = $cnt;
-           local($tmp) = $footnotes{$cnt};
-           if ($tmp) {
-               $br_id  = $tmp;
-               $text_known = 1;
-           } else { $footnotes{$cnt} = $br_id }
-       }
-    } else {
-       $cnt = ++$global{'footnote'};
-       $text_known = 1 if ($footnotes{$cnt});
-    }
-    if ($text_known) {
-       $br_id = ($MINIPAGE ? $mpfootnotes{$cnt} : $footnotes{$cnt});
-       $marker = &get_footnote_mark($mpnote);
-       return (join('', &make_href("$footfile#foot$br_id",$marker),$_));
-    }
-    
-    local($last_word) = &get_last_word() unless ($mpnote);
-
-    # Try to find a  \footnotetext  further on.
-    do {
-       if (s/\\footnotetext\s*\[\s*$cnt\s*]*\]\s*$any_next_pair_pr_rx//o) {
-           ($br_id, $footnote) = ($2, $3);  
-       } else { 
-           $br_id = "fnm$cnt";
-           $footnotes{$cnt} = $br_id;
-       }
-    } unless ($br_id);
-
-    $marker = &get_footnote_mark($mpnote);
-    $last_word .= $marker unless ($marker =~ /$footnote_mark/ );
-    if ($footnote) {
-       # found a  \footnotetext  further on
-       &process_footnote($footnote,$cnt,$br_id,$last_word,$mark);
-       join('',&make_named_href("foot$br_id","$footfile#$br_id",$marker),$_);
-    } elsif ($br_id =~ /fnm/) {
-       # no  \footnotetext  yet, so make the entry in $footnotes
-       &process_footnote('',$cnt,$br_id,$last_word,$mark);
-       # this may not work if there is a <BASE> tag and !($footfile) !!! #
-       join('',&make_named_href("foot$br_id","$footfile#$br_id",$marker),$_);
-    } elsif ($br_id) {
-       # \footnotetext  already processed
-       if ($mpnote) {
-           $mpfootnotes =~ s/(=\"$br_id\">...)(<\/A>)/$1$last_word$3/
-               if ($last_word);
-           # this may not work if there is a <BASE> tag !!! #
-           join('',&make_named_href("foot$br_id","#$br_id",$marker),$_);
-       } else {
-           $footnotes =~ s/(=\"$br_id\">...)(<\/A>)/$1$last_word$3/;
-           # this may not work if there is a <BASE> tag and !($footfile) !!! #
-           join(''
-               ,&make_named_href("foot$br_id","$footfile#$br_id",$marker),$_);
-       }
-    } else { 
-       print "\nCannot find \\footnotetext for \\footnotemark $cnt";
-       # this may not work if there is a <BASE> tag and !($footfile) !!! #
-       join('',&make_named_href("foot$br_id","$footfile",$marker),$_);
-    }
-}
-
-# Under normal circumstances this is never executed. Any commands \footnotetext
-# should have been processed when the corresponding \footnotemark was
-# encountered. It is possible however that when processing pieces of text
-# out of context (e.g. \footnotemarks in figure and table captions)
-# the pair of commands gets separated. Until this is fixed properly,
-# this command just puts the footnote in the footnote file in the hope
-# that its context will be obvious ....
-sub do_cmd_footnotetext {
-    local($_) = @_;
-    local($mark,$dum) = &get_next_optional_argument;
-    local($br_id, $footnote, $prev, $key)=(1,'','','');
-    $footnote = &missing_braces unless (
-       (s/$next_pair_pr_rx/($br_id,$footnote)=($1,$2);''/eo)
-       ||(s/$next_pair_rx/($br_id,$footnote)=($1,$2);''/eo));
-
-    $mark = $global{'footnote'} unless $mark;
-    $prev = $footnotes{$mark};
-    if ($prev) {
-       $prev = ($MINIPAGE ? 'mp' : '') . $prev;
-       # first prepare the footnote-text
-       $footnote = &translate_environments("${OP}$br_id$CP$footnote${OP}$br_id$CP")
-            if ($footnote);
-       $footnote = &translate_commands($footnote) if ($footnote =~ /\\/);
-
-       # now merge it onto the Footnotes page
-       $footnotes =~ s/(=\"$prev\">\.\.\.)(.*<\/A>)(<\/DT>\n<DD>)\n/
-               $1.'<html_this_mark>'.$3.$footnote/e;
-       local($this_mark) = $2;
-       $this_mark =~ s|(<SUP>)(?:<#\d+#>)?(\d+)(?:<#\d+#>)?(<\/SUP>)(<\/A>)$|
-               "$4<A\n HREF=\"$CURRENT_FILE\#foot$prev\">$1$2$3$4"|e;
-       $footnotes =~ s/<html_this_mark>/$this_mark/;
-    } else {
-       &process_footnote($footnote,$mark,$br_id,'','') if $footnote;
-    }
-    $_;
-}
-
-
-sub process_footnote {
-    # Uses $before
-    # Sets $footfile defined in translate
-    # Modifies $footnotes defined in translate
-    local($footnote, $cnt, $br_id, $last_word, $mark, $mini, $same_page) = @_;
-    local($target) = $target;
-
-    # first prepare the footnote-text
-    local($br_idd, $fcnt); $br_id =~ /\D*(\d+)/; $br_idd = $1;
-    $footnote = &translate_environments("$O$br_idd$C$footnote$O$br_idd$C")
-       if ($footnote);
-    $footnote = &translate_commands($footnote) if ($footnote =~ /\\/);
-
-    local($space,$sfoot_style,$efoot_style) = ("\n",'','');
-    if ((!$NO_FOOTNODE)&&(!$mini)&&(!$target)) {
-       $footfile = "${PREFIX}$FOOT_FILENAME$EXTN";
-       $space = ".\n" x 30;
-       $space = "\n<PRE>$space</PRE>";
-    } elsif ($target) {
-       $target = $frame_body_name
-           if (($frame_body_name)&&($target eq $frame_foot_name));
-       $sfoot_style = '<SMALL>';
-       $efoot_style = '</SMALL>';
-    }
-
-    if ($mark) {
-       if ($mini) {
-           $cnt = $mpfootnotes{$mark};
-           if ($in_image) {
-               $fcnt = $global{'mpfootnote'}; --$fcnt if $fcnt;
-               $latex_body .= '\setcounter{mpfootnote}{'.($fcnt||"0")."}\n"
-                   unless ($foot_counters_recorded);
-           }
-       } else {
-           $cnt = $footnotes{$mark};
-           if ($in_image) {
-               $fcnt = $global{'footnote'}; --$fcnt if $fcnt;
-               $latex_body .= '\setcounter{footnote}{'.($fcnt||"0")."}\n"
-                   unless ($foot_counters_recorded);
-           }
-       }
-       if ($cnt) { 
-           &write_warnings("\nredefined target for footnote $mark" )
-               unless ( $cnt eq $br_id )
-       }
-       if ($mini) { $mpfootnotes{$mark} = "$br_id" }
-       elsif ($br_id =~ /fnm\d+/) {
-           $mark = "$footnotes{$cnt}";
-           $footnotes{$cnt} = "$br_id";
-#          $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">..."
-           $footnotes .= "\n<DT>$sfoot_style<A NAME=\"$br_id\">..."
-               . $last_word . "</A>$efoot_style</DT>\n<DD>\n"
-               . $space . "\n</DD>";
-           return;
-       } else { $footnotes{$mark} = "$br_id" }
-    } else {
-       if ($mini) {
-           $mpfootnotes{$cnt} = "$br_id";
-           if ($in_image) {
-               $fcnt = $global{'mpfootnote'}; --$fcnt if $fcnt;
-               $latex_body .= '\setcounter{mpfootnote}{'.($fcnt||"0")."}\n"
-                   unless ($foot_counters_recorded);
-           }
-       } else {
-           $footnotes{$cnt} = "$br_id";
-           if ($in_image) {
-               $fcnt = $global{'footnote'}; --$fcnt if $fcnt;
-               $latex_body .= '\setcounter{footnote}{'.($fcnt||"0")."}\n"
-                   unless ($foot_counters_recorded);
-           }
-       }
-    }
-
-    # catch a \footnotemark *after* the \footnotetext
-    if ((!$footnote)&&($last_word)&&(!$mini)) {
-#      $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">..."
-       $footnotes .= "\n<DT>$sfoot_style<A NAME=\"$br_id\">..."
-           . $last_word
-           . "</A>$efoot_style</DT>\n<DD>\n" . $space . "\n</DD>";
-
-    } elsif ($mini) {
-       if ($HTML_VERSION < 3.0) { $mini .= "." }
-       $mpfootnotes .= "\n<DD>$sfoot_style<A NAME=\"foot$br_id\">$mini</A> " .
-           $footnote . $efoot_style . "\n</DD>\n";
-    } elsif ($same_page) {
-       local($link,$text);
-       $same_page =~ s/:/$text=$`;$link=$';''/e;
-       $same_page = &make_named_href("","$CURRENT_FILE\#$link",$text) if($link);
-       $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">...$last_word</A>"
-           . $same_page . $efoot_style . "</DT>\n<DD>" . $sfoot_style
-           . $footnote . $efoot_style . "\n". $space . "\n</DD>";
-    } else {
-       $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">...$last_word</A>"
-               . $efoot_style . "</DT>\n<DD>" . $sfoot_style
-               . $footnote . "$efoot_style\n" . $space . "\n</DD>";
-    }
-}
-
-
-sub do_cmd_appendix {
-    $latex_body .= "\\appendix\n";
-    if ($section_commands{$outermost_level} == 3) {
-       $global{'section'} = 0;
-       &reset_dependents('section');
-       eval "sub do_cmd_thesection{ &do_cmd_the_appendix(3,\@_) }";
-    } else {
-       $global{'chapter'} = 0;
-       &reset_dependents('chapter');
-       eval "sub do_cmd_thechapter{ &do_cmd_the_appendix(2,\@_) }";
-    }
-    $_[0];
-}
-
-sub do_cmd_the_appendix {
-    local($val,$level) = (0,$_[0]);
-    if ($level == 3) { $val=$global{'section'} }
-    elsif ($level == 2) { $val=$global{'chapter'} }
-    join('', &fAlph($val), '.', $_[1]);
-}
-
-sub do_cmd_appendixname { $app_title . $_[0] }
-sub do_cmd_abstractname { $abs_title . $_[0] }
-sub do_cmd_keywordsname { $key_title . $_[0] }
-sub do_cmd_subjclassname { $sbj_title . $_[0] }
-sub do_cmd_indexname { $idx_title . $_[0] }
-sub do_cmd_contentsname { $toc_title . $_[0] }
-sub do_cmd_datename { $date_name . $_[0] }
-sub do_cmd_refname { $ref_title . $_[0] }
-sub do_cmd_bibname { $bib_title . $_[0] }
-sub do_cmd_figurename { $fig_name . $_[0] }
-sub do_cmd_listfigurename { $lof_title . $_[0] }
-sub do_cmd_tablename { $tab_name . $_[0] }
-sub do_cmd_listtablename { $lot_title . $_[0] }
-sub do_cmd_partname { $part_name . $_[0] }
-sub do_cmd_chaptername { $chapter_name . $_[0] }
-sub do_cmd_sectionname { $section_name . $_[0] }
-sub do_cmd_subsectionname { $subsection_name . $_[0] }
-sub do_cmd_subsubsectionname { $subsubsection_name . $_[0] }
-sub do_cmd_paragraphname { $paragraph_name . $_[0] }
-sub do_cmd_thmname { $thm_title . $_[0] }
-sub do_cmd_proofname { $prf_name . $_[0] }
-sub do_cmd_footnotename { $foot_title . $_[0] }
-sub do_cmd_childlinksname { '<STRONG>'.$child_name.'</STRONG>'. $_[0] }
-sub do_cmd_infopagename { $info_title . $_[0] }
-
-
-sub do_cmd_ref {
-    local($_) = @_;
-    &process_ref($cross_ref_mark,$cross_ref_mark);
-}
-
-sub do_cmd_eqref {
-    local($_) = @_;
-    join('','(',&process_ref($cross_ref_mark,$cross_ref_mark,'',')'));
-}
-
-sub do_cmd_pageref {
-    local($_) = @_;
-    &process_ref($cross_ref_mark,$cross_ref_visible_mark);
-}
-
-# This is used by external style files ...
-sub process_ref {
-    local($ref_mark, $visible_mark, $use_label, $after_label) = @_;
-    $use_label = &balance_inner_tags($use_label) 
-       if $use_label =~ (/<\/([A-Z]+)>($math_verbatim_rx.*)<\1>/);
-    $use_label = &translate_environments($use_label);
-    $use_label = &simplify(&translate_commands($use_label))
-       if ($use_label =~ /\\/ );
-    local($label,$id);
-    local($pretag) = &get_next_optional_argument;
-    $pretag = &translate_commands($pretag) if ($pretag =~ /\\/);    
-    $label = &missing_braces unless (
-       (s/$next_pair_pr_rx/($id, $label) = ($1, $2);''/eo)
-       ||(s/$next_pair_rx/($id, $label) = ($1, $2);''/eo));
-    if ($label) {
-       $label =~ s/<[^>]*>//go ; #RRM: Remove any HTML tags
-       $label =~ s/$label_rx/_/g;      # replace non alphanumeric characters
-
-       $symbolic_labels{"$pretag$label$id"} = $use_label if ($use_label);
-       if (($symbolic_labels{$pretag.$label})&&!($use_label)) {
-           $use_label = $symbolic_labels{$pretag.$label}
-       }
-#      if (!($use_label eq $label)) {
-#          $symbolic_labels{"$label$id"} = $use_label;
-#      };
-       # if $use_label is empty then $label is used as the cross_ref_mark
-       # elseif $use_label is a string then $use_label is used
-        # else the usual mark will be used
-       $use_label = ( (!$use_label && $label) || $use_label);
-
-       print "\nLINK: $ref_mark\#$label\#$id  :$use_label:" if ($VERBOSITY > 3);
-       # The quotes around the HREF are inserted later
-       join('',"<A HREF=$ref_mark#$label#$id>$visible_mark<\/A>",$after_label, $_);
-    }
-    else {
-       print "Cannot find label argument after <$last_word>\n" if $last_word;
-       $after_label . $_;
-    }
-}
-
-#RRM:  This removes unbalanced tags, due to closures for math inside 
-#      the label-text for an <A> anchor.
-sub balance_inner_tags {
-    local($text) = @_;
-    return($text) unless ($text =~ /<\/([A-Z]+)>(\s*$math_verbatim_rx.*)(<\1( [^>]*)?>)/);
-    local($beforeT,$afterT,$tag,$math_verb,$stag) = ($`,$',$1,$2,$3);
-    if (!($beforeT =~ /<$tag>/)) { 
-       $text = join('', $beforeT, $math_verb, $afterT);
-       return (&balance_inner_tags($text));
-    }
-    local(@pieces) = split (/<$tag>/, $beforeT );
-    $beforeT = shift (@pieces);
-    local($cnt,$this) = (0,'');
-    while (@pieces) {
-       $this = shift @pieces;
-       $cnt++;
-       $beforeT .= "<$tag>".$this;
-       $cnt = $cnt - ($this =~ /<\/$tag>/g);
-    }
-    if ($cnt) { 
-       $beforeT .= "<\/$tag>" . $math_verb . $stag;
-       $text = $beforeT . $afterT;
-    } else {
-       $beforeT .= $math_verb;
-       $text = join('', $beforeT, $math_verb, $afterT);
-       return (&balance_inner_tags($text));
-    }
-    $text;
-}
-
-# Uses $CURRENT_FILE defined in translate
-sub do_cmd_label {
-    local($_) = @_;
-    local($label);
-    $label = &missing_braces unless (
-       (s/$next_pair_pr_rx\n?/$label = $2;''/eo)
-       ||(s/$next_pair_rx\n?/$label = $2;''/eo));
-    &anchor_label($label,$CURRENT_FILE,$_);
-}
-
-# This subroutine is also used to process labels in undefined environments
-sub anchor_label { &real_anchor_label(@_) }
-sub real_anchor_label {
-    # Modifies entries in %ref_files defined in translate
-    local($label,$filename,$context) = @_;
-    $label =~ s/<[^>]*>//go;   #RRM: Remove any HTML tags
-    $label =~ s/$label_rx/_/g; # replace non alphanumeric characters
-    # Associate the label with the current file
-    if ($ref_files{$label} ne $filename) {
-       $ref_files{$label} = $filename;
-       $noresave{$label} = 0; $changed = 1; }
-    print "<LABEL: $label>" if ($VERBOSITY > 3);
-    join('',"<A NAME=\"$label\">$anchor_mark</A>",$context);
-}
-
-sub do_cmd_cite {
-    local($_) = @_;
-    &process_cite('','');
-}
-
-
-# This just creates a link from a label (yet to be determined) to the
-# cite_key in the citation file.
-sub process_cite { &process_real_cite(@_) }
-sub process_real_cite {
-    local($mode,$text) = @_;
-    my $has_text = (($text)? 1 : 0);
-#    local($target) = 'contents';print "\nCITE:$text";
-    # process the text from \htmlcite or \hypercite
-    if ($has_text) {
-       $text = &balance_inner_tags($text) 
-           if $use_label =~ (/<\/([A-Z]+)>($math_verbatim_rx.*)<\1>/);
-       $text = &translate_environments($text);
-       $text = &simplify(&translate_commands($text))
-           if ($use_label =~ /\\/ );
-    }
-
-    my $label, $cite_key, $pretag, @cite_keys;
-    local($optional_text,$dummy) =  &get_next_optional_argument;
-    if ($mode =~ /external/) {
-#      $target = '';
-       $pretag = $optional_text; $optional_text = '';
-       $pretag = &translate_commands($pretag) if ($pretag =~ /\\/);
-    } else {
-       $optional_text = ", $optional_text" if $optional_text;
-    }
-    s/^\s*\\space//o;          # Hack - \space is inserted in .aux
-    s/$next_pair_pr_rx//o||s/$next_pair_rx//o;
-    if (!($cite_key = $2)) {
-       print "\n *** Cannot find citation argument\n";
-       return ($_);
-    }
-    @cite_keys = (split(/,/,$cite_key));
-    my ($citations, $join) = ('',',');
-    $join  = '' if ($text);
-    foreach $cite_key (@cite_keys) {
-       $cite_key =~ s/(^\s+|\s+$)//g;
-       $cite_key =~ s/(^\s+|\s+$)//g;
-    # RRM:  if the URL and printable-key are known already, then use them...
-       $cite_key =~ s/$label_rx/_/g;
-       $label = $cite_key;
-       if ($mode eq "nocite") {
-           # nothing more to do, no citations
-       } elsif ( ($SEGMENT) && ($cite_info{$cite_key})
-               && ($ref_files{"cite_$cite_key"}) ) {
-           $join  = "," unless ($text);
-           $text = $cite_info{$cite_key} unless ($text);
-           $citations .= join('', $join
-               , &make_named_href($label,$ref_files{'cite_'."$cite_key"},$text));
-       } elsif (($mode eq "external")&&($external_labels{$pretag."cite_$cite_key"})) {
-           $join  = "," unless ($text);
-           $text = $cross_ref_visible_mark unless ($text);
-           $citations .= join('', $join
-               , &make_named_href($label
-                   , $external_labels{$pretag.'cite_'."$cite_key"}."\#$label"
-                   , $text)
-               );
-       } elsif ($mode eq 'external') {
-           $join  = "," unless ($text);
-           &write_warnings("\nExternal reference missing for citation: $pretag$cite_key");
-           $citations .= "$text$join#!$pretag$cite_key!#";
-        } else {
-           $join  = "," unless ($text);
-           #Replace the key...
-           $citations .= "$join#$cite_key#$cite_mark#$bbl_nr#$text#$cite_mark#";
-        }
-       $text = '';
-    }
-    $citations =~ s/^\s*,\s*//;
-    if ($has_text) { join('', $citations,  $optional_text, $_) }
-    else { join('', "[", $citations,  $optional_text, "]", $_) }
-}
-
-sub do_cmd_index { &do_real_index(@_) }
-sub do_real_index {
-    local($_) = @_;
-    local($br_id, $str);
-    local($idx_option) = &get_next_optional_argument;
-    $str = &missing_braces unless (
-       (s/$next_pair_pr_rx/($br_id, $str) = ($1, $2);''/eo)
-       ||(s/$next_pair_rx/($br_id, $str) = ($1, $2);''/eo));
-    join('',&make_index_entry($br_id,$str),$_);
-}
-sub do_cmd_indexstar { &do_cmd_index(@_) }
-
-# RRM: \bibcite supplies info via the .aux file; necessary with segmented docs.
-sub do_cmd_bibcite {
-    local($_) = @_;
-    local($br_id, $cite_key,$print_key);
-    $cite_key = &missing_braces unless (
-       (s/$next_pair_pr_rx/($br_id, $cite_key) = ($1, $2);''/eo)
-       ||(s/$next_pair_rx/($br_id, $cite_key) = ($1, $2);''/eo));
-    $print_key = &missing_braces unless (
-       (s/$next_pair_pr_rx/($br_id, $print_key) = ($1, $2);''/eo)
-       ||(s/$next_pair_rx/($br_id, $print_key) = ($1, $2);''/eo));
-    $cite_key =~ s/$label_rx/_/g;
-    $cite_info{$cite_key} = $print_key;
-    $_;
-}
-
-# This command will only be encountered inside a thebibliography environment.
-sub do_cmd_bibitem { &do_real_bibitem($CURRENT_FILE, @_) }
-sub do_real_bibitem {
-    local($thisfile, $_) = @_;
-    # The square brackets may contain the label to be printed
-    local($label, $dummy) = &get_next_optional_argument;
-    # Support for the "named" bibliography style
-    if ($label) {
-       $label =~ s/\\protect//g;
-       $label = &translate_commands($label) if ($label =~ /\\/);
-    }
-    local($cite_key);
-    $cite_key = &missing_braces unless (
-       ( s/$next_pair_pr_rx/$cite_key=$2;''/e )
-       ||( s/$next_pair_rx/$cite_key=$2;''/e ));
-
-    $cite_key =~ s/$label_rx/_/g;
-    $label = $cite_info{$cite_key} unless $label; # read from .aux file
-    $label = ++$bibitem_counter unless $label; # Numerical labels
-
-    if ($cite_key) {
-       # Associate the cite_key with the printed label.
-       # The printed label will be substituted back into the document later.
-       $cite_info{$cite_key} = &translate_commands($label);
-       if (!($ref_files{'cite_'."$cite_key"} eq $thisfile)) {
-           $ref_files{'cite_'."$cite_key"} = $thisfile;
-           $changed = 1; }
-
-        #RRM: apply any special styles, as defined below
-       $label = &bibitem_style($label) if (defined &bibitem_style);
-       # Create an anchor around the citation
-       join('',"<P></P><DT><A NAME=\"$cite_key\">$label</A>\n<DD>", $_);
-
-    } else {
-       print "Cannot find bibitem labels: $label\n";
-
-       #RRM: apply any special styles, as defined below
-       $label = &bibitem_style($label) if (defined &bibitem_style);
-       join('',"<P></P><DT>$label\n<DD>", $_); # AFEB added this line
-    }
-}
-
-#RRM: override this with a personal style, defined in  .latex2html-init
-#sub bibitem_style { join('','<STRONG>',$_[0],'</STRONG>') }
-sub bibitem_style {
-    return ($_[0]) unless $BIBITEM_STYLE;
-    local($text) = join(''
-       ,"${O}0$C",$BIBITEM_STYLE,"${O}1$C", @_, "${O}1$C","${O}0$C");
-    $text = &translate_environments($text);
-    &translate_commands($text);
-}
-
-sub do_cmd_newblock {
-    "<BR>".$_[0]
-}
-
-# This just reads in the $FILE.bbl file if it is available and appends
-# it to the items that are still to be processed.
-# The $FILE.bbl should contain a thebibliography environment which will
-# cause its contents to be processed later in the appropriate way.
-# (Note that it might be possible for both the \bibliography command and
-# the thebibliography environment to be present as the former may have been
-# added by the translator as a sectioning command. In this case (both present)
-# the $citefile would have already been set by the thebibliography environment)
-
-sub do_cmd_bibliography { &do_real_bibliography($CURRENT_FILE, @_) }
-sub do_real_bibliography {
-    local($thisfile, $after) = @_;
-    if ((defined &do_cmd_bibname)||$new_command{'bibname'}) {
-       local($br_id)=++$global{'max_id'};
-       $TITLE = &translate_environments("$O$br_id$C\\bibname$O$br_id$C");
-    } else { $TITLE = $bib_title }
-    $toc_sec_title = $TITLE;
-    return($_[0]) if ($making_name);
-    local($bibfile);
-    $bibfile = &missing_braces unless (
-       ($after =~ s/$next_pair_rx/$bibfile=$2;''/eo)||
-       ($after =~ s/$next_pair_rx_rx/$bibfile=$2;''/eo));
-
-    do {
-       unless ($citefile) {
-           $citefile = $thisfile;
-           if (&process_ext_file("bbl")) { # *** BINDS $_ as a side effect ***
-               $after = join('',$_,$after);}
-           else {
-               print "\nCannot open $FILE.bbl $!\n";
-               &write_warnings("\nThe bibliography file was not found.");
-               $after = join('',"\n<H2>No References!</H2>", $after);
-           }
-       }
-    print "\n";
-    } if $bibfile;
-    $after;
-}
-
-# allow for customised info-pages, for different languages
-sub do_cmd_textohtmlinfopage {
-    local($_) = @_;
-    local($linfo) = $TITLES_LANGUAGE . '_infopage';
-    if (defined &$linfo) { eval "&$linfo"; }
-    else { &default_textohtmlinfopage }
-}
-
-sub default_textohtmlinfopage {
-    local($_) = @_;
-    local($argv) = $argv;
-    if (-f "../$argv") { $argv = &make_href ("../$argv", $argv, ); }
-    $_ = ($INFO && $INFO =~ /^\d+$/
-      ? join('', $close_all
-       , "<STRONG>$t_title</STRONG><P>\nThis document was generated using the\n"
-       , "<A HREF=\"$TEX2HTMLADDRESS\"><STRONG>LaTeX</STRONG>2<tt>HTML</tt></A>"
-       , " translator Version $TEX2HTMLVERSION\n"
-       , "<P>Copyright &#169; 1993, 1994, 1995, 1996,\n"
-       , "<A HREF=\"$AUTHORADDRESS\">Nikos Drakos</A>, \n"
-       , "Computer Based Learning Unit, University of Leeds.\n"
-       , "<BR>Copyright &#169; 1997, 1998, 1999,\n"
-       , "<A HREF=\"$AUTHORADDRESS2\">Ross Moore</A>, \n"
-       , "Mathematics Department, Macquarie University, Sydney.\n"
-       , "<P>The command line arguments were: <BR>\n "
-       , "<STRONG>latex2html</STRONG> <TT>$argv</TT>\n"
-       , (($SHOW_INIT_FILE && ($INIT_FILE ne ''))?
-          "\n<P>with initialization from: <TT>$INIT_FILE</TT>\n$init_file_mark\n" :'')
-       , "<P>The translation was initiated by $address_data[0] on $address_data[1]"
-       , $open_all, $_)
-      : join('', $close_all, "$INFO\n", $open_all, $_));
-    $_;
-}
-
-
-# Try to translate LaTeX vertical space in a number of <BR>'s.
-# Eg. 1cm results in one + two extra <BR>'s.
-# To help the browser rendering is quite ugly, but why not.
-#
-sub get_vspace {
-    local($_) = @_;
-    local($vh) = 0;
-
-    return("<BR>") if /-/;
-
-    $vh = int($1 * $vspace_12pt{$2} + 0.5)
-       if (/([0-9.]+)\s*([a-z]+)/);
-    join('',"<BR>","\n<BR>" x $vh);
-}
-
-sub do_cmd_vskip {
-    local($_) = @_;
-    &ignore_numeric_argument;
-    join('',&get_vspace($1),$_);
-}
-
-sub do_cmd_break {
-    local($_) = @_;
-    join('',"<BR>",$_);
-}
-
-sub do_cmd_vspace {
-    local($_) = @_;
-    local($how_much);
-    $how_much = &missing_braces unless (
-       (s/$next_pair_pr_rx/$how_much = $2;''/e)
-       ||(s/$next_pair_rx/$how_much = $2;''/e));
-    join('',&get_vspace($how_much),$_);
-}
-
-sub do_cmd_vspacestar {
-    &do_cmd_vspace;
-}
-
-sub do_cmd_d_backslash {
-    local($_) = @_;
-
-    # Eat space from &pre_process.
-    # We could also modifiy $single_cmd_rx and %normalize, but why not here.
-    s/^ \*?//;
-    local($spc,$dum)=&get_next_optional_argument;
-    # If the [...] occurs on the next line, then it is *not* an argument to \\ .
-    # MRO: replaced $* with /m
-    if ($dum =~ /\n/m) { 
-       $spc = $`;
-        $spc =~ s/\s//gm;
-        $_ = $'.$_ 
-    }
-    join('',(($spc)? &get_vspace($spc): "\n<BR>"),$_);
-}
-
-
-################## Commands used in the $FILE.aux file #######################
-
-sub do_cmd_jobname { $FILE . $_[0] }
-
-# This is used in $FILE.aux
-sub do_cmd_newlabel {
-    local($_) = @_;
-    local($label,$val,$tmp);
-    $label = &missing_braces unless (
-       (s/$next_pair_pr_rx/$label = $2;''/eo)
-       ||(s/$next_pair_rx/$label = $2;''/eo));
-    $tmp = &missing_braces unless (
-       (s/$next_pair_pr_rx/$tmp=$2;''/eo)
-       ||(s/$next_pair_rx/$tmp=$2;''/eo));
-    $val = &missing_braces unless (
-       ($tmp =~ s/$next_pair_pr_rx/$val=$2;''/eo)
-       ||($tmp =~ s/$next_pair_rx/$val=$2;''/eo));
-    $val =~ s/(^\s+|\s+$)//gs;
-    $label =~ s/$label_rx/_/g; # Replace non alphanumeric characters
-    $latex_labels{$label} = $val;
-    &do_labels_helper($label);
-    $_;
-}
-sub do_cmd_oldnewlabel { &do_cmd_newlabel(@_) }
-
-#
-# Sets %encoded_(section|figure|table)_number, which maps encoded
-# section titles to LaTeX numbers
-# .= \$number . \"$;\"";
-sub do_cmd_oldcontentsline { &do_cmd_contentsline(@_) }
-sub do_cmd_contentsline {
-    local($_) = @_;
-    local($arg,$after,$title,$number,$hash,$stype,$page);
-    # The form of the expression is:
-    # \contentsline{SECTION} {... {SECTION_NUMBER} TITLE}{PAGE}
-    $stype = &missing_braces unless (
-        (s/$next_pair_pr_rx/$stype = $2;''/e)
-        ||(s/$next_pair_rx/$stype = $2;''/e));
-    $arg = &missing_braces unless (
-        (s/$next_pair_pr_rx/$arg = $2;''/e)
-        ||(s/$next_pair_rx/$arg = $2;''/e));
-    $page = &missing_braces unless (
-        (s/$next_pair_pr_rx/$page = $2;''/e)
-        ||(s/$next_pair_rx/$page = $2;''/e));
-
-#    s/$any_next_pair_pr_rx/$stype = $2;''/eo; # Chop off {SECTION}
-#    s/$any_next_pair_pr_rx/$arg   = $2;''/eo; # Get {... {SECTION_NUMBER} TITLE}
-#    s/$any_next_pair_pr_rx/$page  = $2;''/eo; # Get page number
-    $hash = $stype if (($stype =~ /^(figure|table)$/)||($SHOW_SECTION_NUMBERS));
-    $hash =~ s/(sub)*(section|chapter|part)/section/;
-    $after = $_;
-    if ($hash) {
-       if ($arg =~ /^$OP/) {
-           $number = &missing_braces unless (
-               ($arg =~ s/$next_pair_pr_rx/$number = $2;''/eo)
-               ||($arg =~ s/$next_pair_rx/$number = $2;''/eo));
-       }       
-       if ($stype eq "part") {
-           while ($arg =~ s/$next_pair_pr_rx//o) {};
-           $number =~ tr/a-z/A-Z/;
-           $number = "Part $number:"}
-       # This cause problem when picking figure numbers...
-       # while ($tmp =~ s/$next_pair_pr_rx//o) {};
-       $number = -1 unless $number;
-#JCL(jcl-tcl)
-##     $_ = $arg;
-#      $title = &sanitize($arg);
-##     &text_cleanup;
-##     $title = &encode_title($_);
-##
-       #remove surrounding brace-numbering
-       $arg =~ s/^($O|$OP)\d+($C|$CP)|($O|$OP)\d+($C|$CP)$//g;
-       $arg =~ s/\\footnote(mark|text)?//g;
-       # \caption arguments should have had environments translated already
-       $arg = &translate_environments($arg) if ($arg =~ /\\begin/);
-       #replace image-markers by the image params
-       $arg =~ s/$image_mark\#([^\#]+)\#/&purify_caption($1)/e;
-
-       #RRM: resolve any embedded cross-references first
-       local($checking_caption) = 1;
-       $title = &simplify($arg);
-       $title = &sanitize($title);
-       $checking_caption = '';
-       eval "\$encoded_${hash}_number{\$title} .= \$number . \"$;\"";
-    }
-    $after;
-}
-
-#
-#  Before normalizing this was \@input.  Used in .aux files.
-#
-sub do_cmd__at_input {
-    local ($_) = @_;
-    local ($file, $after);
-    $file = &missing_braces unless (
-       (s/$next_pair_pr_rx/$file=$2;''/eo)
-       ||(s/$next_pair_rx/$file=$2;''/eo));
-    local($prefix, $suffix) = split(/\./, $file);
-    $after = $_;
-    local($EXTERNAL_FILE) = $prefix;
-    &process_ext_file($suffix);
-    $after;
-}
-
-
-########################### Counter Commands #################################
-# Removes the definition from the input string, adds to the preamble
-# and stores the body in %new_counter;
-sub get_body_newcounter {
-#    local(*_) = @_;
-    local($after_R) = @_;
-    local($_) = $$after_R;
-    local($within,$ctr,$cmd,$tmp,$body,$pat);
-    local($new_ctr) = 'counter';
-    ($ctr,$pat) = &get_next(1);        # Get counter name
-    &write_warnings ("\n*** LaTeX Error: backslash found in counter-name: $ctr")
-       if ($pat =~ s/\\//);
-    $ctr =~ s/^\s*\\//; 
-    $new_ctr .= $pat;
-
-    ($within,$pat) = &get_next(0);     # Get optional within, currently ignored
-    &addto_dependents($within,$ctr);
-    $new_ctr .= $pat;
-    do {
-###    local($_) = "\\arabic<<1>>$ctr<<1>>";
-       $body = "\\arabic<<1>>$ctr<<1>>";
-       &make_unique($body);
-       $cmd = "the$ctr";
-       $tmp = "do_cmd_$cmd";
-       $new_command{$cmd} = join(':!:',0,$body,'}') unless (defined &$tmp);
-           &write_mydb("new_command", $cmd, $new_command{$cmd});
-       undef $body;
-    };
-    &do_body_newcounter($ctr);
-
-    $$after_R = $_;
-    if (!$PREAMBLE) {
-       my $new_cmd = join(''
-           , "counter{$ctr}", ($within ? "[$within]" : '') );
-       &add_to_preamble('counter','\\new'.$new_cmd);
-       return ();
-    }
-    'newed'.$new_ctr;
-}
-
-sub do_body_newcounter {
-    local($ctr) = @_;
-    $latex_body .= &revert_to_raw_tex("\\newcounter{$ctr}\n")
-       unless ($preamble =~ /\\new(counter|theorem){$ctr}/);
-    $global{$ctr} = 0;
-    &process_commands_wrap_deferred("the$ctr ");
-    $_;
-}
-
-
-#RRM: This doesn't work properly yet.
-#     The new booleans need to be stored for use in all partitions.
-#     \if... \else  \fi  is not yet implemented.
-
-sub get_body_newboolean {
-#    local(*_) = @_;
-    local($after_R) = @_;
-    local($_) = $$after_R;
-    my $bool;
-    $bool = &missing_braces unless (
-       (s/$next_pair_pr_rx/$bool=$2;''/e)
-       ||(s/$next_pair_rx/$bool=$2;''/e));
-    $bool =  &process_body_newif('',$bool);
-    $$after_R = $_;
-    'newed'.$bool;
-}
-
-sub get_body_newif {
-#    local(*_) = @_;
-    local($after_R) = @_;
-    local($_) = $$after_R;
-    local($bool);
-    if (!(s/^\s*\\if([a-zA-Z]+)//)) {
-       $$after_R = $_;
-       return();
-    }
-    $bool = $1;
-    $$after_R = $_;
-    join('','newed', &process_body_newif('', $bool));
-}
-
-
-sub process_body_newif {
-    local($texif, $bool) = @_;
-    local($body,$ifbool,$cmd,$tmp,$pat);
-   
-#    ($bool,$pat) = &get_next(1);      # Get boolean name
-
-#    # change the brace-type around the command-name
-#    $pat =~ s/$O/$OP/; $pat =~ s/$C/$CP/; $new_cmd .= $pat;
-
-    $ifbool = "if".$bool;
-    $global{$ifbool} = 0;
-
-    do {
-       $body = "\$global{'$ifbool'} = 1;";
-       $cmd = $bool."true";
-       $code = "sub do_cmd_$cmd { ".$body." \$_[0];}";
-       eval $code;
-       print STDERR "\n*** sub do_cmd_$cmd failed:\n$@\n" if ($@);
-       $raw_arg_cmds{$cmd} = 1;
-
-       $body = "\$global{$ifbool} = 0;";
-       $cmd = $bool."false";
-       $code = "sub do_cmd_$cmd { ".$body." \$_[0];}";
-       eval $code;
-       print STDERR "\n*** sub do_cmd_$cmd failed:\n$@\n" if ($@);
-       $raw_arg_cmds{$cmd} = 1;
-
-       undef $body;
-    };
-    &process_commands_wrap_deferred("${bool}true\n${bool}false\nif$bool\n");
-
-#    $latex_body .= &revert_to_raw_tex("\\newif\\$ifbool\n")
-#      unless ($preamble =~ /\\newif\s*\\$ifbool/);
-
-    if (!$PREAMBLE) {
-       local($new_cmd) = "boolean{\\$bool}";
-       &add_to_preamble ('newif', "\\new$new_cmd" );
-       return ();
-    }
-    local($br_id) = ++$global{'max_id'};
-    'boolean'."$O$br_id$C$bool$O$br_id$C";
-}
-
-
-sub do_cmd_value {
-    local($_) = @_;
-    local($ctr,$val);
-    $ctr = &missing_braces
-       unless ((s/$next_pair_pr_rx/$ctr = $2;''/eo)
-             ||(s/$next_pair_rx/$ctr = $2;''/eo));
-    $val = &get_counter_value($ctr);
-    if ($val) { $val.$_ }
-    else { join(''," 0",$_) }
-}
-
-sub do_cmd_boolean {
-    local($_) = @_;
-    local($bool,$val);
-    $bool = &missing_braces
-       unless ((s/$next_pair_pr_rx/$bool = $2;''/eo)
-             ||(s/$next_pair_rx/$bool = $2;''/eo));
-    $val = &get_boolean_value($bool);
-    if ($val) { $val.$_ }
-    else { "0".$_ }
-}
-
-sub get_counter_value {
-    local($ctr) = @_;
-    local($val,$index);
-    $ctr = 'eqn_number' if ($ctr eq "equation");
-    $index = $section_commands{$ctr};
-
-    if (defined $global{$ctr}) { $val= $global{$ctr}; }
-    elsif (($SEGMENT)&&($index)) { 
-       $val = $segment_sec_id[$index]
-#    if ($index) { 
-#      if ($SEGMENT) { $val = $segment_sec_id[$index] }
-#      else { $val = $curr_sec_id[$index] }
-    } else {
-       &write_warnings ("\ncounter $ctr not defined");
-       $val= 0;
-    }
-    print "\nVAL:$ctr: $val " if ($VERBOSITY > 3);
-    $val;
-}
-
-sub get_boolean_value {
-    local($bool) = @_;
-    local($val,$index);
-    if (defined $global{$bool}) { $val= $global{$bool} }
-    else {
-       &write_warnings ("boolean $bool not defined\n");
-       $val="0";
-    }
-    print "\nBOOL:$bool: $val " if ($VERBOSITY > 3);
-    $val;
-}
-
-sub do_cmd_addtocounter {
-    local($_) = @_;
-    local($ctr,$num,$index);
-    $ctr = &missing_braces
-       unless ((s/$next_pair_rx/$ctr = $2;''/eo)
-             ||(s/$next_pair_pr_rx/$ctr = $2;''/eo));
-    $num = &missing_braces
-       unless ((s/$next_pair_rx/$num = $2;''/eo)
-             ||(s/$next_pair_pr_rx/$num = $2;''/eo));
-
-    $num = &translate_commands($num) if ($num =~ /\\/);
-    if ($num !~ /^\s*(\+|-)?\d+\s*$/) {
-        print STDERR "\n*** cannot set counter $ctr to $num ***\n";
-        return($_);
-    }
-
-    $latex_body .= &revert_to_raw_tex("\\addtocounter{$ctr}{$num}\n");
-    $index = $section_commands{$ctr};
-
-    if (defined $global{$ctr}) { $global{$ctr} += $num }
-    elsif ($index) { 
-       if ($SEGMENT) { $segment_sec_id[$index] += $num }
-       else { $curr_sec_id[$index] += $num }
-       $global{$ctr} += $num;
-    } elsif ($ctr eq "equation") {
-       $global{'eqn_number'} += $num
-    } else { $global{$ctr} += $num };
-    print "\nADD:$ctr:+$num= ". $global{$ctr}." " if ($VERBOSITY > 3);
-#    &reset_dependents($ctr) if ($dependent{$ctr});
-    $_;
-}
-
-sub do_cmd_setcounter {
-    local($_) = @_;
-    local($ctr,$num,$index,$sctr);
-    $ctr = &missing_braces
-       unless ((s/$next_pair_rx/$ctr = $2;''/eo)
-             ||(s/$next_pair_pr_rx/$ctr = $2;''/eo));
-    $num = &missing_braces
-       unless ((s/$next_pair_rx/$num = $2;''/eo)
-             ||(s/$next_pair_pr_rx/$num = $2;''/eo));
-
-    $num = &translate_commands($num) if ($num =~ /\\/);
-    if ($num !~ /^\s*(\+|-)?\d+\s*$/) {
-       print STDERR "\n*** cannot set counter $ctr to $num ***\n";
-       return($_);
-    }
-    if ($ctr =~ /^l/) {
-       $sctr = $';
-       $ctr = $sctr if $section_commands{$sctr};
-    }
-    if (! $AUX_FILE && !($ctr =~ /page/ )) {
-       $latex_body .= &revert_to_raw_tex("\\setcounter{$ctr}{$num}\n");
-       $index = $section_commands{$ctr};
-       if ($index) { 
-           if ($curr_sec_id[$index] <= $num ) {
-               $curr_sec_id[$index] = $num
-           } else {
-               print "\nignoring \\setcounter{$ctr}{$num} currently at ",$curr_sec_id[$index] ;
-               &write_warnings(join('',"\n\\setcounter{$ctr}{$num} ignored,"
-                       ," cannot reduce from ",$curr_sec_id[$index]));
-           }
-           $global{$ctr} = $num;
-       } elsif ($ctr eq "equation") {$global{'eqn_number'} = $num }
-       else { $global{$ctr} = $num };
-    }
-    print "\nSET:$ctr: = $num" if ($VERBOSITY > 3);
-#    &reset_dependents($ctr) if ($dependent{$ctr});
-    $_;
-}
-
-sub do_cmd_setlength {
-    local($_) = @_;
-    local($dimen,$value,$index,$sctr);
-    $dimen = &missing_braces
-       unless ((s/$next_pair_rx/$dimen = $2;''/eo)
-             ||(s/$next_pair_pr_rx/$dimen = $2;''/eo));
-    $value = &missing_braces
-       unless ((s/$next_pair_rx/$value = $2;''/eo)
-             ||(s/$next_pair_pr_rx/$value = $2;''/eo));
-
-    # recognise specific length-parameters
-    if ($dimen =~ /captionwidth/) {
-       local($pxs,$len) = &convert_length($value, $MATH_SCALE_FACTOR);
-       $cap_width = $pxs if ($pxs &&($dimen =~ /captionwidth/));
-    }
-    if ((! $AUX_FILE)&&(! $PREAMBLE)) {
-       $latex_body .= &revert_to_raw_tex("\\setlength{$dimen}{$value}\n");
-       print "\nSETLENGTH:$dimen = $value" if ($VERBOSITY > 3);
-    }
-    $_;
-}
-
-sub do_cmd_setboolean {
-    local($_) = @_;
-    local($bool,$val);
-    $bool = &missing_braces
-       unless ((s/$next_pair_rx/$bool = $2;''/eo)
-             ||(s/$next_pair_pr_rx/$bool = $2;''/eo));
-    $val = &missing_braces
-       unless ((s/$next_pair_rx/$val = $2;''/eo)
-             ||(s/$next_pair_pr_rx/$val = $2;''/eo));
-    if (! $AUX_FILE) {
-       $latex_body .= &revert_to_raw_tex("\\setboolean{$bool}{$val}\n");
-       $global{"if$bool"} = (($val = ~/true/) ? 1 : 0);
-       print "\nSETBOOL:$bool = $val" if ($VERBOSITY > 3);
-    }
-    $_;
-}
-
-sub do_cmd_endsegment {
-    local($_) = @_;
-    local($ctr,$dum) = &get_next_optional_argument;
-    local($index,$steps) = ('',1);
-#    $steps = &missing_braces unless (
-#      (s/$next_pair_pr_rx/$steps = $2;''/e)
-#      ||(s/$next_pair_rx/$steps = $2;''/e));
-    $index = $section_commands{$ctr} if $ctr;
-#    if ($index) { $curr_sec_id[$index] += $steps }
-#    if ($index) { ($after_segment,$after_seg_num) = ($index,$steps) }
-    if ($index) { ($after_segment,$after_seg_num) = ($index,1) }
-    $_;
-}
-
-sub do_cmd_stepcounter {
-    local($_) = @_;
-    local($ctr,$index);
-    $ctr = &missing_braces
-       unless ((s/$next_pair_rx/$ctr = $2;''/eo)
-             ||(s/$next_pair_pr_rx/$ctr = $2;''/eo));
-    if (! $AUX_FILE) {
-       $latex_body .= &revert_to_raw_tex("\\stepcounter{$ctr}\n");
-       $index = $section_commands{$ctr};
-       if ($index) {
-#          if ($SEGMENT) { $segment_sec_id[$index] += 1 }
-#          else { $curr_sec_id[$index] += 1 }
-           $global{$ctr} += 1;
-       } elsif ($ctr eq "equation") { $global{'eqn_number'} += 1 }
-       else { $global{$ctr} += 1 };
-    }
-    print "\nSTP:$ctr:+1" if ($VERBOSITY > 3);
-    &reset_dependents($ctr) if ($dependent{$ctr});
-    $_;
-}
-
-#RRM:   dependent counters are stored as a comma-separated list
-#       in the %dependent hash.
-sub reset_dependents {
-    local($ctr) = @_;
-    local($dep,$subdep,%dependents);
-    @dependents = (split($delim, $dependent{$ctr}));
-    print "\n" if (($VERBOSITY > 3)&&(@dependents));
-    while (@dependents) {
-       $dep = pop(@dependents);
-       print "RESET $dep to 0\n" if ($VERBOSITY > 3);
-       if ($global{$dep}) { $global{$dep} = 0 }
-       elsif ($dep =~ /equation/) { $global{'eqn_number'} = 0 }
-       if ($dependent{$dep}) {
-           push(@dependents,split($delim,$dependent{$dep}));
-       }
-    }
-}
-
-sub do_cmd_numberwithin {
-    local($_) = @_;
-    local($ctr,$within);
-    $ctr = &missing_braces
-       unless ((s/$next_pair_rx/$ctr = $2;''/eo)
-             ||(s/$next_pair_pr_rx/$ctr = $2;''/eo));
-    $within = &missing_braces
-       unless ((s/$next_pair_rx/$within = $2;''/eo)
-             ||(s/$next_pair_pr_rx/$within = $2;''/eo));
-
-    # record the counter dependency
-    &addto_dependents($within,$ctr) if ($within);
-    local($newsub) = "sub do_cmd_the$ctr {"
-       . "\$global{'max_id'}++;\n"
-#        . "local(\$super)=\&do_cmd_the$within();\n"
-       . "local(\$super)=\&translate_commands('\\the$within');\n"
-       . "\$super .= '.' unless (\$super =~/\\.\$/);\n"
-       . "\$super .\&do_cmd_value('<<'.\$global{'max_id'}.'>>"
-       . $ctr . "<<'.\$global{'max_id'}.'>>')}\n";
-    eval $newsub;
-    print " *** sub do_cmd_the$ctr unchanged *** $@ " if ($@);
-    $_;
-}
-
-sub do_cmd_refstepcounter {
-    local($_) = @_;
-    local($ctr);
-    $ctr = &missing_braces
-       unless ((s/$next_pair_rx/$ctr = $2;''/eo)
-             ||(s/$next_pair_pr_rx/$ctr = $2;''/eo));
-    if (! $AUX_FILE) {
-       $latex_body .= &revert_to_raw_tex("\\refstepcounter{$ctr}\n");
-       $index = $section_commands{$ctr};
-       if (defined $global{$ctr}) { $global{$ctr} += 1 }
-       elsif ($index) {
-           if ($SEGMENT) { $segment_sec_id[$index] += 1 }
-           else { $curr_sec_id[$index] += 1 }
-       } elsif ($ctr eq "equation") { $global{'eqn_number'} += 1 }
-       else { $global{$ctr} += 1 };
-    }
-    print "\nSTP: $ctr : +1" if ($VERBOSITY > 3);
-    &reset_dependents($ctr) if ($dependent{$ctr});
-    $_;
-}
-
-sub read_counter_value {
-    local($_) = @_;
-    local($ctr,$br_id,$val);
-    $ctr = &missing_braces
-        unless ((s/$next_pair_pr_rx/$br_id = $1; $ctr = $2;''/eo)
-              ||(s/$next_pair_rx/$br_id = $1; $ctr = $2;''/eo));
-    $val = &get_counter_value($ctr);
-    ($ctr, $val, $br_id, $_)
-}
-
-sub styled_number_text {
-    local($num_style, $val, $txtID) = @_;
-    if ($USING_STYLES) {
-        $txt_style{$num_style} = " " unless ($txt_style{$num_style});
-        join('',"<SPAN CLASS=\"$num_style\">", $val, "</SPAN>", $_);
-    } else { $val.$_ }
-}
-
-sub do_cmd_arabic {
-    local($ctr, $val, $id, $_) = &read_counter_value($_[0]);
-    $val = ($val ? &farabic($val) : "0");
-    &styled_number_text('arabic', $val, $id);
-}
-    
-sub do_cmd_roman {
-    local($ctr, $val, $id, $_) = &read_counter_value($_[0]);
-    if ($val < 0 ) { $val = join('',"-",&froman(-$val)); }
-    elsif ($val) { $val = &froman($val) }
-    else { $val = "0"; }
-    &styled_number_text('roman', $val, $id);
-}
-
-sub do_cmd_Roman {
-    local($ctr, $val, $id, $_) = &read_counter_value($_[0]);
-    if ($val < 0 ) { $val = join('',"-",&fRoman(-$val)); }
-    elsif ($val) { $val = &fRoman($val) }
-    else { $val = "0"; }
-    &styled_number_text('Roman', $val, $id);
-}
-
-sub do_cmd_alph {
-    local($ctr, $val, $id, $_) = &read_counter_value($_[0]);
-    if ($val < 0 ) { $val = join('',"-",&falph(-$val)); }
-    elsif ($val) { $val = &falph($val) }
-    else { $val = "0"; }
-    &styled_number_text('alph', $val, $id);
-}
-
-sub do_cmd_Alph {
-    local($ctr, $val, $id, $_) = &read_counter_value($_[0]);
-    if ($val < 0 ) { $val = join('',"-",&fAlph(-$val)); }
-    elsif ($val) { $val = &fAlph($val) }
-    else { $val = "0"; }
-    &styled_number_text('Alph', $val, $id);
-}
-
-
-sub do_cmd_fnsymbol {
-    local($ctr, $val, $id, $_) = &read_counter_value($_[0]);
-    $val = &process_in_latex_helper($ctr, $val, "fnsymbol{$ctr}");
-    &styled_number_text('Alph', $val, $id);
-}
-
-
-
-# This is a general command for getting counter values;
-# e.g. for section-numbers.
-
-sub do_cmd_thecounter {
-    local($_) = @_;
-    # Uses $counter bound by the caller
-    local($val) = &get_counter_value($counter);
-    $val = &process_in_latex_helper($counter,$val,"the$counter");
-    &styled_number_text($counter, $val, '');
-#   join('',&process_in_latex_helper($counter,$val,"the$counter"),$_[0]);
-}
-
-
-################# Special Naming Macros ##################################
-
-sub do_cmd_LaTeX {
-    local($_) = @_;
-    if ($USING_STYLES) {
-       $env_style{'LaTeX'} = ' ' unless ($env_style{'LaTeX'});
-       $env_style{'logo-LaTeX'} = ' ' unless ($env_style{'logo-LaTeX'});
-       join('',"<SPAN CLASS=\"logo,LaTeX\">",$Laname, $TeXname,"</SPAN>",$_);
-    } else { join('',$Laname, $TeXname, $_); }
-}
-
-sub do_cmd_LaTeXe {
-    local($_) = @_;
-    if ($USING_STYLES) {
-       $env_style{'LaTeX2e'} = ' ' unless ($env_style{'LaTeX2e'});
-       $env_style{'logo-LaTeX2e'} = ' ' unless ($env_style{'logo-LaTeX2e'});
-       join('',"<SPAN CLASS=\"logo,LaTeX2e\">"
-               ,$Laname, $TeXname,'2<SUB>e</SUB>',"</SPAN>",$_);
-    } else { join('',$Laname,$TeXname
-               ,(($HTML_VERSION >= 3.0)? '2<SUB>e</SUB>':'2e'),$_);
-    }
-}
-
-sub do_cmd_latextohtml {
-    local($_) = @_;
-    if ($USING_STYLES) {
-       $env_style{'LaTeX2HTML'} = ' ' unless ($env_style{'LaTeX2HTML'});
-       $env_style{'logo-LaTeX2HTML'} = ' ' unless ($env_style{'logo-LaTeX2HTML'});
-       join('',"<SPAN CLASS=\"logo,LaTeX2HTML\">"
-               ,$Laname, $TeXname,"2<TT>HTML</TT>","</SPAN>",$_);
-    } else { join('',$Laname,$TeXname,"2<TT>HTML</TT>",$_);}
-}
-
-sub do_cmd_TeX {
-    local($_) = @_;
-    if ($USING_STYLES) {
-       $env_style{'logo-TeX'} = ' ' unless ($env_style{'logo-TeX'});
-       join('',"<SPAN CLASS=\"logo-TeX\">",$TeXname,"</SPAN>",$_);
-    } else { join('',$TeXname, $_);}
-}
-
-sub do_cmd_MF {
-    local($_) = @_;
-    if ($USING_STYLES) {
-       $env_style{'logo-Metafont'} = ' ' unless ($env_style{'logo-Metafont'});
-       join('',"<SPAN CLASS=\"logo-Metafont\">",$MFname,"</SPAN>",$_);
-    } else { join('', $MFname, $_);}
-}
-
-sub do_cmd_Xy {
-    local($_) = @_;
-    if ($USING_STYLES) {
-       $env_style{'logo-Xy-pic'} = ' ' unless ($env_style{'logo-Xy-pic'});
-       join('',"<SPAN CLASS=\"logo-Xy-pic\">",$Xyname,"</SPAN>",$_);
-    } else { join('',$Xyname, $_);}
-}
-
-sub do_cmd_AmS {
-    local($_) = @_;
-    if ($USING_STYLES) {
-       $env_style{'logo-AMS'} = ' ' unless ($env_style{'logo-AMS'});
-       join('',"<SPAN CLASS=\"logo-AMS\">",$AmSname,"</SPAN>",$_);
-    } else { join('',$AmSname, $_);}
-}
-
-sub do_cmd_AmSTeX {
-    local($_) = @_;
-    if ($USING_STYLES) {
-       $env_style{'logo-AMS'} = ' ' unless ($env_style{'logo-AMS'});
-       join('',"<SPAN CLASS=\"logo-AMS\">",$AmSname,"-$TeXname","</SPAN>",$_);
-    } else { join('',$AmSname, "-", $TeXname, $_);}
-}
-
-sub do_cmd_char {
-    local($_) = @_;
-# some special characters are already turned into l2h internal
-# representation.
-# Get its represention from the table and use it like as regexp form.
-    local($spmquot) = &escape_rx_chars($html_specials{'"'});
-# Get all internal special char representations as implied during
-# preprocessing.
-    local($spmrx) = join("\000",values %html_specials);
-# escape regexp special chars (not really necessary yet, but why not)
-    $spmrx = &escape_rx_chars($spmrx); #~ s:([\\(){}[\]\^\$*+?.|]):\\$1:g;
-    $spmrx =~ s/\000/|/g;
-    $spmrx = "(.)" unless $spmrx =~ s/(.+)/($1|.)/;
-
-    s/^[ \t]*(\d{1,3})[ \t]*/&#$1;/ &&
-       return($_);
-
-    s/^[ \t]*\'(\d{1,3})[ \t]*/"&#".oct($1).";"/e &&
-       return($_);
-
-    s/^[ \t]*$spmquot(\d{1,2})[ \t]*/"&#".hex($1).";"/e &&
-       return($_);
-
-# This is a kludge to work together with german.perl. Brrr.
-    s/^[ \t]*\'\'(\d{1,2})[ \t]*/"&#".hex($1).";"/e &&
-       return($_);
-# If l2h's special char marker represents more than one character,
-# it's already in the &#xxx; form. Else convert the single character
-# into &#xxx; with the ord() command.
-    s/^[ \t]*\`\\?$spmrx[ \t]*/
-       (length($html_specials_inv{$1}) > 1 ?
-        $html_specials_inv{$1} : "&#".ord($html_specials_inv{$1}||$1).";")/e &&
-            return($_);
-    &write_warnings(join('',
-                        "Could not find character number in \\char",
-                        (/\n/ ? $` : $_), " etc.\n"));
-    $_;
-}
-
-
-sub do_cmd_symbol {
-    local($_) = @_;
-    local($char);
-    $char = &missing_braces
-       unless ((s/$next_pair_pr_rx/$char = $2;''/eo)
-               ||(s/$next_pair_rx/$char = $2;''/eo));
-    join('',&do_cmd_char($char),$_);
-}
-
-################# Accent and Special Symbols ##################################
-
-# Generate code for the accents handling commands that are never
-# applied to i or j.
-# MEH: Now all accents are safe for dotless i or j
-# MEH: Math accents supported as well
-sub generate_accent_commands {
-    local($accent,$accent_cmd);
-    local(%accents) = ("c", "cedil", "pc", "cedil", "d", "bdot", "b", "b",
-                      "tilde", "tilde", "dot", "dot", "bar", "macr",
-                      "hat", "circ", "u", "breve", "v", "caron",
-                      "H", "dblac", "t", "t", "grave", "grave",
-                      "acute", "acute", "ddot", "uml", "check", "caron",
-                      "breve", "breve", "vec", "vec",
-                      "k", "ogon", "r", "ring");
-    foreach $accent (keys(%accents))  {
-       $accent_cmd = "sub do_cmd_$accent {" . 'local($_) = @_;'  .
-           "&accent_safe_for_ij('$accents{$accent}','$accent');" . '$_}';
-       eval $accent_cmd;
-       $accent_cmd = "do_cmd_$accent";
-       print STDERR "\n*** sub do_cmd_$accent failed:\nPERL: $@\n" if ($@);
-    }
-}
-
-# These handle accents, taking care of the dotless i's and j's that
-# may follow (even though accented j's are not part of any alphabet
-# that I know).
-#
-# Note that many forms of accents over dotless i's and j's are
-# handled:
-#   "\^\i rest"
-#   "\^\i
-#    rest"
-#   "\^{\i}rest"
-#   "\^\i{}rest"
-# They all produce "&#238;rest".
-# MEH: now also handles
-#   "\^{}rest"
-#   "\^,rest"
-# and many more
-
-sub accent_safe_for_ij {
-    local($type,$acc_cmd) = @_;
-    local($arg, $first_char,$ij_cmd);
-    #print STDOUT "\nACCENT: $type <$_>\n" ;
-    s/^[ \t]*\n?[ \t]*(\S)/$1/;        # Remove whitespace
-    if (s/^\\([ij])([^a-zA-Z]|$)/$2/) {
-       # Accent of this form: "\^\i rest" or "\^\i{}rest"
-       ($arg) =  $1; $ij_cmd = "\\$1";
-       s/^[ \t]+//o;           # Get rid of whitespaces after \i
-       if (substr($_, 0, 2) =~ /[\n\r][^\n\r]/) {
-           $_ = substr($_, 1); # Get rid of 1 newline after \i
-       }
-    } else {
-       # Accent of this form: "\^{\i}rest" or not an accent on i nor j
-       ($arg) =  &get_next_pair_or_char_pr;
-    }
-    $arg =~ s/([^\s\\<])/$first_char = $1; ''/eo;
-#   print STDOUT "\nACCENT1 type:$type arg:|${arg}| first_char: |$first_char| $ij_cmd 
-#      , $ACCENT_IMAGES\n";
-
-    local($aafter) = $_;
-    local($iso) = &iso_map($first_char,$type); 
-    if ($iso) { $_ = join('', $iso, $arg, $aafter) }
-    elsif ((!($ACCENT_IMAGES))&&(!($ij_cmd))) {
-       local($err_string) = 
-           "\nNo available accent for $first_char$type , using just \"$first_char$arg\"";
-       print $err_string if ($DEBUG||$VERBOSITY > 1);
-       &write_warnings("\n ...set \$ACCENT_IMAGES  to get an image ");
-       $_ = join('', $first_char, $arg, $aafter) }
-    else { 
-       print ", making image of accent: $first_char$type " if ($VERBOSITY > 1);
-       $_ = join('', &mbox_accent($acc_cmd, $first_char, $ij_cmd) , $arg, $aafter)
-    }
-}
-
-sub mbox_accent {
-    local($type, $char, $ij_cmd) = @_;
-    if (length($type) > 1 ) {
-       if ($text_accent{$type}) {
-           $type = $text_accent{$type};
-       } elsif ($type =~ /^(math)?accent/) {
-       } else {
-           print "\n unrecognised accent $type for `$char' ";
-           return $char;
-       }
-    }
-    local(@styles);
-    local($cmd,$style,$bstyle,$estyle) = ('','','','');
-    local(@styles) = split(',',$ACCENT_IMAGES);
-    foreach $style (@styles) {
-       $style =~ s/(^\s*\\|\s*)//g; 
-       $cmd = "do_cmd_$style";
-       if (defined &$cmd) { 
-           $bstyle .= "\\$style\{" ;
-           $estyle .= "\}";
-       } else {
-           &write_warnings("\nunrecognized style \\$style for accented characters");
-       }
-    }
-    if (!($bstyle)) {
-       $bstyle = "\{";
-       $estyle = "\}";
-    } elsif ($bstyle =~ /textit|itshape/) {
-       $bstyle = '\raise.5pt\hbox{' . $bstyle ;        
-       $estyle .= "\}";
-    }
-    $char = $ij_cmd if ($ij_cmd);
-    print STDOUT "\nACCENT: $type, $char" if ($VERBOSITY > 2);
-    local($afterkern); # serifs extend too far on some letters...
-    $afterkern = "\\kern.05em" if (($char =~ /m|n/)||($type=~/[Hv]/));
-    # ...or the accent is wider than the letter, so pad it out a bit
-    $afterkern = "\\kern.15em" if ($char =~ /i|l/); #||($type=~/v/));
-
-    &process_undefined_environment("tex2html_accent_inline"
-        , ++$global{'max_id'}, "${bstyle}\\${type}\{$char\\/\}$estyle$afterkern");
-}
-
-# MEH: Actually tries to find a dotless i or j
-sub do_cmd_i { join('',&iso_map('i', 'nodot') || 'i', $_[0]) }
-sub do_cmd_j { join('',&iso_map('j', 'nodot') || 'j', $_[0]) }
-
-sub do_cmd_accent {
-    local($_) = @_;
-    local($number);
-    if (s/\s*(\d+)\s*//o) {$number = $1}
-    elsif (s/\s*&SMPquot;(\d)(\d)\s*//o) { $number = $1*16 + $2 }
-    elsif (s/\s*\'(\d)(\d)(\d)\s*//o) { $number = $1*64 + $2*8 + $3 }
-    else { s/\s*(\W\w+)([\s\W])/$2/o;  $number = $1 }
-    local($type) = $accent_type{uc($number)};
-    #print STDOUT "\ndo_cmd_accent: $number ($type) |$_|\n";
-    if (! $type) {
-       &write_warnings("Accent number $number is unknown.\n");
-       return $_;
-    }
-    &accent_safe_for_ij($type , 'accent$number' );
-    $_;
-}
-
-sub do_cmd_ae { join('', &iso_map("ae", "lig"), $_[0]);}
-sub do_cmd_AE { join('', &iso_map("AE", "lig"), $_[0]);}
-sub do_cmd_aa { join('', &iso_map("a", "ring"), $_[0]);}
-sub do_cmd_AA { join('', &iso_map("A", "ring"), $_[0]);}
-sub do_cmd_o { join('', &iso_map("o", "slash"), $_[0]);}
-sub do_cmd_O { join('', &iso_map("O", "slash"), $_[0]);}
-sub do_cmd_ss { join('', &iso_map("sz", "lig"), $_[0]);}
-sub do_cmd_DH { join('', &iso_map("ETH", ""), $_[0]);}
-sub do_cmd_dh { join('', &iso_map("eth", ""), $_[0]);}
-sub do_cmd_TH { join('', &iso_map("THORN", ""), $_[0]);}
-sub do_cmd_th { join('', &iso_map("thorn", ""), $_[0]);}
-
-sub do_cmd_pounds { join('', &iso_map("pounds", ""), $_[0]);}
-sub do_cmd_S { join('', &iso_map("S", ""), $_[0]);}
-sub do_cmd_copyright { join('', &iso_map("copyright", ""), $_[0]);}
-sub do_cmd_P { join('', &iso_map("P", ""), $_[0]);}
-
-
-sub brackets { ($OP, $CP);}
-
-sub get_date {
-    local($format,$order) = @_;
-    local(@lt) = localtime;
-    local($d,$m,$y) = @lt[3,4,5];
-    if ($format =~ /ISO/) {
-       sprintf("%4d-%02d-%02d", 1900+$y, $m+1, $d);
-    } elsif ($format) {
-       if ($order) { eval "sprintf(".$format.",".$order.")"; }
-       else { sprintf($format, $d, $m+1, 1900+$y); }
-    } else { sprintf("%d/%d/%d", $m+1, $d, 1900+$y); }
-}
-
-sub address_data {
-    local($user, $date, $_);
-    local($format,$order) = @_;
-    # Get author, (email address) and current date.
-    ($user = L2hos->fullname()) =~ s/,.*//;
-    ($user, &get_date($format,$order));
-}
-
-
-#################################### LaTeX2e ##################################
-
-sub missing_braces {
-#    local($cmd) = @_;
-    local($next, $revert, $thisline);
-    local($this_cmd) = $cmd;
-    $this_cmd =~ s/^\\// unless ($cmd eq "\\");
-    &write_warnings("\n? brace missing for \\$this_cmd");
-    if (/^[\s%]*([^\n]*)\n/ ) {
-       $thisline = &revert_to_raw_tex($1)
-    } else { 
-       $thisline = &revert_to_raw_tex($_); 
-    }
-    print "\n\n*** no brace for \\$this_cmd , before:\n$thisline";
-    s/^\s*//;
-    if ($_ =~ s/$next_token_rx//) { $next = $& };
-    $next =~ s/$comment_mark(\d+\n?)?//g;
-#    $next = &translate_commands($next) if ($next =~ /^\\/);
-    if ($next =~ /^\\(\W|\d|[a-zA-z]*\b)/) {
-       $revert = $next = "\\".$1;
-    } elsif ($next =~ /\W/) {
-       $revert = &revert_to_raw_tex($next);
-    } else { $revert = $next };
-    print "\n*** using \"$revert\" as the argument instead; is this correct?  ***\n\n";
-    $next;
-}
-
-#RRM:
-#     &styled_text_chunk  provides an interface for pieces of styled text,
-# within a single paragraph. The visual markup can be obtained through either
-# 1. link to a stylesheet (CSS)
-# 2. direct markup placed into the output
-# 3. calling another function to process the text
-# 
-# parameters (in order):
-#  $def_tag   : markup tag to be used, unless $USING_STYLES or no $property given,
-#              attributes can be included, only 1st word is used for closing-tag;
-#  $prefix    : prefix for the Unique ID identifier, defaults to 'txt'
-#           OR  contains  CLASS= identifier  when $property is empty(see below);
-#  $type      : general type of the style-sheet information
-#  $class     : specific type of the style-sheet information
-#  $property  : value to be set, applicable to the $type & $class
-#  $alt_proc  : name of procedure to use, if $USING_STYLES == 0, and no $def_tag
-#  $_         : current data-stream
-#  $open_tags_R : current open-tags (not used in this procedure)
-
-sub styled_text_chunk {
-    local($def_tag, $prefix, $type, $class, $property, $alt_proc, $_,
-        $ot) = @_;
-    local($open_tags_R) = defined $ot ? $ot : $open_tags_R;
-    local($text, $env_id, $def_end);
-    local($span_tag) = 'SPAN';
-    $text = &missing_braces
-        unless ((s/$next_pair_pr_rx/$text = $2; $env_id = $1;''/eo)
-           || (s/$next_pair_rx/$text = $2; $env_id = $1;''/eo));
-    $text = &balance_inner_tags($text);
-
-    #start from no open tags
-    local(@save_open_tags) = ();
-    local($open_tags_R) = [];
-
-#    local($decl); 
-#    if ($prefix =~ /CLASS="(\w+)"/ ) {
-#      $decl=$1;
-#      push (@$open_tags_R, $decl);
-#    }
-#    push (@$open_tags_R, $color_env) if $color_env;
-    if (!$inside_math) {
-       $text = &translate_environments($text);
-       $text = &translate_commands($text) if ($text =~ /\\/);
-       $text .= &balance_tags;
-    }
-    
-    if (($USING_STYLES)&&($env_id =~ /^\d+$/)&&($property)) { 
-       $prefix = 'txt' unless ($prefix);
-       $env_id = $prefix.$env_id;
-       $styleID{$env_id} = join('',"$type", ($class ? "-$class" : '')
-                                ,": ", $property,"; ");
-       return(join('',"<$span_tag ID=\"$env_id\">",$text,"<\/$span_tag>", $_));
-    }
-
-    if (($USING_STYLES)&&($prefix =~ /($span_tag )?CLASS=\"(\w+)\"/o)) {
-       local($span_class) = $2;
-       $def_tag = (($1)? $1 : $span_tag." ");
-       $txt_style{$span_class} = "$type: $class "
-           unless ($txt_style{$span_class});
-       return(join('',"<$def_tag CLASS=\"$span_class\">"
-               , $text,"<\/$span_tag>", $_));
-    }
-
-    if (($def_tag) && (!$USING_STYLES)) {
-       $def_tag =~ s/^($span_tag)?CLASS=\"(\w+)\"$// ;
-    }
-
-    if ($def_tag =~ /^(\w+)/) {
-       $def_end = $1;
-       return(join('',"<$def_tag>",$text,"<\/$def_end>", $_));
-    }
-
-    return (join('', eval ("&$alt_proc(\$text)") , $_)) if (defined "&$alt_proc");
-
-    &write_warnings(
-       "\ncannot honour request for $type-$class:$property style at br$env_id");
-    join('', $text, $_);
-}
-
-sub multi_styled_text_chunk {
-    local($def_tag, $prefix, $type, $class, $property, $_, $ot) = @_;
-    local($open_tags_R) = defined $ot ? $ot : $open_tags_R;
-    $prefix = 'txt' unless ($prefix);
-    my(@def_tags) = split(',',$def_tag);
-    my(@types) = split(',',$type);
-    my(@classes) = split(',',$class);
-    my(@properties) = split(',',$property);
-    $text = &missing_braces
-        unless ((s/$next_pair_pr_rx/$text = $2; $env_id = $1;''/eo)
-           || (s/$next_pair_rx/$text = $2; $env_id = $1;''/eo));
-    if (($USING_STYLES)&&($env_id =~ /^\d+$/)&&($property)) { 
-        # $1 contains the bracket-id
-       $env_id = $prefix.$env_id;
-       while (@properties) {
-           $class = shift @classes;
-           $property = shift @properties;
-           $styleID{$env_id} .= join(''
-               , shift @types,
-               , ($class ? "-".$class : '')
-               , ($property ? " : $property" : ''), " ; ");
-           $styleID{$env_id} .= "\n\t\t  " if (@properties);
-       }
-    }
-    join('',"<SPAN ID=\"$env_id\">",$text,"<\/SPAN>", $_);
-}
-
-#RRM: 
-#   This one takes care of commands with argument that really should be
-#   environments; e.g.  \centerline, \rightline, etc.
-#   Note that styles are inherited also from the existing @$open_tags_R.
-#
-sub styled_text_block {
-    local($def_tag, $attrib, $value, $class, $_, $ot) = @_;
-    local($open_tags_R) = defined $ot ? $ot : $open_tags_R;
-    local($text, $env_id, $attribs);
-    if ($attribs =~ /,/ ) {
-        local(@attribs) = split(',',$attrib);
-       local(@values) = split(',',$value);
-       while (@attribs) { 
-            $attribs .= join('', " " , shift @attribs 
-               ,"=\"" , shift @values, "\"") }
-    } elsif($value) { 
-        $attribs = join(''," ",$attrib,"=\"",$value,"\"")
-    } else { $attribs = " " . $attrib }
-
-    local(@save_open_tags) = @$open_tags_R;
-    local($closures) = &close_all_tags();
-    local($reopens)=&balance_tags();
-    $text = &missing_braces
-        unless ((s/$next_pair_pr_rx/$text = $2; $env_id = $1;''/eo)
-           || (s/$next_pair_rx/$text = $2; $env_id = $1;''/eo));
-    if (($USING_STYLES)&&($env_id =~ /^\d+$/)) {
-       $env_id = ++$global{'max_id'};
-       $env_id = "par".$env_id;
-       $styleID{$env_id} = " ";
-       $env_style{$class} = " " if (($class)&&!($env_style{$class}));
-       $class = " CLASS=\"$class\"" if ($class);
-       $env_id = " ID=\"$env_id\"";
-    } else { $class = ''; $env_id = '' };
-
-    $text = &translate_environments($text);
-    $text = &translate_commands($text);
-
-    local($closuresA)=&close_all_tags();
-    local($reopensA) = &balance_tags();
-    $text =~ s/^\n?/\n/o; 
-    join('', $closures
-        , "<$def_tag$class$env_id$attribs>"
-        , $reopens, $text, $closuresA
-        , "</$def_tag>\n", $reopensA,  $_);
-}
-
-
-# this gives a separate ID for each instance
-#sub do_cmd_textbf { &styled_text_chunk('B','','font','weight'
-#                  ,'bold', '', @_); }
-#
-# this uses a single CLASS for all instances
-sub do_cmd_textbf { &styled_text_chunk('B','CLASS="textbf"'
-                   ,'font-weight','bold', '', '', @_); }
-
-
-# this gives a separate ID for each instance
-sub do_cmd_texttt { &styled_text_chunk('TT','','font','','', '', @_); }
-
-# this uses a single CLASS for all instances
-#sub do_cmd_textit { &styled_text_chunk('TT','CLASS="textit"'
-#                  ,'font-family','monospace', '', '', @_); }
-#
-# this gives a separate ID for each instance
-#sub do_cmd_textit { &styled_text_chunk('I','','font','style'
-#                  ,'italic', '', @_); }
-#
-# this uses a single CLASS for all instances
-sub do_cmd_textit { &styled_text_chunk('I','CLASS="textit"'
-                   ,'font-style','italic', '', '', @_); }
-
-
-
-# this gives a separate ID for each instance
-#sub do_cmd_textsl { &styled_text_chunk('I','','font','style'
-#                  ,'oblique', '', @_); }
-#
-# this uses a single CLASS for all instances
-#sub do_cmd_textsl { &styled_text_chunk('I','CLASS="textsl"'
-#                  ,'font-style','oblique', '', '', @_); }
-#
-# ... NS4 implements Italic, not oblique
-sub do_cmd_textsl { &styled_text_chunk('I','CLASS="textsl"'
-                   ,'font-style','italic', '', '', @_); }
-
-
-# this gives a separate ID for each instance
-#sub do_cmd_textsf { &styled_text_chunk('I','','font','family'
-#                  ,'sans-serif', '', @_); }
-#
-# this uses a single CLASS for all instances
-#sub do_cmd_textsf { &styled_text_chunk('I','CLASS="textsf"'
-#                  ,'font-family','sans-serif', '', '', @_); }
-#
-# ... NS4 doesn't implement sans-serif
-sub do_cmd_textsf { &styled_text_chunk('I','CLASS="textsf"'
-                   ,'font-style','italic', '', '', @_); }
-
-
-#sub do_cmd_textsc {
-#    local($_) = @_;
-#    local($text, $next, $scstr, $before, $special);
-#    $text = &missing_braces
-#        unless ((s/$next_pair_pr_rx/$text = $2;''/eo)
-#          || (s/$next_pair_rx/$text = $2;''/eo));
-#    join('', &process_smallcaps($text), $_);
-#}
-
-sub lowercase_entity {
-    local($char) = @_;
-    local($exent);
-    if ($exent = $low_entities{$char}) { "\&#$exent;" }
-    elsif ($exent = $extra_small_caps{$char}) { $exent }
-    else { "\&#$char;" }
-}
-
-sub process_smallcaps {
-    local($text) = @_;
-    local($next, $scstr, $scbef, $special, $char);
-    # is this enough for \sc and \scshape ?
-    $text = &translate_environments($text);
-
-    # MRO: replaced $* with /m
-    while ($text =~ /(\\[a-zA-Z]+|[&;]SPM\w+;|<[^>]+>)+/m ) {
-       $scbef = $`; $special = $&; $text = $';
-       while ( $scbef =~ /(&#\d+;|[a-z$sclower])+[a-z\W\d$sclower]*/m) {
-           $scstr .= $`; $scbef = $';
-           $next = $&; 
-           $next =~ s/&#(\d+);/&lowercase_entity($1)/egm;
-           eval "\$next =~ $scextra" if ($scextra);
-           eval "\$next =~ tr/a-z$sclower/A-Z$scupper/";
-           $scstr .= "<SMALL>" . $next ."<\/SMALL>";
-       }
-       $scstr .= $scbef . $special;
-    }
-    if ($text) {
-       while ( $text =~ /(&#\d+;|[a-z$sclower])+[a-z\W\d$sclower]*/m) {
-           $scstr .= $`; $text = $';
-           $next = $&;
-           $next =~ s/&#(\d+);/&lowercase_entity($1)/egm;
-           eval "\$next =~ $scextra" if ($scextra);
-           eval "\$next =~ tr/a-z$sclower/A-Z$scupper/";
-           $scstr .= "<SMALL>" . $next ."<\/SMALL>";
-       }
-       $scstr .= $text;
-    }
-    $scstr;
-}
-
-# this gives a separate ID for each instance
-#sub do_cmd_textsc { &styled_text_chunk('','','font','variant'
-#                  ,'small-caps', 'process_smallcaps', @_); }
-#
-# this uses a single CLASS for all instances
-#sub do_cmd_textsc { &styled_text_chunk('', 'CLASS="textsc"'
-#                  ,'font-variant','small-caps','', 'process_smallcaps', @_); }
-#
-# ...but NS 4.03 doesn't implement  small-caps !!!
-sub do_cmd_textsc { &styled_text_chunk('',''
-                   ,'font-variant','small-caps','', 'process_smallcaps', @_); }
-
-
-#sub do_cmd_emph { &styled_text_chunk('EM','em','font','variant','','', @_); }
-
-
-# this gives a separate ID for each instance
-#sub do_cmd_underline { &styled_text_chunk('U','','text','decoration','underline','', @_); }
-
-# this uses a single CLASS for all instances
-sub do_cmd_underline { &styled_text_chunk('U','CLASS="underline"'
-                      ,'text-decoration','underline','','', @_); }
-sub do_cmd_underbar { &do_cmd_underline(@_) }
-
-
-# this gives a separate ID for each instance
-#sub do_cmd_strikeout { &styled_text_chunk('STRIKE',''
-#                     ,'text','decoration','line-through','', @_); }
-
-# this uses a single CLASS for all instances
-sub do_cmd_strikeout { &styled_text_chunk('STRIKE','CLASS="strikeout"',
-                      'text-decoration','line-through','','', @_); }
-
-
-sub do_cmd_uppercase {
-    local($_) = @_;
-    local($text,$next,$done,$special,$after);
-    $text = &missing_braces unless (
-           (s/$next_pair_pr_rx/$text = $2;''/eo)
-           ||(s/$next_pair_rx/$text = $2;''/eo));
-    $after = $_;
-    while ($text =~ /(\\[a-zA-Z]+|[&;]SPM\w+;)/ ) {
-       $next = $`;
-       $special = $&;
-       $text = $';
-       $next =~ tr /a-z/A-Z/ if ($next);
-       $done .= $next . $special;
-    }
-    $text =~ tr /a-z/A-Z/ if ($text);
-    $done .= $text;
-    $done = &convert_iso_latin_chars($done) if ($done);
-    join('',$done,$after);
-}
-
-sub do_cmd_lowercase {
-    local($_) = @_;
-    local($text,$next,$done,$special,$after);
-    $text = &missing_braces
-        unless ((s/$next_pair_pr_rx/$text = $2;''/seo)
-           || (s/$next_pair_rx/$text = $2;''/seo));
-    $after = $_;
-    while ($text =~ /(\\[a-zA-Z]+|[&;]SPM\w+;)/ ) {
-       $next = $`;
-       $special = $&;
-       $text = $';
-       $next =~ tr /A-Z/a-z/ if ($next);
-       $done .= $next . $special;
-    }
-    $text =~ tr /A-Z/a-z/ if ($text);
-    $done .= $text;
-    $done = &convert_iso_latin_chars($done) if ($done);
-    join('',$done,$after);
-}
-
-sub do_cmd_MakeUppercase { &do_cmd_uppercase(@_) }
-sub do_cmd_MakeLowercase { &do_cmd_lowercase(@_) }
-
-
-
-sub do_cmd_ensuremath {
-    local($_) = @_;
-    local ($id, $value);
-    $value = &missing_braces unless (
-       (s/$next_pair_pr_rx/$value=$2;''/eo)
-       ||(s/$next_pair_rx/$value=$2;''/eo));
-    join('', &simple_math_env($value), $');
-}
-
-#
-#  This is mainly for \special{header=PostScript_Prologue},
-#      and \graphicspath{path} which occur OUTSIDE of an environment
-#      passed to TeX.  \special's INSIDE such environments are, of
-#      course, left alone.
-
-sub do_cmd_special {
-    local($_) = @_;
-    local ($id, $value);
-    $value = &missing_braces unless (
-       (s/$next_pair_pr_rx/$value=$2;''/eo)
-       ||(s/$next_pair_rx/$value=$2;''/eo));
-    local($special_cmd) = &revert_to_raw_tex($value);
-    &add_to_preamble($cmd,"\\$cmd\{$special_cmd\}");
-    $_;
-}
-
-
-########################## Input and Include commands #########################
-
-sub do_cmd_input {
-    local($_) = @_;
-    local($file,$output);
-    (s/\s*(.*)\s*\n/$file =$1;''/s) unless (
-       (s/$next_pair_pr_rx/$file=$2;''/eo)
-       ||(s/$next_pair_rx/$file=$2;''/eo));
-    local($after) = $_;
-    $file = &revert_to_raw_tex("\\input{$file}\n") if $file;
-    if ($PREAMBLE) { &add_to_preamble('include',$file)}
-    elsif (!($file=~/^\s*$/)) {
-       $output = &process_undefined_environment('center'
-               , ++$global{'max_id'},"\\vbox{$file}");
-    }
-    $output.$after;
-}
-
-sub do_cmd_include {
-    local($_) = @_;
-    local($file,$output);
-    $file = &missing_braces unless (
-       (s/$next_pair_pr_rx/$file=$2;''/eo)
-       ||(s/$next_pair_rx/$file=$2;''/eo));
-    local($after) = $_;
-    $file = &revert_to_raw_tex("\\include{$file}\n") if $file;
-    if ($PREAMBLE) { &add_to_preamble('include',$file)}
-    else {
-       $output = &process_undefined_environment('figure'
-               , ++$global{'max_id'},"\\vbox{$file}");
-    }
-    $output.$after;
-}
-
-########################## Messages #########################
-
-sub do_cmd_message {
-    local($_) = @_;
-    local($message);
-    $message = &missing_braces unless (
-       (s/$next_pair_pr_rx/$message=$2;''/eo)
-       ||(s/$next_pair_rx/$message=$2;''/eo));
-    local($after) = $_;
-    $message = &translate_commands($message);
-    $message =~ s/$comment_mark(\d+)//og;
-    print STDOUT "\n*** $message ***\n";
-    $after;
-}
-
-sub do_cmd_typeout {
-    print STDOUT "\n";
-    local($_) = &do_cmd_message(@_);
-    print STDOUT "\n";
-    $_;
-}
-
-sub do_cmd_expandafter {
-    local($_) = @_;
-    print "\nEXPANDAFTER: " if ($VERBOSITY >3);
-    return($_) unless (s/^\s*(\\\w+)\s*\\//o);
-    print " delaying $1 " if ($VERBOSITY >3);
-    local($delay,$cmd) = ($1,'');
-    s/^(\w+|\W)/$cmd=$1;''/eo;
-    local($nextcmd) = "do_cmd_$cmd";
-    if (defined &$nextcmd) { $_ = &$nextcmd($_) }
-    elsif ($new_command{$cmd}) { 
-        local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd});
-       do { ### local($_) = $body;
-           &make_unique($body);
-       } if ($body =~ /$O/);
-       if ($argn) {
-           do {
-               local($before) = '';
-               local($after) = "\\$cmd ".$_;
-               $after = &substitute_newcmd;   # may change $after
-                $after =~ s/\\\@#\@\@/\\/o unless ($after);
-            };
-       } else { $_ = $body . $_; }
-    } else { print "\nUNKNOWN COMMAND: $cmd "; }
-
-    # now put the delayed function back for processing
-    join('',$delay, " ", $_);
-}
-
-sub do_cmd_tracingall {
-    print "\nTRACING:\n$ref_contents\n$after\n";
-    $VERBOSITY = 8; ""; }
-
-sub do_cmd_htmltracenv { &do_cmd_htmltracing }
-
-sub do_cmd_htmltracing {
-    local($_) = @_;
-    local($value);
-    $value = &missing_braces
-        unless ((s/$next_pair_rx/$value = $2;''/eo)
-           ||(s/$next_pair_pr_rx/$value = $2;''/eo));
-    if ($value =~ /^\s*(\d+)\s*$/) { 
-       $VERBOSITY = $1;
-       if ($VERBOSITY) { 
-           print "\n\n *** setting trace-level to $VERBOSITY ***\n";
-       } else {
-           print "\n\n *** cancelling all tracing ***\n\n";
-       }
-    } else {
-       &write_warnings("argument to \\htmltracing must be a number");
-     }
-    $_ ;
-}
-
-
-############################ Initialization ####################################
-
-sub initialise {
-    ############################ Global variables ###############################
-    $PREAMBLE = 2;             # 1 while translating preamble, 0 while translating body 
-    $NESTING_LEVEL = undef;    #counter for TeX group nesting level
-    $OUT_NODE = 0;             # Used in making filenames of HTML nodes unique
-    $eqno_prefix = '';         # default prefix on equation numbers
-    ($O , $C, $OP, $CP) = ('<<' , '>>', '<#', '#>'); # Open/Close Markers
-    $href_name = 0;            # Used in the HREF NAME= field
-    $wrap_toggle = 'end';
-    $delim = '%:%';            # Delimits items of sectioning information
-                               # stored in a string
-
-    $LATEX2HTML_META = '<META NAME="Generator" CONTENT="LaTeX2HTML v'.$TEX2HTMLV_SHORT.'">'
-       . "\n<META HTTP-EQUIV=\"Content-Style-Type\" CONTENT=\"text/css\">"
-             unless ($LATEX2HTML_META);
-
-    $TeXname = (($HTML_VERSION ge "3.0")? "T<SMALL>E</SMALL>X" : "TeX");
-    $Laname = (($HTML_VERSION ge "3.0")? "L<SUP><SMALL>A</SMALL></SUP>" : "La");
-    $MFname = (($HTML_VERSION ge "3.0")? "M<SMALL>ETAFONT</SMALL>" : "Metafont");
-    $Xyname = (($HTML_VERSION ge "3.0")? "X<SUB><BIG>Y</BIG></SUB>" : "Xy");
-    $AmSname = (($HTML_VERSION ge "3.0")? "A<SUB><BIG>M</BIG></SUB>S" : "AmS");
-
-    $EQN_TAGS = "R" unless ($EQN_TAGS);
-    $EQNO_START = "(";
-    $EQNO_END   = ")";
-
-    $AtBeginDocument_hook  = "\$AtBeginDocument_hook\=\'\'; "
-       unless $AtBeginDocument_hook;
-    $cross_ref_mark = '<tex2html_cr_mark>';
-    $external_ref_mark = '<tex2html_ext_cr_mark>';
-    $cite_mark = '<tex2html_cite_mark>';
-    $hash_mark = '<tex2html_hash_mark>';
-    $protected_hash = '<tex2html_protected_hash>';
-    $param_mark = '<tex2html_param_mark>';
-    $bbl_mark = '<tex2html_bbl_mark>';
-    $toc_mark = '<tex2html_toc_mark>';
-    $lof_mark = '<tex2html_lof_mark>';
-    $lot_mark = '<tex2html_lot_mark>';
-    $info_page_mark = '<tex2html_info_page_mark>';
-    $info_title_mark = '<tex2html_info_title_mark>';
-    $init_file_mark = '<tex2html_init_file_mark>';
-    $childlinks_on_mark = '<tex2html_childlinks_mark>';
-    $childlinks_null_mark = '<tex2html_childlinks_null_mark>';
-    $childlinks_mark = $childlinks_on_mark;
-    $more_links_mark = '<tex2html_morelinks_mark>';
-    $idx_mark = '<tex2html_idx_mark>';
-    $verbatim_mark = '<tex2html_verbatim_mark>';
-    $unfinished_mark = '<tex2html_unfinished_mark>';
-    $verb_mark = '<tex2html_verb_mark>';
-    $verbstar_mark = '<tex2html_verbstar_mark>';
-    $image_mark = '<tex2html_image_mark>';
-    $mydb_mark =  '<tex2html_mydb_mark>';
-    $percent_mark = '<tex2html_percent_mark>';
-    $ampersand_mark = '<tex2html_ampersand_mark>';
-    $dol_mark = '<tex2html_lone_dollar>';
-    $comment_mark = '<tex2html_comment_mark>';
-    $caption_mark = '<tex2html_caption_mark>';
-    $array_col_mark = '<tex2html_col_mark>';
-    $array_row_mark = '<tex2html_row_mark>';
-    $array_text_mark = '<tex2html_text_mark>';
-    $array_mbox_mark = '<tex2html_mbox_mark>';
-
-    $bibitem_counter = 0;
-    $undef_mark = '<tex2html_undef_mark>';
-    $file_mark = '<tex2html_file>';
-    $endfile_mark = '<tex2html_endfile>';
-
-    # This defines textual markers for all the icons
-    # e.g. $up_visible_mark = '<tex2html_up_visible_mark>';
-    # They will be replaced with the real icons at the very end.
-    foreach $icon (keys %icons) {eval "\$$icon = '<tex2html_$icon>'"};
-
-    # Make sure $HTML_VERSION is in the right range and in the right format.
-#    $HTML_VERSION =~ /[\d.]*/;
-#    $HTML_VERSION = 0.0 + $&;
-#    $HTML_VERSION = 2 if ( $HTML_VERSION < 2 );
-#    $HTML_VERSION = 9 if ( $HTML_VERSION > 9 );
-#    $HTML_VERSION = sprintf("%3.1f",$HTML_VERSION);
-
-    &banner();
-    print "Revised and extended by:"
-       . "\n Marcus Hennecke, Ross Moore, Herb Swan and others\n";
-
-    # Collect HTML options and figure out HTML version
-    $HTML_OPTIONS = '' unless ($HTML_OPTIONS);
-    $HTML_VERSION =~ s/^html|\s+//g;
-    local(@HTML_VERSION) = split(/,/, $HTML_VERSION);
-    foreach ( @HTML_VERSION ) {
-       if (/^[\d\.]+$/) {
-           # Make sure $HTML_VERSION is in the right range and in the right format.
-           $HTML_VERSION = 0.0 + $_;
-           $HTML_VERSION = 2 if ( $HTML_VERSION < 2 );
-           $HTML_VERSION = 9 if ( $HTML_VERSION > 9 );
-           $HTML_VERSION = sprintf("%3.1f",$HTML_VERSION);
-       } else {
-           $HTML_OPTIONS .= "$_,";
-       }
-    }
-    $HTML_OPTIONS =~ s/\W$//;  # remove any trailing punctuation
-
-    print "...producing markup for HTML version $HTML_VERSION  ";
-    print ($HTML_OPTIONS ? "with $HTML_OPTIONS extensions\n\n\n" : "\n\n\n");
-
-    # load the character defs for latin-1, but don't set the charset yet
-    &do_require_extension('latin1');
-    $charset = $CHARSET = $PREV_CHARSET = '';
-
-    if ($HTML_VERSION =~ /(2.0|3.0|3.2|4.0|4.1)/) {
-       # Require the version specific file 
-       do { $_ = "$LATEX2HTMLVERSIONS${dd}html$1.pl";
-            if (!(-f $_)) {  s/(\d).(\d.pl)$/$1_$2/ };
-            if (!(-f $_)) {  s/(\d)_(\d.pl)$/$1-$2/ };
-            require $_ || die "\n*** Could not load $_ ***\n";
-            print "\nHTML version: loading $_\n";
-       } unless ($HTML_VERSION =~ /2.0/);
-       $DOCTYPE = "-//".(($HTML_VERSION eq "2.0")? "IETF" : "W3C")
-           . "//DTD HTML $HTML_VERSION"
-           .(($HTML_VERSION eq "3.2")? " Final" : "")
-           .(($HTML_VERSION eq "4.0")? " Transitional" : "");
-
-       if ($HTML_OPTIONS) {
-           local($ext);
-           local($loading_extensions) = 1;
-           # Require the option specific files 
-           @HTML_VERSION = split(/,/, $HTML_OPTIONS);
-           foreach $ext ( @HTML_VERSION ) {
-               &do_require_extension($ext);
-#              do {
-#                  print "\nLoading $LATEX2HTMLVERSIONS$dd$ext.pl";
-#                  require "$LATEX2HTMLVERSIONS$dd$ext.pl";
-#              } if (-f "$LATEX2HTMLVERSIONS$dd$ext.pl");
-           }
-           undef $loading_extensions;
-       }
-    } else {
-       print "\n You specified an invalid version: $HTML_VERSION\n"
-           . "In future please request extensions by name:\n"
-           . "  i18n  table  math  frame  latin1  unicode  etc.\n";
-
-    # Require all necessary version specific files
-       foreach ( sort <$LATEX2HTMLVERSIONS${dd}html[1-9].[0-9].pl> ) {
-           last if ( $_ gt "$LATEX2HTMLVERSIONS${dd}html$HTML_VERSION.pl" );
-           do { print "\nloading $_" if ($DEBUG);
-                require $_; } unless (
-               ($NO_SIMPLE_MATH)&&($_ eq "$LATEX2HTMLVERSIONS${dd}html3.1.pl"));
-       };
-       $STRICT_HTML = 0;
-    }
-
-    # packages automatically implemented, or clearly irrelevant
-    %styles_loaded = 
-     ( 'theorem' , 1 , 'enumerate', 1 , 'a4paper' , 1 , 'b5paper' , 1
-     , '10pt' , 1 , '11pt' , 1 , '12pt' , 1
-     , %styles_loaded );
-
-
-    %declarations =
-    ('em' , '<EM></EM>',
-     'it' , '<I></I>',
-     'bf' , '<B></B>',
-     'tt' , '<TT></TT>',
-     'sl' , '<I></I>',         # Oops!
-     'sf' , '<I></I>',         # Oops!
-     'rm' ,  '<></>',
-     'rmfamily'   ,'<></>',     # see $fontchange_rx
-     'normalfont' ,'<></>',     # see $fontweight_rx and $fontchange_rx
-     'mdseries'   ,'<></>',     # see $fontweight_rx
-     'upshape'    ,'<></>',     # see $fontchange_rx
-     'itshape' ,  '<I></I>',
-     'bfseries' , '<B></B>',
-     'ttfamily' , '<TT></TT>',
-     'slshape' ,  '<I></I>',   # Oops!
-     'sffamily' , '<I></I>',   # Oops!
-##     'scshape' ,  '<I></I>', # Oops!
-#     'boldmath' , '<B></B>',
-#     'quote', '<BLOCKQUOTE></BLOCKQUOTE>',
-#     'quotation', '<BLOCKQUOTE></BLOCKQUOTE>',
-     %declarations     # Just in case someone extends it in the init file
-     );
-
-
-%declarations = (
-     'tiny', '<FONT SIZE="-2"></FONT>',
-     'Tiny', '<FONT SIZE="-2"></FONT>',
-     'scriptsize', '<FONT SIZE="-2"></FONT>',
-     'small', '<FONT SIZE="-1"></FONT>',
-     'Small', '<FONT SIZE="-1"></FONT>',
-     'SMALL', '<FONT SIZE="-1"></FONT>',
-     'smaller', '<SMALL></SMALL>',
-     'footnotesize', '<FONT SIZE="-1"></FONT>',
-     'larger', '<BIG></BIG>',
-     'large', '<FONT SIZE="+1"></FONT>',
-     'Large', '<FONT SIZE="+2"></FONT>',
-     'LARGE', '<FONT SIZE="+2"></FONT>',
-     'huge', '<FONT SIZE="+3"></FONT>',
-     'Huge', '<FONT SIZE="+4"></FONT>',
-#     'centering', '<DIV ALIGN="CENTER"></DIV>',
-#     'center', '<DIV ALIGN="CENTER"></DIV>',
-#     'flushleft', '<DIV ALIGN="LEFT"></DIV>',
-#     'raggedright', '<DIV ALIGN="LEFT"></DIV>',
-#     'flushright', '<DIV ALIGN="RIGHT"></DIV>',
-#     'raggedleft', '<DIV ALIGN="RIGHT"></DIV>',
-     %declarations
-    ) if ($HTML_VERSION > 2.0 );
-
-#  no alignment in HTML 2.0
-#%declarations = (
-#     'centering', '<P ALIGN="CENTER"></P>',
-#     'center', '<P ALIGN="CENTER"></P>',
-#     'flushleft', '<P ALIGN="LEFT"></P>',
-#     'raggedright', '<P ALIGN="LEFT"></P>',
-#     'flushright', '<P ALIGN="RIGHT"></P>',
-#     'raggedleft', '<P ALIGN="RIGHT"></P>',
-
-%declarations = (
-#     'centering', '<P></P>',
-     'center', '<P></P>',
-     'flushleft', '<P></P>',
-     'raggedright', '<P></P>',
-     'flushright', '<P></P>',
-     'raggedleft', '<P></P>',
-     'quote', '<BLOCKQUOTE></BLOCKQUOTE>',
-     'quotation', '<BLOCKQUOTE></BLOCKQUOTE>',
-     'verse', '<BLOCKQUOTE></BLOCKQUOTE>',
-     'preform', '<PRE></PRE>',
-     'unord', '<UL></UL>',
-     'ord', '<OL></OL>',
-     'desc', '<DL></DL>',
-     'list', '',
-     'par', '<P></P>'
-    ) if ($HTML_VERSION == 2.0 );
-
-    &generate_declaration_subs;        # Generate code to handle declarations
-
-    # ...but these block-level divisions must be handled differently...
-%declarations = (
-     'quote', '<BLOCKQUOTE></BLOCKQUOTE>',
-     'quotation', '<BLOCKQUOTE></BLOCKQUOTE>',
-     'verse', '<BLOCKQUOTE></BLOCKQUOTE>',
-     'preform', '<PRE></PRE>',
-     'unord', '<UL></UL>',
-     'ord', '<OL></OL>',
-     'desc', '<DL></DL>',
-#     'list', '<DIV></DIV>',
-     'par', '<P></P>',
-     'samepage', '',
-#     'centering', '<DIV ALIGN="CENTER"></DIV>',
-     'center', '<DIV ALIGN="CENTER"></DIV>',
-     'flushleft', '<DIV ALIGN="LEFT"></DIV>',
-     'raggedright', '<DIV ALIGN="LEFT"></DIV>',
-     'flushright', '<DIV ALIGN="RIGHT"></DIV>',
-     'raggedleft', '<DIV ALIGN="RIGHT"></DIV>',
-     %declarations
-    ) if ($HTML_VERSION > 2.0 );
-
-
-    %section_commands =
-       ('partstar' , '1' , 'chapterstar', '2', 'sectionstar', '3'
-       , 'subsectionstar', '4', 'subsubsectionstar', '5', 'paragraphstar'
-       , '6', 'subparagraphstar', '7'
-       , 'part' , '1' , 'chapter', '2', 'section', '3','subsection', '4'
-       , 'subsubsection', '5', 'paragraph', '6', 'subparagraph', '7'
-       , 'slidehead', '3', %section_commands);
-    # The tableofcontents, listoffigures, listoftables, bibliography and
-    # textohtmlindex are set after determining what is the outermost level
-    # in sub set_depth_levels. Appendix is implemented as a command.
-
-    %standard_section_headings =
-       ('part' , 'H1' , 'chapter' , 'H1', 'section', 'H1', 'subsection', 'H2'
-       , 'subsubsection', 'H3', 'paragraph', 'H4', 'subparagraph', 'H5'
-       , %standard_section_headings );
-
-    # Generates code to handle sectioning commands
-    # for those sections which take an argument.
-    &generate_sectioning_subs;
-
-    %section_headings =
-       ('partstar' , 'H1' , 'chapterstar' , 'H1', 'sectionstar', 'H1'
-       , 'subsectionstar', 'H2', 'subsubsectionstar', 'H3', 'paragraphstar'
-       , 'H4', 'subparagraphstar', 'H5', %section_headings);
-
-    # These need their own custom code but are treated as sectioning commands
-    %section_headings =
-       ('tableofcontents', 'H2', 'listoffigures', 'H2', 'listoftables', 'H2'
-       , 'bibliography', 'H2', 'textohtmlindex', 'H2'
-       , %standard_section_headings
-       , %section_headings);
-
-    &generate_accent_commands; # Code to handle accent commands
-
-    # These are replaced as soon as the text is read in.
-    %html_specials = (  '<', ';SPMlt;'
-               ,  '>', ';SPMgt;'
-               ,  '&', ';SPMamp;'
-#              ,  '``', '\lq\lq '  # probably not a good idea
-#              ,  "''", '\rq\rq ',  # probably not a good idea
-               ,  '"', ';SPMquot;'
-               );
-
-    %html_specials = ( %html_specials
-               , '``', ';SPMldquo;', "''", ';SPMrdquo;'
-               ) if ($HTML_VERSION >= 5 );
-
-    # This mapping is needed in sub revert_to_raw_tex
-    # before passing stuff to latex for processing.
-    %html_specials_inv = (
-                ';SPMlt;' ,'<'
-               , ';SPMgt;','>'
-               , ';SPMamp;','&'
-               , ';SPMquot;','"'
-               , ';SPMldquo;','``'
-               , ';SPMrdquo;',"''"
-               , ';SPMdollar;', '$'    # for alltt
-               , ';SPMpct;', '%'
-               , ';SPMtilde;', '&#126;'
-               );
-
-    # normalsize vertical dimension factors for 12pt (1.0 <=> <BR>)
-    %vspace_12pt = ('ex', 1.0, 'em', 1.0, 'pt', 0.1, 'pc', 1.0,
-       'in', 6.0, 'bp', 0.1, 'cm', 2.3, 'mm', 0.2, 'dd', 0.1,
-       'cc', 1.0, 'sp', 0.0);
-
-    # For some commands such as \\, \, etc it is not possible to define
-    # perl subroutines because perl does not allow some non-ascii characters
-    # in subroutine names. So we define a table and a subroutine to relate
-    # such commands to ascii names.
-    %normalize = ('\\', 'd_backslash'
-                 , '/', 'esc_slash', "`", 'grave'
-                 , "'", 'acute', "^", 'hat', '"', 'ddot'
-                 , '~', 'tilde', '.', 'dot', '=', 'bar'
-                 , '{', 'lbrace' , '}', 'rbrace', '|', 'Vert'
-                 , '#', 'esc_hash', '$', 'esc_dollar'
-                 );
-
-    %text_accent = (  'cedil','c', 'bdot','d', 'b','b' , 'tilde','~'
-                    , 'circ' ,'^', 'hat','^', 'check','v' , 'caron','v'
-                    , 'acute','\'' , 'grave','`' , 'dot','.' , 'breve','u'
-                    , 'ddot','"' , 'uml','"' , 'bar','=','macr','='
-                    , 'dblacc','H' , 't','t' , 'ogon','k' , 'ring','r'
-                  );
-
-    # %languages_translations holds for each known language the
-    # appropriate translation function. The function is called in
-    # slurp_input.
-    # The translation functions subtitute LaTeX macros
-    # with ISO-LATIN-1 character references
-    %language_translations = (
-          'english',   'english_translation'
-        , 'USenglish', 'english_translation'
-        , 'original',  'english_translation'
-        , 'german',    'german_translation'
-        , 'austrian',  'german_translation'
-        , 'finnish',   'finnish_translation'
-        , 'french',    'french_translation'
-        , 'spanish',   'spanish_translation'
-        , 'swedish',   'swedish_translation'
-        , 'turkish',   'turkish_translation'
-       );
-
-# Reiner: 
-#    $standard_label_rx = 
-#      "\\s*[[]\\s*(((\$any_next_pair_rx4)|([[][^]]*[]])|[^]])*)[]]";
-#    $enum_label_rx = "^((({[^{}]*})|([^{}]))*)([aAiI1])(.*)";
-#    $enum_level = 0;  # level for enumerate (1-4, i-iv)
-    %enum = ( 
-               'enumi',        0,                      # counter for level 1
-               'enumii',       0,                      # counter for level 2
-               'enumiii',      0,
-               'enumiv',       0,
-               'theenumi',     "&arabic('enumi')",     # eval($enum{"theenumi"})
-               'theenumii',    "&alph('enumii')",
-               'theenumiii',   "&roman('enumiii')",
-               'theenumiv',    "&Alph('enumiv')",
-                       # e.g. eval("$enum{'labelenumi'}")
-               'labelenumi',   'eval($enum{"theenumi"}) . "."', 
-               'labelenumii',  '"(" . eval($enum{"theenumii"}) . ")"', 
-               'labelenumiii', 'eval($enum{"theenumiii"}) . "."',
-               'labelenumiv',  'eval($enum{"theenumiv"}) . "."'
-               );
-
-    %RomanI = ( '1',"I",'2',"II",'3',"III",'4',"IV"
-                   ,'5',"V",'6',"VI",'7',"VII", '8',"VIII",'9',"IX");
-    %RomanX = ( '1',"X",'2',"XX",'3',"XXX",'4',"XL"
-                   ,'5',"L",'6',"LX",'7',"LXX", '8',"LXXX",'9',"XC");
-    %RomanC = ( '1',"C",'2',"CC",'3',"CCC",'4',"CD"
-                   ,'5',"D",'6',"DC",'7',"DCC", '8',"DCCC",'9',"CM");
-    %RomanM = ( '1',"M",'2',"MM",'3',"MMM",'4',"MH"
-                   ,'5',"H",'6',"HM",'7',"HMM",'8',"HMMM");
-
-    %enum_label_funcs = ( 
-       "a", "alph", "A", "Alph", "i", "roman", "I", "Roman", "1", "arabic" );
-
-sub farabic{
-    local($_)=@_;
-    $_;
-}
-sub arabic{
-    local($_)=@_;
-    eval($enum{$_});
-}
-
-sub falph{
-    local($num)=@_;
-#    chr($num+64);
-    substr(" abcdefghijklmnopqrstuvwxyz",$num,1)
-}
-sub alph{
-    local($num)=@_;
-    &falph(eval($enum{$num}));
-}
-sub fAlph{
-    local($num)=@_;
-#    chr($num+32);
-    substr(" ABCDEFGHIJKLMNOPQRSTUVWXYZ",$num,1)
-}
-sub Alph{
-    local($num)=@_;
-    &falph(eval($enum{$num}));
-}
-
-sub Roman{
-    local($num)=@_;
-    &fRoman(eval($enum{$num}));
-}
-sub fRoman{
-    local($num)=@_;
-    local($RmI)= $num%10; ($RmI) = (($RmI) ? $RomanI{"$RmI"} : '' );
-    $num = $num/10; local($RmX)= $num%10; ($RmX) = (($RmX) ? $RomanX{"$RmX"} : '' );
-    $num = $num/10; local($RmC)= $num%10; ($RmC) = (($RmC) ? $RomanC{"$RmC"} : '' );
-    $num = $num/10; local($RmM)= $num%10; ($RmM) = (($RmM) ? $RomanM{"$RmM"} : '' );
-    "$RmM" . "$RmC" . "$RmX" . "$RmI";
-}
-sub froman{
-    local($_)=@_;
-    $_ = &fRoman($_);
-    $_ =~ tr/A-Z/a-z/;
-    $_;
-}
-sub roman{
-    local($num)=@_;
-    &froman(eval($enum{$num}));
-}
-
-
-    %unitscale = ("in",72,"pt",72.27/72,"pc",12,"mm",72/25.4,"cm",72/2.54
-                 ,"\\hsize",100,"\\vsize",100
-                 ,"\\textwidth",100,"\\textheight",100
-                 ,"\\pagewidth",100,"\\linewidth",100
-                 );
-    %units = ("in","in","pt","pt","pc","pi","mm","mm","cm","cm"
-             ,"\\hsize","%","\\vsize","%","\\textwidth","%","\\textheight","%");
-
-sub convert_length { # clean
-    my ($this,$scale) = @_;
-    $scale = 1 unless $scale;
-    my ($pxs,$len,$full);
-    if ( $this =~ /([\d.]*)\s*(in|pt|pc|mm|cm|\\[hv]size|\\\w+(width|height))?/ ) {
-       $len = ($1 ? $1 : 1); $full = $2;
-       if ($full &&($full =~ /\\([hv]size|\w+(width|height))/)) { $scale = 1;};
-       $pxs = (($full) ? int($len * $unitscale{$full}*$scale + 0.5)
-                : int($len*$scale + .5) );
-       if ( $full =~ /\\([hv]size|\w+(width|height))/) { $pxs .= '%';};
-    };
-    ($pxs,$len);
-}
-
-
-
-    # Inclusion in this list will cause a command or an environment to be ignored.
-    # This is suitable for commands without arguments and for environments.
-    # If however a do_env|cmd_<env|cmd> exists then it will be used.
-    %ignore = ('sloppypar', 1,  'document', 1, 'newblock', 1,
-              ',', 1,  '@', 1, ' ', 1,  '-', 1,
-               'sloppy', 1,
-              'hyphen', 1, 'titlepage', 1, 'htmlonly', 1,
-              'flushleft', 1, 'flushright', 1, 'slide', 1,
-              'tiny', 1, 'Tiny', 1, 'scriptsize', 1, 'footnotesize', 1,
-              'small', 1, 'normalsize', 1, 'large', 1, 'Large', 1,
-              'LARGE', 1, 'huge', 1, 'Huge', 1,
-              %ignore);
-
-    # Specify commands with arguments that should be ignored.
-    # Arbitrary code can be placed between the arguments
-    # to be executed while processing the command.
-    #
-# Note that some commands MAY HAVE ARGUMENTS WHICH SHOULD BE LEFT AS TEXT
-    # EVEN THOUGH THE COMMAND IS IGNORED (e.g. hbox, center, etc)
-
-&ignore_commands( <<_IGNORED_CMDS_);
-NeedsTeXFormat # {} # []
-ProvidesClass # {} # []
-ProvidesFile # {} # []
-ProvidesPackage # {} # []
-abovedisplayskip # &ignore_numeric_argument
-abovedisplayshortskip # &ignore_numeric_argument
-addcontentsline # {} # {} # {}
-addtocontents # {} # {}
-addvspace # {} # &ignore_numeric_argument
-and
-and # \$_ = join(''," - ",\$_)
-backmatter
-baselineskip # &ignore_numeric_argument
-belowdisplayskip # &ignore_numeric_argument
-belowdisplayshortskip # &ignore_numeric_argument
-bibdata
-bibliographystyle # {}
-bibstyle # {}
-bigskipamount # &ignore_numeric_argument
-smallskipamount # &ignore_numeric_argument
-medskipamount # &ignore_numeric_argument
-center
-citation # {}
-citeauthoryear
-clearpage
-cline # {}
-#documentclass # [] # {}
-#documentstyle # [] # {}
-#end # {}
-enlargethispage # {}
-evensidemargin # &ignore_numeric_argument
-filecontents
-filbreak
-fil
-fill
-flushbottom
-fontsize # {} # {}
-footheight # &ignore_numeric_argument
-footskip  # &ignore_numeric_argument
-frontmatter
-fussy
-global
-goodbreak
-hbox
-headheight # &ignore_numeric_argument
-headsep # &ignore_numeric_argument
-hfil
-hfill
-hfuzz # &ignore_numeric_argument
-hline
-hspace # {} # \$_ = join(''," ",\$_)
-hspacestar # {} # \$_ = join(''," ",\$_)
-html
-ifcase
-ignorespaces
-indent
-itemindent # &ignore_numeric_argument
-itemsep # &ignore_numeric_argument
-labelsep # &ignore_numeric_argument
-labelwidth # &ignore_numeric_argument
-leavevmode
-leftmargin # &ignore_numeric_argument
-listparindent # &ignore_numeric_argument
-lower # &ignore_numeric_argument
-long
-mainmatter
-makebox # [] # []
-makeindex
-marginpar # {}
-marginparsep # &ignore_numeric_argument
-marginparwidth # &ignore_numeric_argument
-markboth # {} # {}
-markright # {}
-mathord
-mathbin
-mathindent # &ignore_numeric_argument
-mathrel
-mathop
-mathtt
-#mdseries
-newpage
-#newedboolean # {}
-#newedcommand # {} # [] # [] # {}
-#newedcounter # {} # []
-#newedenvironment # {} # [] # [] # {} # {}
-#newedtheorem # {} # [] # {} # []
-#providedcommand # {} # [] # [] # {}
-#renewedcommand # {} # [] # [] # {}
-#renewedenvironment # {} # [] # [] # {} # {}
-nobreakspace # \$_ = join('',";SPMnbsp;",\$_)
-nonbreakingspace # \$_ = join('',";SPMnbsp;",\$_)
-noalign
-nobreak
-nocite # {}
-noindent
-nolinebreak# []
-nopagebreak #[]
-normalmarginpar
-numberline
-oddsidemargin # &ignore_numeric_argument
-omit
-onecolumn
-outer
-pagenumbering #{}
-pagestyle # {}
-parindent # &ignore_numeric_argument
-parsep # &ignore_numeric_argument
-parskip # &ignore_numeric_argument
-partopsep # &ignore_numeric_argument
-penalty # &ignore_numeric_argument
-phantom # {}
-protect
-raggedright
-raggedbottom
-raise # &ignore_numeric_argument
-raisebox # {} # [] # []
-relax
-reversemarginpar
-rightmargin # &ignore_numeric_argument
-#rmfamily
-rule # [] # {} # {}
-samepage
-selectfont
-startdocument # \$SEGMENT=1;\$SEGMENTED=1; \$_
-strut
-suppressfloats # []
-textheight # &ignore_numeric_argument
-textwidth # &ignore_numeric_argument
-textnormal
-#textrm
-textup
-theorempreskipamount # &ignore_numeric_argument
-theorempostskipamount # &ignore_numeric_argument
-thispagestyle # {}
-topmargin # &ignore_numeric_argument
-topsep # &ignore_numeric_argument
-topskip # &ignore_numeric_argument
-twocolumn
-unskip
-#upshape
-vfil
-vfill
-vfilll
-vline
-_IGNORED_CMDS_
-
-    # Commands which need to be passed, ALONG WITH THEIR ARGUMENTS, to TeX.
-    # Note that this means that the arguments should *not* be translated,
-    # This is handled by wrapping the commands in the dummy tex2html_wrap
-    # environment before translation begins ...
-
-    # Also it can be used to specify environments which may be defined
-    # using do_env_* but whose contents will be passed to LaTeX and
-    # therefore should not be translated.
-    # Note that this code squeezes spaces out of the args of psfig;
-
-
-    # Images are cropped to the minimum bounding-box for these...
-
-&process_commands_in_tex (<<_RAW_ARG_CMDS_);
-psfig # {} # \$args =~ s/ //g;
-usebox # {}
-framebox # [] # [] # {}
-_RAW_ARG_CMDS_
-
-    # ... but these are set in a box to measure height/depth 
-    # so that white space can be preserved in the images.
-
-&process_commands_inline_in_tex (<<_RAW_ARG_CMDS_);
-#etalchar # {} \$args =~ s/(.*)/\$\^\{\$1\}\\\$/o; 
-fbox # {}
-#frac # [] # {} # {}
-dag
-ddag
-l
-L
-oe
-OE
-textexclamdown
-textquestiondown
-textregistered
-textperiodcentered
-#textcircled # {}
-#raisebox # {} # [] # [] # {}
-_RAW_ARG_CMDS_
-
-
-
-# These are handled by wrapping the commands in the dummy tex2html_nowrap
-# environment before translation begins. This environment will be
-# stripped off later, when the commands are put into  images.tex  ...
-
-&process_commands_nowrap_in_tex (<<_RAW_ARG_NOWRAP_CMDS_);
-#begingroup
-#endgroup
-#bgroup
-#egroup
-errorstopmode
-nonstopmode
-scrollmode
-batchmode
-psfigurepath # {}
-pssilent
-psdraft
-psfull
-thinlines
-thicklines
-linethickness # {}
-hyphenation # {}
-hyphenchar # \\ # &get_numeric_argument
-hyphenpenalty # &get_numeric_argument
-#let # \\ # <<\\(\\W|\\w+)>>
-newedboolean # {}
-newedcommand # {} # [] # [] # {}
-newedcounter # {} # []
-newedenvironment # {} # [] # [] # {} # {}
-newedtheorem # {} # [] # {} # []
-#providedcommand # {} # [] # [] # {}
-#renewedcommand # {} # [] # [] # {}
-#renewedenvironment # {} # [] # [] # {} # {}
-DeclareMathAlphabet # {} # {} # {} # {} # {}
-SetMathAlphabet # {} # {} # {} # {} # {} # {}
-DeclareMathSizes # {} # {} # {} # {}
-DeclareMathVersion # {}
-DeclareSymbolFont # {} # {} # {} # {} # {}
-DeclareSymbolFontAlphabet # {} # {}
-DeclareMathSymbol # {} # {} # {} # {}
-SetSymbolFont # {} # {} # {} # {} # {} # {}
-DeclareFontShape # {} # {} # {} # {} # {} # {}
-DeclareFontFamily # {} # {} # {}
-DeclareFontEncoding # {} # {} # {}
-DeclareFontSubstitution # {} # {} # {} # {}
-mathversion # {}
-#newfont # {} # {}
-#normalfont
-#rmfamily
-#mdseries
-newlength # {}
-setlength # {} # {}
-addtolength # {} # {}
-settowidth # {}# {}
-settoheight # {} # {}
-settodepth # {} # {}
-newsavebox # {}
-savebox # {} # [] # {}
-sbox # {} # {}
-setbox # {}
-TagsOnLeft  # \$EQN_TAGS = \"L\" if \$PREAMBLE;
-TagsOnRight # \$EQN_TAGS = \"R\" if \$PREAMBLE;
-_RAW_ARG_NOWRAP_CMDS_
-
-
-&process_commands_wrap_deferred (<<_RAW_ARG_DEFERRED_CMDS_);
-alph # {}
-Alph # {}
-arabic # {}
-author # [] # {}
-boldmath
-unboldmath
-captionstar # [] # {}
-caption # [] # {}
-#endsegment # []
-#segment # [] # {} # {} # {}
-fnsymbol # {}
-footnote # [] # {}
-footnotemark # []
-footnotetext # [] # {}
-#thanks # {}
-roman # {}
-Roman # {}
-#mbox # {}
-parbox # [] # [] # [] # {} # {}
-#selectlanguage # [] # {}
-setcounter # {} # {}
-addtocounter # {} # {}
-stepcounter # {}
-refstepcounter # {}
-value # {}
-par
-hrule # &ignore_numeric_argument
-linebreak # []
-pagebreak # []
-newfont # {} # {}
-smallskip
-medskip
-bigskip
-centering
-raggedright
-raggedleft
-itshape
-#textit # {}
-upshape
-slshape
-#scshape
-rmfamily
-sffamily
-ttfamily
-mdseries
-bfseries
-#textbf # {}
-em
-normalfont
-it
-rm
-sl
-bf
-tt
-sf
-Tiny
-tiny
-scriptsize
-footnotesize
-small
-Small
-SMALL
-normalsize
-large
-Large
-LARGE
-huge
-Huge
-lowercase # {}
-uppercase # {}
-MakeLowercase # {}
-MakeUppercase # {}
-htmlinfo # []
-htmlinfostar # []
-tableofchildlinks # []
-tableofchildlinksstar # []
-tableofcontents
-listoffigures
-listoftables
-thepart
-thepage
-thechapter
-thesection
-thesubsection
-thesubsubsection
-theparagraph
-thesubparagraph
-theequation
-htmltracenv # {}
-HTMLsetenv # [] # {} # {}
-#newedboolean # {}
-#newedcounter # {} # []
-#newedcommand # {} # [] # [] # {}
-#newedtheorem # {} # [] # {} # []
-#newedenvironment # {} # [] # [] # {} # {}
-providedcommand # {} # [] # [] # {}
-renewedcommand # {} # [] # [] # {}
-renewedenvironment # {} # [] # [] # {} # {}
-url # {}
-htmlurl # {}
-latextohtml
-TeX
-LaTeX
-LaTeXe
-LaTeXiii
-Xy
-MF
-AmS
-AmSTeX
-textcircled # {}
-_RAW_ARG_DEFERRED_CMDS_
-
-
-#rrm
-# implement the XBit-Hack for Apache servers, to handle
-# Server-Side Includes (SSIs) with .html filename extension
-#
-sub check_htaccess {
-    my $access_file = '.htaccess';
-    my $has_access = '';
-    local $_;
-    print "\nChecking for .htaccess  file";
-    if (-f $access_file) {
-       print STDOUT " ... found";
-       open(HTACCESS, "<$access_file");
-       while (<HTACCESS>) {
-           if (/^\s*XBitHack\s*on\s*$/) {
-               print STDOUT " with XBitHack on";
-               $has_access =1; last;
-           };
-       }
-       print STDOUT "\n";
-       close HTACCESS;
-       return() if $has_access;
-       open (HTACCESS, ">>$access_file");
-       &write_warnings("appended to .htaccess in $DESTDIR");
-    } else {
-       open (HTACCESS, ">$access_file");
-       chmod 0644, $access_file;
-       &write_warnings("created .htaccess file in $DESTDIR");
-    }
-    print HTACCESS "\nXBitHack on\n";
-    close HTACCESS;
-}
-
-# This maps the HTML mnemonic names for the ISO-LATIN-1 character references
-# to their numeric values. When converting latex specials characters to
-# ISO-LATIN-1 equivalents I use the numeric values because this makes any
-# conversion back to latex (using revert_raw_tex) more reliable (in case
-# the text contains "&mnemonic_name"). Errors may occur if an environment
-# passed to latex (e.g. a table) contains the numeric values of character
-# references.
-
-# RRM: removed this portion; load from  latin1.pl instead
-#&do_require_extension('latin1');
-
-sub make_isolatin1_rx {
-    local($list) = &escape_rx_chars(join($CD,(values %iso_8859_1_character_map_inv)));
-    $list =~ s/$CD/|/g;
-    $isolatin1_rx = "($list)";
-}
-
-
-    ################### Frequently used regular expressions ###################
-    # $1 : preamble
-
-    $preamble_rx = "(^[\\s\\S]*)(\\\\begin\\s*$O\\d+$C\\s*document\\s*$O\\d+$C|\\\\startdocument)";
-
-    # \d (number) should sometimes also be a delimiter but this causes
-    # problems with command names  that are allowed to contain numbers (eg tex2html)
-    # \d is a delimiter with commands which take numeric arguments?
-    # JCL: I can't see that. \tex2html is also no valid LaTeX (or TeX).
-    # It is parsed \tex 2html, and \tex may take 2html as argument, but this
-    # is invalid LaTeX. \d must be treated as delimiter.
-
-# JCL(jcl-del) - Characters to be treated as letters, everything else
-# is a delimiter.
-    # internal LaTeX command separator, shouldn't be equal to $;
-    $CD = "\001";
-    &make_cmd_spc_rx; # determines space to follow a letter command
-#old    $delimiters = '\'\\s[\\]\\\\<>(=).,#;:~\/!-';
-    $letters = 'a-zA-Z';
-    $delimiter_rx = "([^$letters])";
-#
-
-    # liberalized environment names (white space, optional arg, interpunctuation signs etc.)
-    # $1 : br_id, $2 : <environment>
-    $begin_env_rx="(\\\\protect)?\\\\begin\\s*(\\[([^\\]]*)])?$O(\\d+)$C\\s*([^'[\\]\\\\#~]+)\\s*$O\\4$C";
-    $begin_env_pr_rx="(\\\\protect)?\\\\begin\\s*(\\[([^\\]]*)])?$OP(\\d+)$CP\\s*([^'[\\]\\\\#~]+)\\s*$OP\\4$CP";
-
-    $mbox_rx = "\\\\mbox\\s*";
-
-    $match_br_rx = "\\s*$O\\d+$C\\s*";
-
-    $opt_arg_rx = "\\s*\\[([^\\]]*)\\]\\s*";   # Cannot handle nested []s!
-    $optional_arg_rx = "^\\s*\\[([^]]*)\\]";   # Cannot handle nested []s!
-
-    $block_close_rx = "^<\\/(DIV|P|BLOCKQUOTE)>\$";
-    $all_close_rx = "^<\\/(BODY|PRE|OL|UL|DL|FORM|ADDRESS)>\$";
-
-    # Matches a pair of matching brackets
-    # $1 : br_id
-    # $2 : contents
-    $next_pair_rx = "^[\\s%]*$O(\\d+)$C([\\s\\S]*)$O\\1$C($comment_mark\\d*\\n?)?";
-
-    # will comments be a problem after these ???
-    $any_next_pair_rx = "$O(\\d+)$C([\\s\\S]*)$O\\1$C";
-    $any_next_pair_rx4 = "$O(\\d+)$C([\\s\\S]*)$O\\4$C";
-    $any_next_pair_pr_rx4 = "$OP(\\d+)$CP([\\s\\S]*)$OP\\4$CP";
-    $any_next_pair_rx5 = "$O(\\d+)$C([\\s\\S]*)$O\\5$C";
-    $any_next_pair_rx6 = "$O(\\d+)$C([\\s\\S]*)$O\\6$C";
-
-    # used for labels in {enumerate} environments
-    $standard_label_rx = 
-       "\\s*[[]\\s*((($any_next_pair_rx4)|([[][^]]*[]])|[^]])*)[]]";
-    $enum_label_rx = "^((({[^{}]*})|([^{}]))*)([aAiI1])(.*)";
-    $enum_level = 0;   # level for enumerate (1-4, i-iv)
-
-
-    # Matches the \ensuremath command
-    $enspair = "\\\\ensuremath\\s*" . $any_next_pair_rx;
-#    $enspair = "\\\\ensuremath\\s*$O(\\d+)$C([\\s\\S]*[\\\\\$&]+[\\s\\S]*)$O\\1$C";
-
-    # Matches math comments, from  math.pl
-    $math_verbatim_rx = "$verbatim_mark#math(\\d+)#";
-    $mathend_verbatim_rx = "$verbatim_mark#mathend([^#]*)#";
-
-    # Matches math array environments
-    $array_env_rx = "array|cases|\\w*matrix";
-
-    # initially empty; has a value in HTML 3.2 and 4.0
-    $math_class = '' unless ($math_class);
-    $eqno_class = '' unless ($eqno_class);
-
-    # Matches to end-of-line and subsequent spaces
-    $EOL = "[ \\t]*\\n?";
-
-    # Matches wrapped \par command
-    $par_rx = "\\n?\\\\begin(($O|$OP)\\d+($C|$CP))tex2html_deferred\\1\\\\par\\s\*"
-        . "\\\\end(($O|$OP)\\d+($C|$CP))tex2html_deferred\\4\\n?";
-
-    # $1 : br_id
-    $begin_cmd_rx = "$O(\\d+)$C";
-
-    # $1 : image filename prefix
-    $img_rx = "(\\w*T?img\\d+)";
-
-    # $1 : largest argument number
-    $tex_def_arg_rx = "^[#0-9]*#([0-9])($O|$OP)";
-
-    #   only some non-alphanumerics are allowed in labels,  Why?
-    $label_rx = "[^\\w\.\\\-\\\+\\\:]";
-
-#JCL(jcl-del) - new face, see also &do_cmd_makeatletter et.al.
-#    $cmd_delims = q|-#,.~/\'`^"=\$%&_{}@|; # Commands which are also delimiters!
-#    $single_cmd_atletter_rx = "\\\\([a-zA-Z\\\@]+\\*?|[$cmd_delims]|\\\\)";
-#    $single_cmd_atother_rx = "\\\\([a-zA-Z]+\\*?|[$cmd_delims]|\\\\)";
-    # $1 : declaration or command or newline (\\)
-    &make_single_cmd_rx;
-#
-
-    # $1 : description in a list environment
-    $item_description_rx =
-#      "\\\\item\\s*[[]\\s*((($any_next_pair_rx4)|([[][^]]*[]])|[^]])*)[]]";
-       "\\\\item\\s*[[]\\s*((($any_next_pair_pr_rx4)|([[][^]]*[]])|[^]])*)[]]";
-
-    $fontchange_rx = 'rm|em|it|sl|sf|tt|sc|upshape|normalfont';
-    $fontweight_rx = 'bf|mdseries|normalfont';
-    $colorchange_rx = "(text)?color\\s*(\#\\w{6})?";
-    $sizechange_rx = 'tiny|Tiny|scriptsize|footnotesize|small|Small|SMALL' .
-       '|normalsize|large|Large|LARGE|huge|Huge';
-
-#    $image_switch_rx = "makeimage";
-    $image_switch_rx = "makeimage|scshape|sc";
-    $env_switch_rx = "writetolatex";
-    $raw_arg_cmds{'font'} = 1;
-
-    # Matches the \caption command
-    # $1 : br_id
-    # $2 : contents
-     $caption_suffixes = "lof|lot";
-#    $caption_rx = "\\\\caption\\s*([[]\\s*((($any_next_pair_rx5)|([[][^]]*[]])|[^]])*)[]])?$O(\\d+)$C([\\s\\S]*)$O\\8$C$EOL";
-
-    $caption_rx = "\\\\(top|bottom|table)?caption\\s*\\\*?\\s*([[]\\s*((($any_next_pair_rx6)|([[][^]]*[]])|[^]])*)[]])?$O(\\d+)$C([\\s\\S]*)$O\\9$C$EOL";
-    $caption_width_rx = "\\\\setlength\\s*(($O|$OP)\\d+($C|$CP))\\\\captionwidth\\1\\s*(($O|$OP)\\d+($C|$CP))([^>]*)\\4";
-
-    # Matches the \htmlimage command
-    # $1 : br_id
-    # $2 : contents
-    $htmlimage_rx = "\\\\htmlimage\\s*$O(\\d+)$C([\\s\\S]*)$O\\1$C$EOL";
-    $htmlimage_pr_rx = "\\\\htmlimage\\s*$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP$EOL";
-
-    # Matches the \htmlborder command
-    # $1 : optional argument...
-    # $2 : ...contents  i.e. extra attributes
-    # $3 : br_id
-    # $4 : contents i.e. width
-    $htmlborder_rx = "\\\\htmlborder\\s*(\\[([^]]*)\\])?\\s*$O(\\d+)$C(\\d*)$O\\3$C$EOL";
-    $htmlborder_pr_rx = "\\\\htmlborder\\s*(\\[([^]]*)\\])?\\s*$OP(\\d+)$CP(\\d*)$OP\\3$CP$EOL";
-
-    # Matches a pair of matching brackets
-    # USING PROCESSED DELIMITERS;
-    # (the delimiters are processed during command translation)
-    # $1 : br_id
-    # $2 : contents
-#    $next_pair_pr_rx = "^[\\s%]*$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP";
-    $next_pair_pr_rx = "^[\\s%]*$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP($comment_mark\\d*\\n?)?";
-    $any_next_pair_pr_rx = "$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP($comment_mark\\d*\\n?)?";
-    $next_token_rx = "^[\\s%]*(\\\\[A-Za-z]+|\\\\[^a-zA-Z]|.)";
-
-    $HTTP_start = 'http:';
-
-    # This will be used to recognise escaped special characters as such
-    # and not as commands
-    $latex_specials_rx = '[\$]|&|%|#|{|}|_';
-    $html_escape_chars = '<>&';
-
-    # This is used in sub revert_to_raw_tex before handing text to be processed
-    # by latex.
-    $html_specials_inv_rx = join("|", keys %html_specials_inv);
-
-    # These are used for direct replacements in/from  ALT=... strings
-    %html_special_entities = ('<','lt','>','gt','"','quot','&','amp');
-    %html_spec_entities_inv = ('lt','<','gt','>','quot','"','amp','&');
-
-    # This is also used in sub revert_to_raw_tex
-    $character_entity_rx = '(&#(\d+);)';
-    $named_entity_rx = '&(\w+);';
-
-    #commands for altering theorem-styles
-    $theorem_cmd_rx = 'theorem(style|(header|body)font)';
-
-
-    # Matches a \begin or \end {tex2html_wrap}. Also used by revert_to_raw_tex
-    $tex2html_wrap_rx = '\\\\(begin|end)\\s*\{\\s*(tex2html_(wrap|nowrap|deferred|nomath|preform|\\w*_inline)[_a-z]*|makeimage)\\s*\}'."($EOL)";
-    $tex2html_deferred_rx = '\\\\(begin|end)(<<\\d+>>)tex2html_deferred\\2';
-    $tex2html_deferred_rx2 = '\\\\(begin|end)(<<\\d+>>)tex2html_deferred\\4';
-    $tex2html_envs_rx = "\\\\(begin|end)\\s*(($O|$OP)\\d+($C|$CP))\\s*(tex2html_(wrap|nowrap|deferred|nomath|preform|\w+_inline)[_a-z]*||makeimage)\\s*\\2";
-
-    # The first empty parenthese pair is for non-letter commands.
-    # $2: meta command, $4: delimiter (may be empty)  ignore the *-version distinction
-#    $meta_cmd_rx = "()\\\\(providecommand|renewcommand|renewenvironment|newcommand|newenvironment|newtheorem|newcounter|newboolean|newif|let)(([^$letters$cmd_spc])|$cmd_spcs_rx)";
-    $meta_cmd_rx = "()\\\\(providecommand|renewcommand|renewenvironment|newcommand|newenvironment|newtheorem|newcounter|newboolean|newif|DeclareRobustCommand|DeclareMathOperator\\*?)\\\*?(([^$letters$cmd_spc])|$cmd_spcs_rx)";
-
-    &make_counters_rx;
-
-    # Matches a label command and its argument
-    $labels_rx = "\\\\label\\s*$O(\\d+)$C([\\s\\S]*)$O\\1$C$EOL";
-    $labels_rx8 = "\\\\label\\s*$O(\\d+)$C([\\s\\S]*)$O\\8$C$EOL";
-
-    # Matches environments that should not be touched during the translation
-#   $verbatim_env_rx = "\\s*{(verbatim|rawhtml|LVerbatim)[*]?}";
-    $verbatim_env_rx = "\\s*(\\w*[Vv]erbatim|rawhtml|imagesonly|tex2html_code)[*]?";
-    $image_env_rx = "\\s*(picture|xy|diagram)[*]?";
-    $keepcomments_rx = "\\s*(picture|makeimage|xy|diagram)[*]?";
-
-    # names of different math environment types
-    $display_env_rx = "displaymath|makeimage|eqnarray|equation";
-    $inline_env_rx = "inline|indisplay|entity|xy|diagram";
-    $sub_array_env_rx = "array|(small|\\w)\?matrix|tabular|cases";
-
-    # Matches environments needing pre-processing for images
-    $pre_processor_env_rx = "\\\\(begin|end)\\s*(($O|$OP|\{)\\d+($C|$CP|\}))pre_(\\w+)\\2";
-
-    # Matches icon markers
-    $icon_mark_rx = "<tex2html_(" . join("|", keys %icons) . ")>";
-
-    $start_time = time;
-    print STDOUT join(" ", "Starting at", $start_time, "seconds\n")
-        if ($TIMING||$DEBUG||($VERBOSITY>2));
-
-}      # end of &initialise
-
-# Frequently used regular expressions with arguments
-sub make_end_env_rx {
-    local($env) = @_;
-    $env = &escape_rx_chars($env);
-    "\\\\end\\s*$O(\\d+)$C\\s*$env\\s*$O\\1$C".$EOL;
-}
-
-sub make_begin_end_env_rx {
-    local($env) = @_;
-    $env = &escape_rx_chars($env);
-    "\\\\(begin|end)\\s*$O(\\d+)$C\\s*$env\\s*$O\\3$C(\\s*\$)?";
-}
-
-sub make_end_cmd_rx {
-    local($br_id) = @_;
-    "$O$br_id$C";
-}
-
-#JCL(jcl-del) - see also &tokenize.
-# Arrange commands into a regexp for tokenisation.
-# Any letter command will gobble spaces, but avoids to match
-# on ensuing letters (\foo won't match on \foox).
-# Any non-letter command retains spaces and matches always
-# by itself (\| matches \|... regardless of ...).
-#
-# This all is a huge kludge. The commands names should stay fix,
-# regardless of changing catcodes. If we have \makeatletter,
-# and LaTeX2HTML marks \@foo, then \@foo will be expanded
-# properly before \makeatother, but does weird things on \@foo
-# after \makeatother (\@foo in LaTeX is then \@ and foo, which
-# isn't recognized as such).
-# The reason is that the text to match the command \@foo
-# in LaTeX mustn't be \@foo at all, because any text in LaTeX
-# is also attributed with the category codes.
-#
-# But at least we have proper parsing of letter and non-letter
-# commands as long as catcoding won't upset LaTeX2HTML too much.
-#
-sub make_new_cmd_rx {
-    return("") if $#_ < 0; # empty regexp if list is empty!
-
-    # We have a subtle treatment of ambivalent commands like
-    # \@foo in situations depicted above!
-    # Get every command that contains no letters ...
-    local($nonlettercmds) =
-       &escape_rx_chars(join($CD, grep(!/[$letters]/,@_)));
-    # and every command that contains a letter
-    local($lettercmds) =
-       &escape_rx_chars(join($CD, grep(/[$letters]/,@_)));
-
-    if (%renew_command) {
-       local($renew);
-       foreach $renew (keys %renew_command) {
-           $lettercmds =~ s/(^|$CD)$renew//; }
-        $lettercmds =~ s/^$CD$//;
-    }
-
-    # replace the temporary $CD delimiter (this enables eg. \| command)
-    $nonlettercmds =~ s/$CD/|/g;
-    $lettercmds =~ s/$CD/|/g;
-
-    # In case we have no non-letter commands, insert empty parentheses
-    # to align match strings.
-    #
-    $nonlettercmds =~ s/^\||\|$//g;
-    $lettercmds =~ s/^\||\|$//g;
-    local($rx) = (length($nonlettercmds) ? "\\\\($nonlettercmds)" : "");
-    if (length($lettercmds)) {
-       $rx .= ( length($rx) ? "|" : "()" );
-       $rx .= "\\\\($lettercmds)(([^$letters$cmd_spc])|$cmd_spcs_rx|\$)";
-    }
-    # $1: non-letter cmd, $2: letter cmd, $4: delimiter
-    # Eg. \\(\@|...|\+)|\\(abc|...|xyz)(([^a-zA-Z \t])|[ \t]+)
-    # $1 and $2 are guaranteed to alternate, $4 may be empty.
-    $rx;
-}
-
-# Build a simple regexp to use after tokenisation for
-# faster translation.
-sub make_new_cmd_no_delim_rx {
-    return("") if $#_ < 0; # empty regexp if list is empty!
-    # Get every command that contains no letters ...
-    local($_) = &escape_rx_chars(join($CD, @_));
-    s/$CD/|/g;
-
-    join('',"\\\\(",$_,")");
-}
-
-
-#JCL(jcl-del) - new face: w/o arg (was 'begin' only), escapes env names
-sub make_new_env_rx {
-    local($envs) = &escape_rx_chars(join($CD, keys %new_environment));
-    $envs =~ s/$CD/|/g;
-    length($envs) ? "\\\\begin\\s*$O(\\d+)$C\\s*($envs)\\s*$O\\1$C\\s*" : "";
-}
-
-sub make_new_end_env_rx {
-    local($envs) = &escape_rx_chars(join($CD, keys %new_environment));
-    $envs =~ s/$CD/|/g;
-    length($envs) ? "\\\\end\\s*$O(\\d+)$C\\s*($envs)\\s*$O\\1$C\\s*" : "";
-}
-
-#JCL(jcl-del) - $delimiter_rx -> ^$letters
-# don't care for $cmd_spc_rx; space after sectioning commands
-# is unlikely and I don't want to try too much new things
-#
-sub make_sections_rx {
-    local($section_alts) = &get_current_sections;
-    # $section_alts includes the *-forms of sectioning commands
-    $sections_rx = "()\\\\($section_alts)(([^$letters$cmd_spc])|$cmd_spcs_rx|\$)";
-#    $sections_rx = "()\\\\($section_alts)([^$letters])";
-}
-
-sub make_order_sensitive_rx {
-    local(@theorem_alts, $theorem_alts);
-    @theorem_alts = ($preamble =~ /\\newtheorem\s*{([^\s}]+)}/og);
-    $theorem_alts = join('|',@theorem_alts);
-#
-#  HWS: Added kludge to require counters to be more than 2 characters long
-#      in order to be flagged as order-sensitive.  This will permit equations
-#      with \theta to remain order-insensitive.  Also permit \alpha and
-#      the eqnarray* environment to remain order-insensitive.
-#
-    $order_sensitive_rx =
-#        "(equation|eqnarray[^*]|\\\\caption|\\\\ref|\\\\the[a-z]{2,2}[a-z]|\\\\stepcounter" .
-        "(\\\\caption|\\\\ref|\\\\the[a-z]{2,2}[a-z]|\\\\stepcounter" .
-        "|\\\\arabic|\\\\roman|\\\\Roman|\\\\alph[^a]|\\\\Alph|\\\\fnsymbol)";
-    $order_sensitive_rx =~ s/\)/|$theorem_alts)/ if $theorem_alts;
-}
-
-sub make_language_rx {
-    local($language_alts) = join("|", keys %language_translations);
-#    $setlanguage_rx = "\\\\se(lec)?tlanguage\\s*{\\\\?($language_alts)}";
-    $setlanguage_rx = "\\\\setlanguage\\s*{\\\\?($language_alts)}";
-    $language_rx = "\\\\($language_alts)TeX";
-    $case_change_rx = "(\\\\(expandafter|noexpand)\s*)?\\\\((Make)?([Uu]pp|[Ll]ow)ercase)\s*";
-}
-
-sub addto_languages {
-    local($lang) = @_;
-    local($trans) = "main'".$lang.'_translation';
-    if (defined &$trans) {
-       $language_translations {$lang} = $lang.'_translation';
-    }
-}
-
-# JCL(jcl-del) - new rexexp type
-sub make_raw_arg_cmd_rx {
-    # $1 or $2 : commands to be processed in latex (with arguments untouched)
-    # $4 : delimiter
-    $raw_arg_cmd_rx = &make_new_cmd_rx(keys %raw_arg_cmds);
-    $raw_arg_cmd_rx;
-}
-
-# There are probably more.
-# Interferences not checked out yet, thus in makeat... only.
-sub make_letter_sensitive_rx {
-    $delimiter_rx = "([^$letters])";
-    &make_sections_rx;
-    &make_single_cmd_rx;
-    &make_counters_rx;
-}
-
-#JCL(jcl-del) - this could eat one optional newline, too.
-# But this might result in large lines... anyway, it *should* be
-# handled. A possible solution would be to convert adjacent newlines
-# into \par's in preprocessing.
-sub make_cmd_spc_rx {
-    $cmd_spc = " \\t";
-    $cmd_spc_rx = "[ \\t]*"; # zero or more
-    $cmd_spcs_rx = "[ \\t]+"; # one or more
-}
-
-sub make_single_cmd_rx {
-    $single_cmd_rx = "\\\\([^$letters])|\\\\([$letters]+\\*?)(([^$letters$cmd_spc])|$cmd_spcs_rx|\n|\$)";
-}
-
-sub make_counters_rx {
-    # Matches counter commands - these are caught early and are appended to the
-    # file that is passed to latex.
-#JCL(jcl-del) - $delimiter_rx -> ^$letters
-    $counters_rx = "()\\\\(newcounter|addtocounter|setcounter|refstepcounter|stepcounter|arabic|roman|Roman|alph|Alph|fnsymbol)(([^$letters$cmd_spc])|$cmd_spcs_rx|\$)";
-}
-
-
-# Creates an anchor for its argument and saves the information in
-# the array %index;
-# In the index the word will use the beginning of the title of
-# the current section (instead of the usual pagenumber).
-# The argument to the \index command is IGNORED (as in latex)
-sub make_index_entry { &make_real_index_entry(@_) }
-sub make_real_index_entry {
-    local($br_id,$str) = @_;
-    local($this_file) = $CURRENT_FILE;
-    $TITLE = $saved_title if (($saved_title)&&(!($TITLE)||($TITLE eq $default_title)));
-    # Save the reference
-    $str = "$str###" . ++$global{'max_id'}; # Make unique
-    $index{$str} .= &make_half_href($this_file."#$br_id");
-    "<A NAME=\"$br_id\">$anchor_invisible_mark<\/A>";
-}
-
-sub image_message { # clean
-    print <<"EOF";
-
-To resolve the image conversion problems please consult
-the "Troubleshooting" section of your local User Manual
-or read it online at
-   http://www-texdev.ics.mq.edu.au/l2h/docs/manual/
-
-EOF
-}
-
-sub image_cache_message { # clean
-   print <<"EOF";
-
-If you are having problems displaying the correct images with Mosaic,
-try selecting "Flush Image Cache" from "Options" in the menu-bar
-and then reload the HTML file.
-EOF
-}
-
-__DATA__
-
-# start of POD documentation
-
-=head1 NAME
-
-latex2html - Translate LaTeX files to HTML (HyperText Markup Language)
-
-=head1 SYNOPSIS
-
-B<latex2html> S<[ B<-help> | B<-h> ]> S<[ B<-version> | B<-V> ]>
-
-B<latex2html> S<[ B<-split> I<num> ]>
-S<[ B<-link> I<num> ]>
-S<[ B<-toc_depth> I<num> ]>
-S<[ B<->(B<no>)B<toc_stars> ]>
-S<[ B<->(B<no>)B<short_extn> ]>
-S<[ B<-iso_language> I<lang> ]>
-S<[ B<->(B<no>)B<validate> ]>
-S<[ B<->(B<no>)B<latex> ]>
-S<[ B<->(B<no>)B<djgpp> ]>
-S<[ B<->(B<no>)B<fork> ]>
-S<[ B<->(B<no>)B<external_images> ]>
-S<[ B<->(B<no>)B<ascii_mode> ]>
-S<[ B<->(B<no>)B<lcase_tags> ]>
-S<[ B<->(B<no>)B<ps_images> ]>
-S<[ B<-font_size> I<size> ]>
-S<[ B<->(B<no>)B<tex_defs> ]>
-S<[ B<->(B<no>)B<navigation> ]>
-S<[ B<->(B<no>)B<top_navigation> ]>
-S<[ B<->(B<no>)B<buttom_navigation> ]>
-S<[ B<->(B<no>)B<auto_navigation> ]>
-S<[ B<->(B<no>)B<index_in_navigation> ]>
-S<[ B<->(B<no>)B<contents_in_navigation> ]>
-S<[ B<->(B<no>)B<next_page_in_navigation> ]>
-S<[ B<->(B<no>)B<previous_page_in_navigation> ]>
-S<[ B<->(B<no>)B<footnode> ]>
-S<[ B<->(B<no>)B<numbered_footnotes> ]>
-S<[ B<-prefix> I<output_filename_prefix> ]>
-S<[ B<->(B<no>)B<auto_prefix> ]>
-S<[ B<-long_titles> I<num> ]>
-S<[ B<->(B<no>)B<custom_titles> ]>
-S<[ B<-title>|B<-t> I<top_page_title> ]>
-S<[ B<->(B<no>)B<rooted> ]>
-S<[ B<-rootdir> I<output_directory> ]>
-S<[ B<-dir> I<output_directory> ]>
-S<[ B<-mkdir> ]>
-S<[ B<-address> I<author_address> | B<-noaddress> ]>
-S<[ B<->(B<no>)B<subdir> ]>
-S<[ B<-info> I<0> | I<1> | I<string> ]>
-S<[ B<->(B<no>)B<auto_link> ]>
-S<[ B<-reuse> I<num> | B<-noreuse> ]>
-S<[ B<->(B<no>)B<antialias_text> ]>
-S<[ B<->(B<no>)B<antialias> ]>
-S<[ B<->(B<no>)B<transparent> ]>
-S<[ B<->(B<no>)B<white> ]>
-S<[ B<->(B<no>)B<discard> ]>
-S<[ B<-image_type> I<type> ]>
-S<[ B<->(B<no>)B<images> ]>
-S<[ B<-accent_images> I<type> | B<-noaccent_images> ]>
-S<[ B<-style> I<style> ]>
-S<[ B<->(B<no>)B<parbox_images> ]>
-S<[ B<->(B<no>)B<math> ]>
-S<[ B<->(B<no>)B<math_parsing> ]>
-S<[ B<->(B<no>)B<latin> ]>
-S<[ B<->(B<no>)B<entities> ]>
-S<[ B<->(B<no>)B<local_icons> ]>
-S<[ B<->(B<no>)B<scalable_fonts> ]>
-S<[ B<->(B<no>)B<images_only> ]>
-S<[ B<->(B<no>)B<show_section_numbers> ]>
-S<[ B<->(B<no>)B<show_init> ]>
-S<[ B<-init_file> I<Perl_file> ]>
-S<[ B<-up_url> I<up_URL> ]>
-S<[ B<-up_title> I<up_title> ]>
-S<[ B<-down_url> I<down_URL> ]>
-S<[ B<-down_title> I<down_title> ]>
-S<[ B<-prev_url> I<prev_URL> ]>
-S<[ B<-prev_title> I<prev_title> ]>
-S<[ B<-index> I<index_URL> ]>
-S<[ B<-biblio> I<biblio_URL> ]>
-S<[ B<-contents> I<toc_URL> ]>
-S<[ B<-external_file> I<external_aux_file> ]>
-S<[ B<->(B<no>)B<short_index> ]>
-S<[ B<->(B<no>)B<unsegment> ]>
-S<[ B<->(B<no>)B<debug> ]>
-S<[ B<-tmp> I<path> ]>
-S<[ B<->(B<no>)B<ldump> ]>
-S<[ B<->(B<no>)B<timing> ]>
-S<[ B<-verbosity> I<num> ]>
-S<[ B<-html_version> I<num> ]>
-S<[ B<->(B<no>)B<strict> ]>
-I<file.tex> S<[ I<file2.tex> ... ]>
-
-=head1 DESCRIPTION
-
-I<LaTeX2HTML> is a Perl program that translates LaTeX source files into
-HTML. For each source file given as an argument the translator will create
-a directory containing the corresponding HTML files.
-
-=head1 OPTIONS
-
-Many options can be specified in a true/false manner. This is indicated by
-I<(no)>, e.g. to enable passing unknown environments to LaTeX, say "-latex",
-to disable the feature say "-nolatex" or "-no_latex" (portability mode).
-
-=over 4
-
-=item B<-help> | B<-h>
-
-Print this online manual and exit.
-
-=item B<-version> | B<-V>
-
-Print the LaTeX2HTML release and version information and exit.
-
-=item B<-split> I<num>
-
-Stop making separate files at this depth (say "-split 0" for one huge HTML
-file).
-
-=item B<-link> I<num>
-
-Stop showing child nodes at this depth.
-
-=item B<-toc_depth> I<num>
-
-MISSING_DESCRIPTION
-
-=item B<->(B<no>)B<toc_stars>
-
-MISSING_DESCRIPTION
-
-=item B<->(B<no>)B<short_extn>
-
-If this is set all HTML file will have extension C<.htm> instead of
-C<.html>. This is helpful when shipping the document to PC systems.
-
-=item B<-iso_language> I<lang>
-
-MISSING_DESCRIPTION
-
-=item B<->(B<no>)B<validate>
-
-When this is set true, the HTML validator specified in F<l2hconf.pm>
-will run.
-
-=item B<->(B<no>)B<latex>
-
-Pass unknown environments to LaTeX. This is the default.
-
-=item B<->(B<no>)B<djgpp>
-
-Specify this switch if you are running DJGPP on DOS and need to avoid
-running out of filehandles.
-
-=item B<->(B<no>)B<fork>
-
-Enable/disable forking. The default is reasonable for this platform.
-
-=item B<->(B<no>)B<external_images>
-
-If set, leave the images outside the document.
-
-=item B<->(B<no>)B<ascii_mode>
-
-This is different from B<-noimages>.
-If this is set, B<LaTeX2HTML> will show textual tags rather than
-images, both in navigation panel and text (Eg. C<[Up]> instead the up
-icon).
-You could use this feature to create simple text from your
-document, eg. with 'Save as... Text' from B<Netscape> or with
-B<lynx -dump>.
-
-=item B<->(B<no>)B<lcase_tags>
-
-writes out HTML tag names using lowercase letters, rather than uppercase.
-
-=item B<->(B<no>)B<ps_images>
-
-If set, use links to external postscript images rather than inlined bitmaps.
-
-=item B<-font_size> I<size>
-
-To set the point size of LaTeX-generated GIF files, specify the desired
-value (i.e., C<10pt>, C<11pt>, C<12pt>, etc.).
-The default is to use the point size of the original LaTeX document.
-This value will be magnified by I<$FIGURE_SCALE_FACTOR> and
-I<$MATH_SCALE_FACTOR> defined in F<l2hconf.pm>.
-
-=item B<->(B<no>)B<tex_defs>
-
-Enable interpretation of raw TeX commands (default).
-Note: There are many variations of C<\def> that B<LaTeX2HTML> cannot process
-correctly!
-
-=item B<->(B<no>)B<navigation>
-
-Put a navigation panel at the top of each page (default).
-
-=item B<->(B<no>)B<top_navigation>
-
-Enables navigation links at the top of each page (default).
-
-=item B<->(B<no>)B<buttom_navigation>
-
-Enables navigation links at the buttom of each page.
-
-=item B<->(B<no>)B<auto_navigation>
-
-Put navigation links at the top of each page. If the page exceeds
-I<$WORDS_IN_PAGE> number of words then put one at the bottom of the page.
-
-=item B<->(B<no>)B<index_in_navigation>
-
-Put a link to the index page in the navigation panel.
-
-=item B<->(B<no>)B<contents_in_navigation>
-
-Put a link to the table of contents in the navigation panel.
-
-=item B<->(B<no>)B<next_page_in_navigation>
-
-Put a link to the next logical page in the navigation panel.
-
-=item B<->(B<no>)B<previous_page_in_navigation>
-
-Put a link to the previous logical page in the navigation panel.
-
-=item B<->(B<no>)B<footnode>
-
-Puts all footnotes onto a separate HTML page, called F<footnode.html>,
-rather than at the bottom of the page where they are referenced.
-
-=item B<->(B<no>)B<numbered_footnotes>
-
-If true, you will get every footnote applied with a subsequent number, else
-with a generic hyperlink icon.
-
-=item B<-prefix> I<output_filename_prefix>
-
-Set the output file prefix, prepended to all C<.html>, C<.gif> and C<.pl>
-files. See also B<-auto_prefix>.
-
-=item B<->(B<no>)B<auto_prefix>
-
-Set this to automatically insert the equivalent of B<-prefix >C<basename->",
-where "basename" is the base name of the file being translated.
-
-=item B<-long_titles> I<num>
-
-MISSING_DESCRIPTION
-
-=item B<->(B<no>)B<custom_titles>
-
-MISSING_DESCRIPTION
-
-=item B<-title>|B<-t> I<top_page_title>
-
-The title (displayed in the browser's title bar) the document shall get.
-
-=item B<->(B<no>)B<rooted>
-
-MISSING_DESCRIPTION
-
-=item B<-rootdir> I<output_directory>
-
-MISSING_DESCRIPTION
-
-=item B<-dir> I<output_directory>
-
-Put the result in this directory instead of parallel to the LaTeX file,
-provided the directory exists, or B<-mkdir> is specified.
-
-=item B<-mkdir>
-
-Allow directory specified with B<-dir> to be created if necessary.
-
-=item B<-address> I<author_address> | B<-noaddress>
-
-Supply your own string if you don't like the default 
-"E<lt>NameE<gt> E<lt>DateE<gt>". B<-noaddress> suppresses the
-generation of an address footer.
-
-=item B<->(B<no>)B<subdir>
-
-If set (default), B<LaTeX2HTML> creates (or reuses) another file directory.
-When false, the generated HTML files will be placed in the current
-directory.
-
-=item B<-info> I<0> | I<1> | I<string>
-
-=item B<-noinfo>
-
-If 0 is specified (or B<-noinfo> is used), do not generate an I<"About this
-document..."> section. If 1 is specified (default), the standard info page is
-generated. If a custom string is given, it is used as the info page.
-
-=item B<->(B<no>)B<auto_link>
-
-MISSING_DESCRIPTION
-
-=item B<-reuse> I<num> | B<-noreuse>
-
-If false, do not reuse or recycle identical images generated in previous
-runs. If the html subdirectory already exists, start the interactive session.
-If I<num> is nonzero, do recycle them and switch off the interactive session.
-If 1, only recycle images generated from previous runs.
-If 2, recycle images from the current and previous runs (default).
-
-=item B<->(B<no>)B<antialias_text>
-
-Use anti-aliasing in the generation of images of typeset material;
-e.g. mathematics and text, e.g. in tables and {makeimage} environments.
-
-=item B<->(B<no>)B<antialias>
-
-Use anti-aliasing in the generation of images of figures. This usually
-results in "sharper" bitmap images.
-
-=item B<->(B<no>)B<transparent>
-
-If this is set to false then any inlined images generated from "figure" 
-environments will NOT be transparent.
-
-=item B<->(B<no>)B<white>
-
-This sets the background of generated images to white for anti-aliasing.
-
-=item B<->(B<no>)B<discard>
-
-if true, the PostScript file created for each generated image
-is discarded immediately after its image has been rendered and saved in the
-required graphics format. This can lead to significant savings in disk-space,
-when there are a lot of images, since otherwise these files are not discarded 
-until the end of all processing.
-
-=item B<-image_type> I<type>
-
-Specify the type of bitmap images to be generated. Depending on your setup,
-B<LaTeX2HTML> can generate B<gif> or B<png> images. Note: Gif images have
-certain legal restrictions, as their generation involves an algorithm
-patented by Unisys.
-
-=item B<->(B<no>)B<images>
-
-If false, B<LaTeX2HTML> will not attempt to produce any inlined images.
-The missing images can be generated "off-line" by restarting B<LaTeX2HTML>
-with B<-images_only>.
-
-=item B<-accent_images> I<type> | B<-noaccent_images>
-
-MISSING_DESCRIPTION
-
-=item B<-style> I<style>
-
-MISSING_DESCRIPTION
-
-=item B<->(B<no>)B<parbox_images>
-
-MISSING_DESCRIPTION
-
-=item B<->(B<no>)B<math>
-
-By default the special MATH extensions are not used
-since they do not conform with the HTML 3.2 standard.
-
-=item B<->(B<no>)B<math_parsing>
-
-MISSING_DESCRIPTION
-
-=item B<->(B<no>)B<latin>
-
-MISSING_DESCRIPTION
-
-=item B<->(B<no>)B<entities>
-
-MISSING_DESCRIPTION
-
-=item B<->(B<no>)B<local_icons>
-
-Set this if you want to copy the navigation icons to each document directory
-so that the document directory is self-contained and can be dropped into
-another server tree without further actions.
-
-=item B<->(B<no>)B<scalable_fonts>
-
-MISSING_DESCRIPTION
-
-=item B<->(B<no>)B<images_only>
-
-When true, B<LaTeX2HTML> will only try to convert the inlined images in the
-file F<images.tex> which should have been generated automatically during
-previous runs. This is very useful for correcting "bad LaTeX" in this file.
-
-=item B<->(B<no>)B<show_section_numbers>
-
-When this is set true, the section numbers are shown. The section numbers
-should then match those that would have been produced by LaTeX.
-The correct section numbers are obtained from the $FILE.aux file generated 
-by LaTeX.
-Hiding the section numbers encourages use of particular sections 
-as standalone documents. In this case the cross reference to a section 
-is shown using the default symbol rather than the section number.
-
-=item B<->(B<no>)B<show_init>
-
-MISSING_DESCRIPTION
-
-=item B<-init_file> I<Perl_file>
-
-MISSING_DESCRIPTION
-
-=item B<-up_url> I<up_URL>, B<-up_title> I<up_title>
-
-=item B<-down_url> I<down_URL>, B<-down_title> I<down_title>
-
-=item B<-prev_url> I<prev_URL>, B<-prev_title> I<prev_title>
-
-=item B<-index> I<index_URL>,
-
-=item B<-contents> I<toc_URL>
-
-=item B<-biblio> I<biblio_URL>
-
-If both of the listed two options are set then the "Up" ("Previous" etc.)
-button of the navigation panel in the first node/page of a converted
-document will point to I<up_URL> etc. I<up_title> should be set
-to some text which describes this external link.
-Similarly you might use these options to link external documents
-to your navigation panel.
-
-=item B<-external_file> I<external_aux_file>
-
-MISSING_DESCRIPTION
-
-=item B<->(B<no>)B<short_index>
-
-If this is set then B<makeidx.perl> will construct codified names
-for the text of index references.
-
-=item B<->(B<no>)B<unsegment>
-
-Use this to translate a segmented document as if it were not
-segmented.
-
-=item B<->(B<no>)B<debug>
-
-If this is set then intermediate files are left for later inspection and
-a lot of diagnostic output is produced. This output may be useful when
-searching for problems and/or submitting bug reports to the developers.
-Temporary files include F<$$_images.tex> and F<$$_images.log> created during
-image conversion. Caution: Intermediate files can be I<enormous>!
-
-=item B<-tmp> I<path>
-
-Path for temporary files. This should be a local, fast filesystem because it is heavily used during image generation. The default is set in F<l2hconf.pm>.
-
-=item B<->(B<no>)B<ldump>
-
-This will cause LaTeX2HTML to produce a LaTeX dump of images.tex which is read
-in on subsequent runs and speeds up startup time of LaTeX on the images.tex
-translation. This actually consumes additional time on the first run, but pays
-off on subsequent runs. The dump file will need about 1 Meg of disk space.
-
-=item B<->(B<no>)B<timing>
-
-MISSING_DESCRIPTION
-
-=item B<-verbosity> I<num>
-
-The amount of message information printed to the screen during processing
-by B<LaTeX2HTML> is controlled by this setting.
-By increasing this value, more information is displayed.
-Here is the type of extra information that is shown at each level:
-
-  0   no extra information
-  1   section types and titles
-  2   environment
-  3   command names
-  4   links, labels and internal sectioning codes
-
-=item B<-html_version> I<list>
-
-Which HTML version should be generated. Currently available are:
-C<2.0>, C<3.0>, C<3.2>, C<4.0>. Some additional options that may be
-added are: C<math> (parse mathematics), C<i18n> (?), 
-C<table> (generate tables), C<frame> (generate frames),
-C<latin1>...C<latin9> (use ISO-Latin-x encoding),
-C<unicode> (generate unicode characters). Separate the options with ',',
-e.g. C<4.0,math,frame>.
-
-=item B<->(B<no>)B<strict>
-
-MISSING_DESCRIPTION
-
-=back
-
-=head1 FILES
-
-=over 4
-
-=item F<$LATEX2HTMLPLATDIR/l2hconf.pm>
-
-This file holds the global defaults and configuration settings for
-B<LaTeX2HTML>.
-
-=item F<$HOME/.latex2html-init>
-
-=item F<./.latex2html-init>
-
-These files may contain settings that override the global defaults, just
-like specifying command line switches.
-
-=back
-
-=head1 ENVIRONMENT
-
-=over 4
-
-=item LATEX2HTMLDIR
-
-Path where LaTeX2HTML library files are found. On this installation
-LATEX2HTMLDIR is F</usr/share/latex2html>
-
-=item PERL5LIB
-
-Set by the B<latex2html> program to find perl modules.
-
-=item L2HCONFIG
-
-An alternative configuration filename. The standard configuration file
-is F<$LATEX2HTMLPLATDIR/l2hconf.pm>. You may specify a sole filename (searched
-for in F<$LATEX2HTMLPLATDIR> (and F<$PERL5LIB>) or a complete path.
-
-=item L2HINIT_NAME
-
-The standard user-specific configuration filename is F<.latex2html-init>.
-This environment variable will override this name.
-
-=item HOME
-
-Evaluated if the system does not know about "home" directories (like
-DOS, WinXX, OS/2, ...) to determine the path to F<$L2HINIT_NAME>.
-
-=item TEXE_DONT_INCLUDE, TEXE_DO_INCLUDE
-
-Used internally for communication with B<texexpand>.
-
-=item TEXINPUTS
-
-Used to find TeX includes of all sorts.
-
-=back
-
-=head1 PROBLEMS
-
-For information on various problems and remedies see the WWW online
-documentation or the documents available in the distribution.
-An online bug reporting form and various archives are available at
-F<http://www.latex2html.org/>
-
-There is a mailing list for discussing B<LaTeX2HTML>: C<latex2html@tug.org>
-
-=head1 AUTHOR
-
-Nikos Drakos,  Computer Based Learning Unit, University of Leeds
-E<lt>nikos@cbl.leeds.ac.ukE<gt>. Several people have contributed
-suggestions, ideas, solutions, support and encouragement.
-
-The B<pstoimg> script was written by Marek Rouchal 
-E<lt>marek@saftsack.fs.uni-bayreuth.deE<gt>
-as a generalisation of the B<pstogif> utility to allow graphic formats
-other than GIF to be created. Various options and enhancements have
-been added by Ross Moore.
-Some of the code is based upon the pstoppm.ps postscript program 
-originally written by Phillip Conrad (Perfect Byte, Inc.)
-and modified by L. Peter Deutsch (Aladdin Enterprises).
-
-=head1 SEE ALSO
-
-See the WWW online documentation or the F<$LATEX2HTMLDIR/doc/manual.ps>
-file for more detailed information and examples.
-
-L<pstoing>, L<texexpand>
-
-=cut
-
diff --git a/contrib/mysql/README b/contrib/mysql/README
deleted file mode 100644 (file)
index f511910..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-
-in those directories you will find the database definitions for the plugins
-gofax gofon glog with mysql.
-
-Benoit Mortier <benoit.mortier@opensides.be>
-
diff --git a/contrib/mysql/glpi/glpi.sql b/contrib/mysql/glpi/glpi.sql
deleted file mode 100644 (file)
index a18e3b7..0000000
+++ /dev/null
@@ -1,1627 +0,0 @@
-create database glpi;
-use glpi;
-
-CREATE TABLE `glpi_cartridges` (
-  `ID` int(11) NOT NULL auto_increment,
-  `FK_glpi_cartridges_type` int(11) NOT NULL default '0',
-  `FK_glpi_printers` int(11) NOT NULL default '0',
-  `date_in` date default NULL,
-  `date_use` date default NULL,
-  `date_out` date default NULL,
-  `pages` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_cartridges_type` (`FK_glpi_cartridges_type`),
-  KEY `FK_glpi_printers` (`FK_glpi_printers`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
-
-INSERT INTO `glpi_cartridges` (`ID`, `FK_glpi_cartridges_type`, `FK_glpi_printers`, `date_in`, `date_use`, `date_out`, `pages`) VALUES 
-(5, 5, 5, '2006-09-29', '2006-09-29', NULL, 0),
-(4, 5, 5, '2006-09-29', '2006-09-29', NULL, 0);
-
-
-CREATE TABLE `glpi_cartridges_assoc` (
-  `ID` int(11) NOT NULL auto_increment,
-  `FK_glpi_cartridges_type` int(11) NOT NULL default '0',
-  `FK_glpi_type_printer` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `FK_glpi_type_printer` (`FK_glpi_type_printer`,`FK_glpi_cartridges_type`),
-  KEY `FK_glpi_cartridges_type` (`FK_glpi_cartridges_type`),
-  KEY `FK_glpi_type_printer_2` (`FK_glpi_type_printer`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;
-
-
-INSERT INTO `glpi_cartridges_assoc` (`ID`, `FK_glpi_cartridges_type`, `FK_glpi_type_printer`) VALUES 
-(1, 1, 1),
-(2, 2, 5),
-(3, 2, 1),
-(4, 3, 13),
-(5, 4, 13),
-(6, 5, 11),
-(7, 5, 10),
-(8, 5, 5),
-(9, 5, 12),
-(10, 5, 2),
-(11, 5, 14),
-(12, 5, 3);
-
-
-
-CREATE TABLE `glpi_cartridges_type` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  `ref` varchar(255) NOT NULL default '',
-  `location` int(11) NOT NULL default '0',
-  `type` tinyint(4) NOT NULL default '0',
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `tech_num` int(11) default '0',
-  `deleted` enum('Y','N') NOT NULL default 'N',
-  `comments` text NOT NULL,
-  `alarm` tinyint(4) NOT NULL default '10',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
-  KEY `tech_num` (`tech_num`),
-  KEY `deleted` (`deleted`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
-
-
-INSERT INTO `glpi_cartridges_type` (`ID`, `name`, `ref`, `location`, `type`, `FK_glpi_enterprise`, `tech_num`, `deleted`, `comments`, `alarm`) VALUES 
-(1, 'TestPatrone', '', 0, 1, 8, 0, '', '', 0),
-(2, 'HP_deskjet_7100C', '', 0, 4, 8, 0, '', 'None', 0),
-(3, 'teseter', '', 0, 3, 12, 0, '', '', 0),
-(4, 'teseter2', '', 0, 3, 12, 0, '', '', 0),
-(5, 'Epson Stylus Nuclear Color', '', 0, 3, 12, 0, '', 'Uranium green.\r\n', 0);
-
-
-
-CREATE TABLE `glpi_computer_device` (
-  `ID` int(11) NOT NULL auto_increment,
-  `specificity` varchar(250) NOT NULL default '',
-  `device_type` tinyint(4) NOT NULL default '0',
-  `FK_device` int(11) NOT NULL default '0',
-  `FK_computers` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  KEY `device_type` (`device_type`),
-  KEY `device_type_2` (`device_type`,`FK_device`),
-  KEY `FK_computers` (`FK_computers`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=136 ;
-
-
-INSERT INTO `glpi_computer_device` (`ID`, `specificity`, `device_type`, `FK_device`, `FK_computers`) VALUES 
-(87, '', 1, 1, 1),
-(92, '', 1, 1, 13),
-(133, '', 1, 1, 17),
-(120, '', 1, 1, 23),
-(122, '', 1, 1, 24),
-(135, '', 1, 1, 19),
-(132, '', 1, 1, 29);
-
-
-
-CREATE TABLE `glpi_computers` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(200) NOT NULL default '',
-  `serial` varchar(200) NOT NULL default '',
-  `otherserial` varchar(200) NOT NULL default '',
-  `contact` varchar(90) NOT NULL default '',
-  `contact_num` varchar(90) NOT NULL default '',
-  `tech_num` int(11) NOT NULL default '0',
-  `comments` text NOT NULL,
-  `date_mod` datetime default NULL,
-  `os` int(11) default NULL,
-  `location` int(11) default NULL,
-  `domain` int(11) NOT NULL default '0',
-  `network` int(11) NOT NULL default '0',
-  `model` int(11) default NULL,
-  `type` int(11) default NULL,
-  `is_template` enum('0','1') NOT NULL default '0',
-  `tplname` varchar(200) default NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `deleted` enum('Y','N') NOT NULL default 'N',
-  PRIMARY KEY  (`ID`),
-  KEY `location` (`location`),
-  KEY `os` (`os`),
-  KEY `type` (`model`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
-  KEY `deleted` (`deleted`),
-  KEY `is_template` (`is_template`),
-  KEY `date_mod` (`date_mod`),
-  KEY `tech_num` (`tech_num`),
-  KEY `type_2` (`type`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=41 ;
-
-
-INSERT INTO `glpi_computers` (`ID`, `name`, `serial`, `otherserial`, `contact`, `contact_num`, `tech_num`, `comments`, `date_mod`, `os`, `location`, `domain`, `network`, `model`, `type`, `is_template`, `tplname`, `FK_glpi_enterprise`, `deleted`) VALUES 
-(1, 'cn=asterisk,ou=servers,ou=systems,dc=gonicus,dc=de', '', '', '', '1', 1, '', '2006-03-08 12:12:04', 5, 0, 0, 0, 0, 27, '0', NULL, 8, 'N'),
-(4, 'cn=pyramid,ou=terminals,ou=systems,dc=gonicus,dc=de', '', '', '', '', 0, '', '2006-03-08 07:05:07', 5, 0, 0, 0, 0, 21, '0', NULL, 8, 'N'),
-(5, 'cn=ctu03,ou=phones,ou=systems,dc=gonicus,dc=de', '', '', '', '', 0, '', '2006-02-10 08:58:15', 6, 0, 0, 0, 0, 21, '0', NULL, 8, 'N'),
-(6, 'cn=fax,ou=servers,ou=systems,dc=gonicus,dc=de', '', '', '', '', 3, '', '2006-03-01 10:04:06', 6, 0, 0, 0, 0, 21, '0', NULL, 12, 'N'),
-(19, 'cn=cl1--6665,ou=workstations,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '18', 0, '', '2007-01-30 08:03:00', 5, 0, 0, 0, 0, 27, '0', NULL, 16, 'N'),
-(11, 'cn=vserver-04f,ou=servers,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '', 0, '', '2006-05-12 07:51:32', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
-(13, 'cn=GetraenkeHalter,ou=netdevices,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '6', 7, 'tester', '2006-06-21 12:34:54', 7, 0, 0, 0, 0, 28, '0', NULL, 16, 'N'),
-(18, 'cn=cl1--151,ou=workstations,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'tester', '2007-01-30 07:55:33', 18, 0, 0, 0, 0, 18, '0', NULL, 16, 'N'),
-(16, 'cn=ctu153,ou=phones,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '8', 9, 'Tester für den Comment \\\\\\n<br>\r\ntester', '2006-06-20 09:24:35', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
-(17, 'cn=cl1--157,ou=workstations,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'asdfasdf \n\r\nasdf', '2007-01-30 07:01:41', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
-(20, 'cn=vserver-01.intranet.gonicus.de,ou=servers,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'sda', '2007-05-21 06:53:29', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
-(21, 'cn=vserver-01.intranet.gonicus.de,ou=servers,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'sda', '2007-05-21 06:53:29', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
-(23, 'cn=kohlenhydrate,ou=servers,ou=systems,ou=keks,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '11', 11, 'eg', '2006-09-29 09:37:30', 7, 0, 0, 0, 0, 26, '0', NULL, 8, 'N'),
-(24, 'cn=Mineralstoffe,ou=workstations,ou=systems,ou=keks,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'dfsaaaaaaaaaaaaaaaaaaaaaaaaaaa', '2006-10-18 11:21:03', 7, 0, 0, 0, 0, 27, '0', NULL, 16, 'N'),
-(25, 'cn=Ammoniumcarbonat,ou=phones,ou=systems,ou=keks,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '11', 11, 'asdf', '2006-09-29 10:34:32', 7, 0, 0, 0, 0, 21, '0', NULL, 16, 'N'),
-(26, 'cn=Kakaomasse,ou=netdevices,ou=systems,ou=keks,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '11', 11, 'ikk', '2006-09-29 10:41:12', 7, 0, 0, 0, 0, 27, '0', NULL, 8, 'N'),
-(27, 'cn=afs-22,ou=servers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '', 0, '-ö', '2006-11-30 13:31:50', 7, 0, 0, 0, 0, 26, '0', NULL, 16, 'N'),
-(28, 'cn=Netzwerkkomponente,ou=netdevices,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '11', 0, '', '2006-11-29 14:43:00', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
-(29, 'cn=vserver-04.intranet.gonicus.de,ou=servers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'asdfasdf', '2006-11-30 12:48:22', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
-(30, 'cn=okulele,ou=servers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '21', 21, 'No comment', '2007-01-23 14:20:48', 11, 0, 0, 0, 0, 21, '0', NULL, 16, 'N'),
-(31, 'cn=keksesindlecker45,ou=workstations,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'sdfsdfaasdf', '2007-01-16 08:26:35', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
-(32, 'cn=phoneTesterAparatz,ou=phones,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '', 0, '', '2007-01-15 08:21:39', 5, 0, 0, 0, 0, 18, '0', NULL, 12, 'N'),
-(39, 'cn=terminal,ou=terminals,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '', 0, '', '2007-05-21 07:02:42', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N');
-
-
-
-CREATE TABLE `glpi_config` (
-  `ID` int(11) NOT NULL auto_increment,
-  `ldap_port` varchar(10) NOT NULL default '389',
-  `num_of_events` varchar(200) NOT NULL default '',
-  `jobs_at_login` varchar(200) NOT NULL default '',
-  `sendexpire` varchar(200) NOT NULL default '',
-  `cut` varchar(200) NOT NULL default '',
-  `expire_events` varchar(200) NOT NULL default '',
-  `list_limit` varchar(200) NOT NULL default '',
-  `version` varchar(200) NOT NULL default '',
-  `logotxt` varchar(200) NOT NULL default '',
-  `root_doc` varchar(200) NOT NULL default '',
-  `event_loglevel` varchar(200) NOT NULL default '',
-  `mailing` varchar(200) NOT NULL default '',
-  `imap_auth_server` varchar(200) NOT NULL default '',
-  `imap_host` varchar(200) NOT NULL default '',
-  `ldap_host` varchar(200) NOT NULL default '',
-  `ldap_basedn` varchar(200) NOT NULL default '',
-  `ldap_rootdn` varchar(200) NOT NULL default '',
-  `ldap_pass` varchar(200) NOT NULL default '',
-  `admin_email` varchar(200) NOT NULL default '',
-  `mailing_resa_all_admin` varchar(200) NOT NULL default '0',
-  `mailing_resa_user` varchar(200) NOT NULL default '1',
-  `mailing_resa_admin` varchar(200) NOT NULL default '1',
-  `mailing_signature` varchar(200) NOT NULL default '',
-  `mailing_new_admin` varchar(200) NOT NULL default '',
-  `mailing_followup_admin` varchar(200) NOT NULL default '',
-  `mailing_finish_admin` varchar(200) NOT NULL default '',
-  `mailing_new_all_admin` varchar(200) NOT NULL default '',
-  `mailing_followup_all_admin` varchar(200) NOT NULL default '',
-  `mailing_finish_all_admin` varchar(200) NOT NULL default '',
-  `mailing_new_all_normal` varchar(200) NOT NULL default '',
-  `mailing_followup_all_normal` varchar(200) NOT NULL default '',
-  `mailing_finish_all_normal` varchar(200) NOT NULL default '',
-  `mailing_new_attrib` varchar(200) NOT NULL default '',
-  `mailing_followup_attrib` varchar(200) NOT NULL default '',
-  `mailing_finish_attrib` varchar(200) NOT NULL default '',
-  `mailing_new_user` varchar(200) NOT NULL default '',
-  `mailing_followup_user` varchar(200) NOT NULL default '',
-  `mailing_finish_user` varchar(200) NOT NULL default '',
-  `ldap_field_name` varchar(200) NOT NULL default '',
-  `ldap_field_email` varchar(200) NOT NULL default '',
-  `ldap_field_location` varchar(200) NOT NULL default '',
-  `ldap_field_realname` varchar(200) NOT NULL default '',
-  `ldap_field_phone` varchar(200) NOT NULL default '',
-  `ldap_condition` varchar(255) NOT NULL default '',
-  `permit_helpdesk` varchar(200) NOT NULL default '',
-  `default_language` varchar(255) NOT NULL default 'french',
-  `priority_1` varchar(200) NOT NULL default '#fff2f2',
-  `priority_2` varchar(200) NOT NULL default '#ffe0e0',
-  `priority_3` varchar(200) NOT NULL default '#ffcece',
-  `priority_4` varchar(200) NOT NULL default '#ffbfbf',
-  `priority_5` varchar(200) NOT NULL default '#ffadad',
-  `date_fiscale` date NOT NULL default '2005-12-31',
-  `cartridges_alarm` int(11) NOT NULL default '10',
-  `cas_host` varchar(255) NOT NULL default '',
-  `cas_port` varchar(255) NOT NULL default '',
-  `cas_uri` varchar(255) NOT NULL default '',
-  `planning_begin` time NOT NULL default '08:00:00',
-  `planning_end` time NOT NULL default '20:00:00',
-  `utf8_conv` int(11) NOT NULL default '0',
-  `auto_assign` enum('0','1') NOT NULL default '0',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
-
-
-INSERT INTO `glpi_config` (`ID`, `ldap_port`, `num_of_events`, `jobs_at_login`, `sendexpire`, `cut`, `expire_events`, `list_limit`, `version`, `logotxt`, `root_doc`, `event_loglevel`, `mailing`, `imap_auth_server`, `imap_host`, `ldap_host`, `ldap_basedn`, `ldap_rootdn`, `ldap_pass`, `admin_email`, `mailing_resa_all_admin`, `mailing_resa_user`, `mailing_resa_admin`, `mailing_signature`, `mailing_new_admin`, `mailing_followup_admin`, `mailing_finish_admin`, `mailing_new_all_admin`, `mailing_followup_all_admin`, `mailing_finish_all_admin`, `mailing_new_all_normal`, `mailing_followup_all_normal`, `mailing_finish_all_normal`, `mailing_new_attrib`, `mailing_followup_attrib`, `mailing_finish_attrib`, `mailing_new_user`, `mailing_followup_user`, `mailing_finish_user`, `ldap_field_name`, `ldap_field_email`, `ldap_field_location`, `ldap_field_realname`, `ldap_field_phone`, `ldap_condition`, `permit_helpdesk`, `default_language`, `priority_1`, `priority_2`, `priority_3`, `priority_4`, `priority_5`, `date_fiscale`, `cartridges_alarm`, `cas_host`, `cas_port`, `cas_uri`, `planning_begin`, `planning_end`, `utf8_conv`, `auto_assign`) VALUES 
-(1, '389', '10', '1', '1', '80', '30', '15', ' 0.6', 'GLPI powered by indepnet', '/glpi', '5', '0', '', '', '', '', '', '', 'admsys@xxxxx.fr', '0', '1', '1', 'SIGNATURE', '1', '1', '1', '1', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', 'uid', 'mail', 'physicaldeliveryofficename', 'cn', 'telephonenumber', '', '', 'english', '#fff2f2', '#ffe0e0', '#ffcece', '#ffbfbf', '#ffadad', '2005-12-31', 10, '', '', '', '08:00:00', '20:00:00', 0, '0');
-
-
-
-CREATE TABLE `glpi_connect_wire` (
-  `ID` int(11) NOT NULL auto_increment,
-  `end1` int(11) NOT NULL default '0',
-  `end2` int(11) NOT NULL default '0',
-  `type` tinyint(4) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `end1_1` (`end1`,`end2`,`type`),
-  KEY `end1` (`end1`),
-  KEY `end2` (`end2`),
-  KEY `type` (`type`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=10 ;
-
-
-INSERT INTO `glpi_connect_wire` (`ID`, `end1`, `end2`, `type`) VALUES 
-(1, 1, 1, 4),
-(5, 2, 17, 4),
-(4, 2, 13, 4),
-(7, 2, 23, 4),
-(8, 2, 24, 4),
-(9, 2, 29, 4);
-
-
-
-CREATE TABLE `glpi_consumables` (
-  `ID` int(11) NOT NULL auto_increment,
-  `FK_glpi_consumables_type` int(11) default NULL,
-  `date_in` date default NULL,
-  `date_out` date default NULL,
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_cartridges_type` (`FK_glpi_consumables_type`),
-  KEY `date_in` (`date_in`),
-  KEY `date_out` (`date_out`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_consumables_type` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  `ref` varchar(255) NOT NULL default '',
-  `location` int(11) NOT NULL default '0',
-  `type` tinyint(4) NOT NULL default '0',
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `tech_num` int(11) default '0',
-  `deleted` enum('Y','N') NOT NULL default 'N',
-  `comments` text NOT NULL,
-  `alarm` tinyint(4) NOT NULL default '10',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
-  KEY `tech_num` (`tech_num`),
-  KEY `deleted` (`deleted`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_contact_enterprise` (
-  `ID` int(11) NOT NULL auto_increment,
-  `FK_enterprise` int(11) NOT NULL default '0',
-  `FK_contact` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `FK_enterprise` (`FK_enterprise`,`FK_contact`),
-  KEY `FK_enterprise_2` (`FK_enterprise`),
-  KEY `FK_contact` (`FK_contact`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_contacts` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  `phone` varchar(30) NOT NULL default '',
-  `phone2` varchar(30) NOT NULL default '',
-  `fax` varchar(30) NOT NULL default '',
-  `email` varchar(255) NOT NULL default '',
-  `type` tinyint(4) NOT NULL default '1',
-  `comments` text NOT NULL,
-  `deleted` enum('Y','N') NOT NULL default 'N',
-  PRIMARY KEY  (`ID`),
-  KEY `deleted` (`deleted`),
-  KEY `type` (`type`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_contract_device` (
-  `ID` int(11) NOT NULL auto_increment,
-  `FK_contract` int(11) NOT NULL default '0',
-  `FK_device` int(11) NOT NULL default '0',
-  `device_type` tinyint(4) NOT NULL default '0',
-  `is_template` enum('0','1') NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `FK_contract` (`FK_contract`,`FK_device`,`device_type`),
-  KEY `FK_contract_2` (`FK_contract`),
-  KEY `FK_device` (`FK_device`,`device_type`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_contract_enterprise` (
-  `ID` int(11) NOT NULL auto_increment,
-  `FK_enterprise` int(11) NOT NULL default '0',
-  `FK_contract` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `FK_enterprise` (`FK_enterprise`,`FK_contract`),
-  KEY `FK_enterprise_2` (`FK_enterprise`),
-  KEY `FK_contract` (`FK_contract`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_contracts` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  `num` varchar(255) NOT NULL default '',
-  `cost` float NOT NULL default '0',
-  `contract_type` int(11) NOT NULL default '0',
-  `begin_date` date default NULL,
-  `duration` tinyint(4) NOT NULL default '0',
-  `notice` tinyint(4) NOT NULL default '0',
-  `periodicity` tinyint(4) NOT NULL default '0',
-  `facturation` tinyint(4) NOT NULL default '0',
-  `bill_type` int(11) NOT NULL default '0',
-  `comments` text NOT NULL,
-  `compta_num` varchar(255) NOT NULL default '',
-  `deleted` enum('Y','N') NOT NULL default 'N',
-  `week_begin_hour` time NOT NULL default '00:00:00',
-  `week_end_hour` time NOT NULL default '00:00:00',
-  `saturday_begin_hour` time NOT NULL default '00:00:00',
-  `saturday_end_hour` time NOT NULL default '00:00:00',
-  `saturday` enum('Y','N') NOT NULL default 'N',
-  `monday_begin_hour` time NOT NULL default '00:00:00',
-  `monday_end_hour` time NOT NULL default '00:00:00',
-  `monday` enum('Y','N') NOT NULL default 'N',
-  `device_countmax` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  KEY `contract_type` (`contract_type`),
-  KEY `begin_date` (`begin_date`),
-  KEY `bill_type` (`bill_type`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_device_case` (
-  `ID` int(11) NOT NULL auto_increment,
-  `designation` varchar(255) NOT NULL default '',
-  `format` enum('Grand','Moyen','Micro') NOT NULL default 'Moyen',
-  `comment` text NOT NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `specif_default` varchar(250) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
-
-
-
-
-
-CREATE TABLE `glpi_device_control` (
-  `ID` int(11) NOT NULL auto_increment,
-  `designation` varchar(255) NOT NULL default '',
-  `interface` enum('IDE','SATA','SCSI','USB') NOT NULL default 'IDE',
-  `raid` enum('Y','N') NOT NULL default 'Y',
-  `comment` text NOT NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `specif_default` varchar(250) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
-
-
-
-
-
-CREATE TABLE `glpi_device_drive` (
-  `ID` int(11) NOT NULL auto_increment,
-  `designation` varchar(255) NOT NULL default '',
-  `is_writer` enum('Y','N') NOT NULL default 'Y',
-  `speed` varchar(30) NOT NULL default '',
-  `interface` enum('IDE','SATA','SCSI') NOT NULL default 'IDE',
-  `comment` text NOT NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `specif_default` varchar(250) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
-
-
-
-
-
-CREATE TABLE `glpi_device_gfxcard` (
-  `ID` int(11) NOT NULL auto_increment,
-  `designation` varchar(120) NOT NULL default '',
-  `ram` varchar(10) NOT NULL default '',
-  `interface` enum('AGP','PCI','PCI-X','Other') NOT NULL default 'AGP',
-  `comment` text NOT NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `specif_default` varchar(250) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
-
-
-
-
-
-CREATE TABLE `glpi_device_hdd` (
-  `ID` int(11) NOT NULL auto_increment,
-  `designation` varchar(100) NOT NULL default '',
-  `rpm` varchar(20) NOT NULL default '',
-  `interface` int(11) NOT NULL default '0',
-  `cache` varchar(20) NOT NULL default '',
-  `comment` text NOT NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `specif_default` varchar(250) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
-
-
-
-
-
-CREATE TABLE `glpi_device_iface` (
-  `ID` int(11) NOT NULL auto_increment,
-  `designation` varchar(120) NOT NULL default '',
-  `bandwidth` varchar(20) NOT NULL default '',
-  `comment` text NOT NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `specif_default` varchar(250) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
-
-
-
-
-
-CREATE TABLE `glpi_device_moboard` (
-  `ID` int(11) NOT NULL auto_increment,
-  `designation` varchar(100) NOT NULL default '',
-  `chipset` varchar(120) NOT NULL default '',
-  `comment` text NOT NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `specif_default` varchar(250) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
-
-
-INSERT INTO `glpi_device_moboard` (`ID`, `designation`, `chipset`, `comment`, `FK_glpi_enterprise`, `specif_default`) VALUES 
-(1, 'NVidia Nforce 9', 'Nforce', 'kein', 2, '');
-
-
-
-CREATE TABLE `glpi_device_pci` (
-  `ID` int(11) NOT NULL auto_increment,
-  `designation` varchar(255) NOT NULL default '',
-  `comment` text NOT NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `specif_default` varchar(250) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
-
-
-
-
-
-CREATE TABLE `glpi_device_power` (
-  `ID` int(11) NOT NULL auto_increment,
-  `designation` varchar(255) NOT NULL default '',
-  `power` varchar(20) NOT NULL default '',
-  `atx` enum('Y','N') NOT NULL default 'Y',
-  `comment` text NOT NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `specif_default` varchar(250) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
-
-
-
-
-
-CREATE TABLE `glpi_device_processor` (
-  `ID` int(11) NOT NULL auto_increment,
-  `designation` varchar(120) NOT NULL default '',
-  `frequence` int(11) NOT NULL default '0',
-  `comment` text NOT NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `specif_default` varchar(250) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
-
-
-
-
-
-CREATE TABLE `glpi_device_ram` (
-  `ID` int(11) NOT NULL auto_increment,
-  `designation` varchar(100) NOT NULL default '',
-  `frequence` varchar(8) NOT NULL default '',
-  `comment` text NOT NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `specif_default` varchar(250) NOT NULL default '',
-  `type` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
-
-
-
-
-
-CREATE TABLE `glpi_device_sndcard` (
-  `ID` int(11) NOT NULL auto_increment,
-  `designation` varchar(120) NOT NULL default '',
-  `type` varchar(100) NOT NULL default '',
-  `comment` text NOT NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `specif_default` varchar(250) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
-
-
-
-
-
-CREATE TABLE `glpi_doc_device` (
-  `ID` int(11) NOT NULL auto_increment,
-  `FK_doc` int(11) NOT NULL default '0',
-  `FK_device` int(11) NOT NULL default '0',
-  `device_type` tinyint(4) NOT NULL default '0',
-  `is_template` enum('0','1') NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `FK_doc` (`FK_doc`,`FK_device`,`device_type`),
-  KEY `FK_doc_2` (`FK_doc`),
-  KEY `FK_device` (`FK_device`,`device_type`),
-  KEY `is_template` (`is_template`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=55 ;
-
-
-INSERT INTO `glpi_doc_device` (`ID`, `FK_doc`, `FK_device`, `device_type`, `is_template`) VALUES 
-(17, 1, 1, 1, '0'),
-(8, 1, 2, 1, '0'),
-(50, 1, 1, 3, '0'),
-(51, 4, 5, 3, '0'),
-(52, 1, 7, 3, '0'),
-(53, 4, 7, 3, '0'),
-(54, 1, 8, 3, '0');
-
-
-
-CREATE TABLE `glpi_docs` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  `filename` varchar(255) NOT NULL default '',
-  `rubrique` int(11) NOT NULL default '0',
-  `mime` varchar(30) NOT NULL default '',
-  `date_mod` datetime NOT NULL default '0000-00-00 00:00:00',
-  `comment` text NOT NULL,
-  `deleted` enum('Y','N') NOT NULL default 'N',
-  `link` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `rubrique` (`rubrique`),
-  KEY `deleted` (`deleted`),
-  KEY `date_mod` (`date_mod`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
-
-
-INSERT INTO `glpi_docs` (`ID`, `name`, `filename`, `rubrique`, `mime`, `date_mod`, `comment`, `deleted`, `link`) VALUES 
-(1, 'Anleitung', 'class_mail-methods-kolab.inc', 0, 'application/octet-stream', '2006-01-25 11:23:16', 'leeer', 'N', ''),
-(4, 'Hardware handbuch', 'sieve-php.inc', 0, 'application/octet-stream', '2006-09-29 11:01:52', 'Steht alles drin.\r\n42.342 Seiten', 'N', '');
-
-
-
-CREATE TABLE `glpi_dropdown_cartridge_type` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=14 ;
-
-
-INSERT INTO `glpi_dropdown_cartridge_type` (`ID`, `name`) VALUES 
-(3, 'Color blue'),
-(4, 'Color combination RGB'),
-(6, 'Laser Cartridge Red'),
-(8, 'Laser Cartridge Green'),
-(9, 'Laser Cartridge combination RGB'),
-(10, 'Color Black'),
-(11, 'Color Black /& Rgb');
-
-
-
-CREATE TABLE `glpi_dropdown_consumable_type` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_dropdown_contact_type` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_dropdown_contract_type` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
-
-
-INSERT INTO `glpi_dropdown_contract_type` (`ID`, `name`) VALUES 
-(1, 'Pr&#234;t'),
-(2, 'Location'),
-(3, 'Leasing'),
-(4, 'Assurances'),
-(5, 'Maintenance Hardware'),
-(6, 'Maintenance Software'),
-(7, 'Prestation');
-
-
-
-CREATE TABLE `glpi_dropdown_domain` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_dropdown_enttype` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_dropdown_firmware` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_dropdown_hdd_type` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
-
-
-INSERT INTO `glpi_dropdown_hdd_type` (`ID`, `name`) VALUES 
-(1, 'IDE'),
-(2, 'SATA'),
-(3, 'SCSI');
-
-
-
-CREATE TABLE `glpi_dropdown_iface` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) default NULL,
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_dropdown_kbcategories` (
-  `ID` int(11) NOT NULL auto_increment,
-  `parentID` int(11) NOT NULL default '0',
-  `name` varchar(255) NOT NULL default '',
-  `completename` text NOT NULL,
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `parentID_2` (`parentID`,`name`),
-  KEY `parentID` (`parentID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_dropdown_locations` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  `parentID` int(11) NOT NULL default '0',
-  `completename` text NOT NULL,
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `name` (`name`,`parentID`),
-  KEY `parentID` (`parentID`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
-
-
-INSERT INTO `glpi_dropdown_locations` (`ID`, `name`, `parentID`, `completename`) VALUES 
-(1, 'lala', 0, 'chk'),
-(2, 'ldala', 1, 'chacka');
-
-
-
-CREATE TABLE `glpi_dropdown_model` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) default NULL,
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_dropdown_netpoint` (
-  `ID` int(11) NOT NULL auto_increment,
-  `location` int(11) NOT NULL default '0',
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `location` (`location`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_dropdown_network` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_dropdown_os` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) default NULL,
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=21 ;
-
-
-INSERT INTO `glpi_dropdown_os` (`ID`, `name`) VALUES 
-(5, 'Windows 3.1'),
-(6, 'Debian Sarge'),
-(7, 'Debian Woody'),
-(11, 'Windows 98 se'),
-(10, 'Debian SID'),
-(14, 'Windows Server 2003'),
-(18, 'Windows 99');
-
-
-
-CREATE TABLE `glpi_dropdown_ram_type` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
-
-
-INSERT INTO `glpi_dropdown_ram_type` (`ID`, `name`) VALUES 
-(1, 'EDO'),
-(2, 'DDR'),
-(3, 'SDRAM'),
-(4, 'SDRAM-2');
-
-
-
-CREATE TABLE `glpi_dropdown_rubdocs` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) default NULL,
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_dropdown_state` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) default NULL,
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
-
-
-INSERT INTO `glpi_dropdown_state` (`ID`, `name`) VALUES 
-(1, 'asdf'),
-(2, 'asdfasdf');
-
-
-
-CREATE TABLE `glpi_dropdown_tracking_category` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) default NULL,
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_dropdown_vlan` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_enterprises` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(50) NOT NULL default '',
-  `type` int(11) NOT NULL default '0',
-  `address` text NOT NULL,
-  `website` varchar(100) NOT NULL default '',
-  `phonenumber` varchar(20) NOT NULL default '',
-  `comments` text NOT NULL,
-  `deleted` enum('Y','N') NOT NULL default 'N',
-  `fax` varchar(255) NOT NULL default '',
-  `email` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `deleted` (`deleted`),
-  KEY `type` (`type`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=18 ;
-
-
-INSERT INTO `glpi_enterprises` (`ID`, `name`, `type`, `address`, `website`, `phonenumber`, `comments`, `deleted`, `fax`, `email`) VALUES 
-(8, 'Microsoft', 0, 'Neverlandranche', 'www.google.de', '0001', 'No comment', '', '02', '02@01.00'),
-(12, 'Cherry', 0, '3 Tasten höher als ''n''   4 te links.', 'http://cherry_oder_so_aehnlich.com', 'N/A', 'N/A', '', 'N/A', 'N/A@N/A.N/A'),
-(16, 'GONICUS GmbH', 0, '', 'http://www.gonicus.de', '', 'fg', '', '', '');
-
-
-
-CREATE TABLE `glpi_event_log` (
-  `ID` int(11) NOT NULL auto_increment,
-  `item` int(11) NOT NULL default '0',
-  `itemtype` varchar(20) NOT NULL default '',
-  `date` datetime NOT NULL default '0000-00-00 00:00:00',
-  `service` varchar(20) default NULL,
-  `level` tinyint(4) NOT NULL default '0',
-  `message` text NOT NULL,
-  PRIMARY KEY  (`ID`),
-  KEY `comp` (`item`),
-  KEY `date` (`date`),
-  KEY `itemtype` (`itemtype`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=105 ;
-
-
-INSERT INTO `glpi_event_log` (`ID`, `item`, `itemtype`, `date`, `service`, `level`, `message`) VALUES 
-(90, 0, 'dropdowns', '2006-01-18 14:58:40', 'setup', 5, 'glpi added a value to a dropdown.'),
-(89, 0, 'dropdowns', '2006-01-18 14:58:31', 'setup', 5, 'glpi added a value to a dropdown.'),
-(88, 0, 'dropdowns', '2006-01-18 14:58:22', 'setup', 5, 'glpi added a value to a dropdown.'),
-(87, 0, 'dropdowns', '2006-01-18 14:58:07', 'setup', 5, 'glpi added a value to a dropdown.'),
-(86, 0, 'dropdowns', '2006-01-18 14:56:55', 'setup', 5, 'glpi added a value to a dropdown.'),
-(85, 0, 'dropdowns', '2006-01-18 14:56:40', 'setup', 5, 'glpi added a value to a dropdown.'),
-(84, 0, 'dropdowns', '2006-01-18 14:56:28', 'setup', 5, 'glpi added a value to a dropdown.'),
-(83, 0, 'dropdowns', '2006-01-18 14:56:12', 'setup', 5, 'glpi added a value to a dropdown.'),
-(82, 1, 'cartridges', '2006-01-18 14:55:35', 'inventory', 4, 'glpi added item HP Deskjet 80000 Green.'),
-(81, -1, 'system', '2006-01-18 14:49:46', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(80, -1, 'system', '2006-01-18 14:47:02', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(79, -1, 'system', '2006-01-17 12:23:40', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(78, 4, 'documents', '2006-01-17 09:51:47', 'document', 4, 'glpi associate device.'),
-(77, 4, 'documents', '2006-01-17 09:51:38', 'document', 4, 'glpi associate device.'),
-(76, 4, 'printers', '2006-01-17 09:41:51', 'inventory', 4, 'glpi updated item.'),
-(75, 0, 'dropdowns', '2006-01-17 09:41:28', 'setup', 5, 'glpi added a value to a dropdown.'),
-(74, 0, 'dropdowns', '2006-01-17 09:41:14', 'setup', 5, 'glpi added a value to a dropdown.'),
-(73, 0, 'dropdowns', '2006-01-17 09:41:03', 'setup', 5, 'glpi added a value to a dropdown.'),
-(72, 4, 'printers', '2006-01-17 08:56:20', 'inventory', 4, 'glpi added Name.'),
-(71, -1, 'system', '2006-01-17 08:48:04', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(31, -1, 'system', '2005-12-23 09:38:42', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(32, 26, 'computers', '2005-12-23 09:39:05', 'inventory', 4, 'glpi deleted item.'),
-(33, 0, 'Devices', '2005-12-23 14:53:31', 'inventory', 4, 'glpi added gzt.'),
-(34, -1, 'system', '2006-01-03 07:49:38', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(35, -1, 'system', '2006-01-03 08:16:04', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(36, 11, 'networking', '2006-01-03 08:30:08', 'inventory', 4, 'glpi added item name .'),
-(37, 2, 'Devices', '2006-01-03 12:07:52', 'inventory', 4, 'glpi updated item.'),
-(38, 0, 'Devices', '2006-01-03 13:12:53', 'inventory', 4, 'glpi added asdfasdf.'),
-(39, 0, 'Devices', '2006-01-03 13:27:36', 'inventory', 4, 'glpi added amd.'),
-(40, 0, 'Devices', '2006-01-03 13:33:00', 'inventory', 4, 'glpi added Duschaube.'),
-(41, 0, 'Devices', '2006-01-03 13:46:11', 'inventory', 4, 'glpi added name.'),
-(42, 0, 'Devices', '2006-01-03 14:03:42', 'inventory', 4, 'glpi added Hdd.'),
-(43, 0, 'Devices', '2006-01-03 14:42:23', 'inventory', 4, 'glpi added name.'),
-(44, 0, 'Devices', '2006-01-03 14:59:12', 'inventory', 4, 'glpi added Controllers.'),
-(45, 0, 'Devices', '2006-01-03 15:06:59', 'inventory', 4, 'glpi added gfxcard.'),
-(46, 0, 'Devices', '2006-01-03 15:18:33', 'inventory', 4, 'glpi added power.'),
-(47, 0, 'Devices', '2006-01-03 15:22:32', 'inventory', 4, 'glpi added pheripgherals.'),
-(48, -1, 'system', '2006-01-04 08:15:26', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(49, 2, 'Devices', '2006-01-04 08:16:05', 'inventory', 4, 'glpi updated item.'),
-(50, 26, 'computers', '2006-01-04 08:22:28', 'inventory', 4, 'glpi Unlinked a device from computer 26.'),
-(51, -1, 'system', '2006-01-04 11:23:06', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(52, 26, 'documents', '2006-01-04 11:23:47', 'document', 4, 'glpi associate device.'),
-(53, 2, 'documents', '2006-01-04 11:25:40', 'document', 4, 'glpi added item tester.'),
-(54, 3, 'documents', '2006-01-04 11:26:09', 'document', 4, 'glpi added item .'),
-(55, 4, 'documents', '2006-01-04 11:26:29', 'document', 4, 'glpi added item .'),
-(56, -1, 'system', '2006-01-04 15:22:51', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(57, 3, 'documents', '2006-01-04 15:41:50', 'document', 4, 'glpi updated item.'),
-(58, -1, 'system', '2006-01-05 10:17:59', 'login', 3, 'glpi  logged in from 10.3.64.43.'),
-(59, 26, 'documents', '2006-01-05 10:18:52', 'document', 4, 'glpi associate device.'),
-(60, -1, 'system', '2006-01-06 08:24:59', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(61, -1, 'system', '2006-01-06 09:21:47', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(62, -1, 'system', '2006-01-06 10:03:43', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(63, 0, 'dropdowns', '2006-01-06 10:33:17', 'setup', 5, 'glpi added a value to a dropdown.'),
-(64, 0, 'dropdowns', '2006-01-06 10:41:57', 'setup', 5, 'glpi added a value to a dropdown.'),
-(65, 0, 'dropdowns', '2006-01-06 10:42:12', 'setup', 5, 'glpi added a value to a dropdown.'),
-(66, 5, 'monitors', '2006-01-06 14:38:56', 'inventory', 4, 'glpi added asdfasdf.'),
-(67, 27, 'computers', '2006-01-06 14:39:39', 'inventory', 5, 'glpi connected item.'),
-(68, -1, 'system', '2006-01-16 12:08:10', 'login', 1, 'failed login: root'),
-(69, -1, 'system', '2006-01-16 12:08:23', 'login', 1, 'failed login: admin'),
-(70, -1, 'system', '2006-01-16 12:08:35', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(91, 0, 'dropdowns', '2006-01-18 14:58:57', 'setup', 5, 'glpi added a value to a dropdown.'),
-(92, 0, 'dropdowns', '2006-01-18 14:59:08', 'setup', 5, 'glpi added a value to a dropdown.'),
-(93, 0, 'dropdowns', '2006-01-18 14:59:21', 'setup', 5, 'glpi added a value to a dropdown.'),
-(94, 1, 'cartridges', '2006-01-18 15:00:07', 'inventory', 4, 'glpi updated item.'),
-(95, 1, 'cartridges', '2006-01-18 15:02:10', 'inventory', 4, 'glpi added a cartridge.'),
-(96, 1, 'cartridges', '2006-01-18 15:03:19', 'inventory', 4, 'glpi added a cartridge.'),
-(97, 1, 'cartridges', '2006-01-18 15:31:39', 'inventory', 5, 'glpi installed cartridge.'),
-(98, -1, 'system', '2006-01-19 08:33:27', 'login', 3, 'glpi logged in from 10.3.64.43.'),
-(99, 1, 'cartridges', '2006-01-19 08:34:32', 'inventory', 4, 'glpi added 17 cartridge.'),
-(100, 0, 'infocom', '2006-01-19 08:34:54', 'financial', 4, 'glpi added infocoms.'),
-(101, 1, 'cartridges', '2006-01-19 10:21:27', 'inventory', 4, 'glpi updated item.'),
-(102, 1, 'cartridges', '2006-01-19 10:21:33', 'inventory', 4, 'glpi added 1 cartridge.'),
-(103, 2, 'cartridges', '2006-01-19 10:22:45', 'inventory', 4, 'glpi added item Laserjet3.'),
-(104, 2, 'cartridges', '2006-01-19 10:23:16', 'inventory', 4, 'glpi updated item.');
-
-
-
-CREATE TABLE `glpi_followups` (
-  `ID` int(11) NOT NULL auto_increment,
-  `tracking` int(11) default NULL,
-  `date` datetime default NULL,
-  `author` int(11) NOT NULL default '0',
-  `contents` text,
-  PRIMARY KEY  (`ID`),
-  KEY `tracking` (`tracking`),
-  KEY `author` (`author`),
-  KEY `date` (`date`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_infocoms` (
-  `ID` int(11) NOT NULL auto_increment,
-  `FK_device` int(11) NOT NULL default '0',
-  `device_type` tinyint(4) NOT NULL default '0',
-  `buy_date` date NOT NULL default '0000-00-00',
-  `use_date` date NOT NULL default '0000-00-00',
-  `warranty_duration` tinyint(4) NOT NULL default '0',
-  `warranty_info` varchar(255) NOT NULL default '',
-  `FK_enterprise` int(11) default NULL,
-  `num_commande` varchar(50) NOT NULL default '',
-  `bon_livraison` varchar(50) NOT NULL default '',
-  `num_immo` varchar(50) NOT NULL default '',
-  `value` float NOT NULL default '0',
-  `warranty_value` float default NULL,
-  `amort_time` tinyint(4) NOT NULL default '0',
-  `amort_type` varchar(20) NOT NULL default '',
-  `amort_coeff` float NOT NULL default '0',
-  `comments` text NOT NULL,
-  `facture` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `FK_device` (`FK_device`,`device_type`),
-  KEY `FK_enterprise` (`FK_enterprise`),
-  KEY `buy_date` (`buy_date`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
-
-
-INSERT INTO `glpi_infocoms` (`ID`, `FK_device`, `device_type`, `buy_date`, `use_date`, `warranty_duration`, `warranty_info`, `FK_enterprise`, `num_commande`, `bon_livraison`, `num_immo`, `value`, `warranty_value`, `amort_time`, `amort_type`, `amort_coeff`, `comments`, `facture`) VALUES 
-(1, 10, 19, '0000-00-00', '0000-00-00', 0, '', NULL, '', '', '', 0, NULL, 0, '', 0, '', '');
-
-
-
-CREATE TABLE `glpi_inst_software` (
-  `ID` int(11) NOT NULL auto_increment,
-  `cID` int(11) NOT NULL default '0',
-  `license` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  KEY `cID` (`cID`),
-  KEY `sID` (`license`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_kbitems` (
-  `ID` int(11) NOT NULL auto_increment,
-  `categoryID` int(11) NOT NULL default '0',
-  `question` text NOT NULL,
-  `answer` text NOT NULL,
-  `faq` enum('yes','no') NOT NULL default 'no',
-  PRIMARY KEY  (`ID`),
-  KEY `categoryID` (`categoryID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_licenses` (
-  `ID` int(15) NOT NULL auto_increment,
-  `sID` int(15) NOT NULL default '0',
-  `serial` varchar(255) NOT NULL default '',
-  `expire` date default NULL,
-  `oem` enum('N','Y') NOT NULL default 'N',
-  `oem_computer` int(11) NOT NULL default '0',
-  `buy` enum('Y','N') NOT NULL default 'Y',
-  PRIMARY KEY  (`ID`),
-  KEY `sID` (`sID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_links` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_links_device` (
-  `ID` int(11) NOT NULL auto_increment,
-  `FK_links` int(11) NOT NULL default '0',
-  `device_type` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `device_type_2` (`device_type`,`FK_links`),
-  KEY `device_type` (`device_type`),
-  KEY `FK_links` (`FK_links`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_monitors` (
-  `ID` int(10) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  `date_mod` datetime NOT NULL default '0000-00-00 00:00:00',
-  `contact` varchar(255) NOT NULL default '',
-  `contact_num` varchar(255) NOT NULL default '',
-  `tech_num` int(11) NOT NULL default '0',
-  `comments` text NOT NULL,
-  `serial` varchar(255) NOT NULL default '',
-  `otherserial` varchar(255) NOT NULL default '',
-  `size` int(3) NOT NULL default '0',
-  `flags_micro` tinyint(4) NOT NULL default '0',
-  `flags_speaker` tinyint(4) NOT NULL default '0',
-  `flags_subd` tinyint(4) NOT NULL default '0',
-  `flags_bnc` tinyint(4) NOT NULL default '0',
-  `location` int(11) default NULL,
-  `type` int(11) default NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `is_global` enum('0','1') NOT NULL default '0',
-  `deleted` enum('Y','N') NOT NULL default 'N',
-  `is_template` enum('0','1') NOT NULL default '0',
-  `tplname` varchar(255) default NULL,
-  PRIMARY KEY  (`ID`),
-  KEY `ID` (`ID`),
-  KEY `type` (`type`),
-  KEY `location` (`location`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
-  KEY `deleted` (`deleted`),
-  KEY `is_template` (`is_template`),
-  KEY `tech_num` (`tech_num`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
-
-
-INSERT INTO `glpi_monitors` (`ID`, `name`, `date_mod`, `contact`, `contact_num`, `tech_num`, `comments`, `serial`, `otherserial`, `size`, `flags_micro`, `flags_speaker`, `flags_subd`, `flags_bnc`, `location`, `type`, `FK_glpi_enterprise`, `is_global`, `deleted`, `is_template`, `tplname`) VALUES 
-(2, 'asdfasdf', '0000-00-00 00:00:00', '', '', 0, '', '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', '', '');
-
-
-
-CREATE TABLE `glpi_networking` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(30) NOT NULL default '',
-  `ram` varchar(10) NOT NULL default '',
-  `serial` varchar(50) NOT NULL default '',
-  `otherserial` varchar(50) NOT NULL default '',
-  `contact` varchar(30) NOT NULL default '',
-  `contact_num` varchar(30) NOT NULL default '',
-  `tech_num` int(11) NOT NULL default '0',
-  `date_mod` datetime NOT NULL default '0000-00-00 00:00:00',
-  `comments` text NOT NULL,
-  `location` int(11) default NULL,
-  `domain` int(11) NOT NULL default '0',
-  `network` int(11) NOT NULL default '0',
-  `type` int(11) default NULL,
-  `firmware` int(11) default NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `deleted` enum('Y','N') NOT NULL default 'N',
-  `is_template` enum('0','1') NOT NULL default '0',
-  `tplname` varchar(255) default NULL,
-  `ifmac` varchar(30) NOT NULL default '',
-  `ifaddr` varchar(30) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `location` (`location`),
-  KEY `type` (`type`),
-  KEY `firmware` (`firmware`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
-  KEY `deleted` (`deleted`),
-  KEY `is_template` (`is_template`),
-  KEY `tech_num` (`tech_num`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=12 ;
-
-
-INSERT INTO `glpi_networking` (`ID`, `name`, `ram`, `serial`, `otherserial`, `contact`, `contact_num`, `tech_num`, `date_mod`, `comments`, `location`, `domain`, `network`, `type`, `firmware`, `FK_glpi_enterprise`, `deleted`, `is_template`, `tplname`, `ifmac`, `ifaddr`) VALUES 
-(10, '', '', '', '', '', '', 0, '0000-00-00 00:00:00', '', NULL, 0, 0, NULL, NULL, 0, 'N', '1', 'Blank Template', '', ''),
-(11, '', '', '', '', '', '', 0, '2006-01-03 08:30:08', '', 0, 0, 0, 0, 0, 0, 'N', '0', NULL, '', '');
-
-
-
-CREATE TABLE `glpi_networking_ports` (
-  `ID` int(11) NOT NULL auto_increment,
-  `on_device` int(11) NOT NULL default '0',
-  `device_type` tinyint(4) NOT NULL default '0',
-  `logical_number` int(11) NOT NULL default '0',
-  `name` char(30) NOT NULL default '',
-  `ifaddr` char(30) NOT NULL default '',
-  `ifmac` char(30) NOT NULL default '',
-  `iface` int(11) default NULL,
-  `netpoint` int(11) default NULL,
-  PRIMARY KEY  (`ID`),
-  KEY `on_device` (`on_device`,`device_type`),
-  KEY `netpoint` (`netpoint`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_networking_vlan` (
-  `ID` int(11) NOT NULL auto_increment,
-  `FK_port` int(11) NOT NULL default '0',
-  `FK_vlan` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `FK_port_2` (`FK_port`,`FK_vlan`),
-  KEY `FK_port` (`FK_port`),
-  KEY `FK_vlan` (`FK_vlan`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_networking_wire` (
-  `ID` int(11) NOT NULL auto_increment,
-  `end1` int(11) NOT NULL default '0',
-  `end2` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `end1_1` (`end1`,`end2`),
-  KEY `end1` (`end1`),
-  KEY `end2` (`end2`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_peripherals` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  `date_mod` datetime NOT NULL default '0000-00-00 00:00:00',
-  `contact` varchar(255) NOT NULL default '',
-  `contact_num` varchar(255) NOT NULL default '',
-  `tech_num` int(11) NOT NULL default '0',
-  `comments` text NOT NULL,
-  `serial` varchar(255) NOT NULL default '',
-  `otherserial` varchar(255) NOT NULL default '',
-  `location` int(11) NOT NULL default '0',
-  `type` int(11) NOT NULL default '0',
-  `brand` varchar(255) NOT NULL default '',
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `is_global` enum('0','1') NOT NULL default '0',
-  `deleted` enum('Y','N') NOT NULL default 'N',
-  `is_template` enum('0','1') NOT NULL default '0',
-  `tplname` varchar(255) default NULL,
-  PRIMARY KEY  (`ID`),
-  KEY `type` (`type`),
-  KEY `location` (`location`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
-  KEY `deleted` (`deleted`),
-  KEY `is_template` (`is_template`),
-  KEY `tech_num` (`tech_num`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
-
-
-INSERT INTO `glpi_peripherals` (`ID`, `name`, `date_mod`, `contact`, `contact_num`, `tech_num`, `comments`, `serial`, `otherserial`, `location`, `type`, `brand`, `FK_glpi_enterprise`, `is_global`, `deleted`, `is_template`, `tplname`) VALUES 
-(1, '', '0000-00-00 00:00:00', '', '', 0, '', '', '', 0, 0, '', 0, '0', 'N', '1', 'Blank Template'),
-(2, 'gf5200', '2005-12-13 09:34:32', 'Herr Herr', '0231', 4, 'f', '45875486468', '4554', 0, 0, 'GC', 1, '0', 'N', '0', NULL);
-
-
-
-CREATE TABLE `glpi_printers` (
-  `ID` int(10) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  `date_mod` datetime NOT NULL default '0000-00-00 00:00:00',
-  `contact` varchar(255) NOT NULL default '',
-  `contact_num` varchar(255) NOT NULL default '',
-  `tech_num` int(11) NOT NULL default '0',
-  `serial` varchar(255) NOT NULL default '',
-  `otherserial` varchar(255) NOT NULL default '',
-  `flags_serial` tinyint(4) NOT NULL default '0',
-  `flags_par` tinyint(4) NOT NULL default '0',
-  `flags_usb` tinyint(4) NOT NULL default '0',
-  `comments` text NOT NULL,
-  `ramSize` varchar(6) NOT NULL default '',
-  `location` int(11) default NULL,
-  `domain` int(11) NOT NULL default '0',
-  `network` int(11) NOT NULL default '0',
-  `type` int(11) default NULL,
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `deleted` enum('Y','N') NOT NULL default 'N',
-  `is_template` enum('0','1') NOT NULL default '0',
-  `tplname` varchar(255) default NULL,
-  `initial_pages` varchar(30) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  KEY `id` (`ID`),
-  KEY `location` (`location`),
-  KEY `type` (`type`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
-  KEY `deleted` (`deleted`),
-  KEY `is_template` (`is_template`),
-  KEY `tech_num` (`tech_num`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;
-
-
-INSERT INTO `glpi_printers` (`ID`, `name`, `date_mod`, `contact`, `contact_num`, `tech_num`, `serial`, `otherserial`, `flags_serial`, `flags_par`, `flags_usb`, `comments`, `ramSize`, `location`, `domain`, `network`, `type`, `FK_glpi_enterprise`, `deleted`, `is_template`, `tplname`, `initial_pages`) VALUES 
-(1, 'cn=demohost,ou=printers,ou=systems,dc=gonicus,dc=de', '2006-02-01 12:48:33', '', '', 0, '', '', 0, 0, 0, '', '0', 0, 0, 0, 2, 8, 'N', '0', NULL, '0'),
-(2, 'cn=drucker4,ou=printers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '2006-09-19 09:49:33', '', '', 0, '', '', 0, 0, 0, '', '0', 0, 0, 0, 3, 12, 'N', '0', NULL, '0'),
-(3, 'cn=drucker6,ou=printers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '2006-11-29 14:53:41', '', '', 0, '', '', 0, 0, 0, '', '0', 0, 0, 0, 3, 12, 'N', '0', NULL, '0'),
-(4, 'cn=Fettsäuren,ou=printers,ou=systems,ou=keks,ou=DasTestDep,o=Landeshauptstadt München,c=de', '2006-09-28 09:17:45', '', '', 0, '', '', 1, 1, 1, '', '0', 0, 0, 0, 3, 12, 'N', '0', NULL, '0'),
-(5, 'cn=Brennwert,ou=printers,ou=systems,ou=keks,ou=DasTestDep,o=Landeshauptstadt München,c=de', '2006-09-29 11:02:10', '', '', 0, '', '', 1, 1, 1, 'dfsaaaaaaaaaaaaaaaaa', '0', 0, 0, 0, 3, 12, 'N', '0', NULL, '0'),
-(7, 'cn=atz23,ou=printers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '2006-11-29 10:19:48', '', '', 19, '', '', 1, 1, 1, 'ursssszzzzzzzzzzzzzzzzzzzzzzzzzzzzzz', '0', 0, 0, 0, 3, 12, 'N', '0', NULL, '0'),
-(8, 'cn=drucker2,ou=printers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '2006-11-29 10:25:26', '', '', 0, '', '', 1, 1, 1, 'test', '0', 0, 0, 0, 3, 12, 'N', '0', NULL, '0');
-
-
-
-CREATE TABLE `glpi_repair_item` (
-  `ID` int(11) NOT NULL auto_increment,
-  `device_type` tinyint(4) NOT NULL default '0',
-  `id_device` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  KEY `device_type` (`device_type`),
-  KEY `device_type_2` (`device_type`,`id_device`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_reservation_item` (
-  `ID` int(11) NOT NULL auto_increment,
-  `device_type` tinyint(4) NOT NULL default '0',
-  `id_device` int(11) NOT NULL default '0',
-  `comments` text NOT NULL,
-  PRIMARY KEY  (`ID`),
-  KEY `device_type` (`device_type`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
-
-
-INSERT INTO `glpi_reservation_item` (`ID`, `device_type`, `id_device`, `comments`) VALUES 
-(1, 1, 20, '');
-
-
-
-CREATE TABLE `glpi_reservation_resa` (
-  `ID` bigint(20) NOT NULL auto_increment,
-  `id_item` int(11) NOT NULL default '0',
-  `begin` datetime NOT NULL default '0000-00-00 00:00:00',
-  `end` datetime NOT NULL default '0000-00-00 00:00:00',
-  `id_user` int(11) NOT NULL default '0',
-  `comment` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  KEY `id_item` (`id_item`),
-  KEY `id_user` (`id_user`),
-  KEY `begin` (`begin`),
-  KEY `end` (`end`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_software` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(200) NOT NULL default '',
-  `version` varchar(20) NOT NULL default '',
-  `comments` text,
-  `location` int(11) default NULL,
-  `tech_num` int(11) NOT NULL default '0',
-  `platform` int(11) default NULL,
-  `is_update` enum('N','Y') NOT NULL default 'N',
-  `update_software` int(11) NOT NULL default '-1',
-  `FK_glpi_enterprise` int(11) NOT NULL default '0',
-  `deleted` enum('Y','N') NOT NULL default 'N',
-  `is_template` enum('0','1') NOT NULL default '0',
-  `tplname` varchar(255) default NULL,
-  `date_mod` datetime default NULL,
-  PRIMARY KEY  (`ID`),
-  KEY `platform` (`platform`),
-  KEY `location` (`location`),
-  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
-  KEY `deleted` (`deleted`),
-  KEY `is_template` (`is_template`),
-  KEY `date_mod` (`date_mod`),
-  KEY `tech_num` (`tech_num`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
-
-
-INSERT INTO `glpi_software` (`ID`, `name`, `version`, `comments`, `location`, `tech_num`, `platform`, `is_update`, `update_software`, `FK_glpi_enterprise`, `deleted`, `is_template`, `tplname`, `date_mod`) VALUES 
-(6, '', '', NULL, NULL, 0, NULL, 'N', -1, 0, 'N', '1', 'Blank Template', NULL);
-
-
-
-CREATE TABLE `glpi_state_item` (
-  `ID` int(11) NOT NULL auto_increment,
-  `device_type` tinyint(4) NOT NULL default '0',
-  `id_device` int(11) NOT NULL default '0',
-  `state` int(11) default '1',
-  `is_template` enum('0','1') NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  KEY `device_type` (`device_type`),
-  KEY `device_type_2` (`device_type`,`id_device`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_tracking` (
-  `ID` int(11) NOT NULL auto_increment,
-  `date` datetime default NULL,
-  `closedate` datetime NOT NULL default '0000-00-00 00:00:00',
-  `status` enum('new','old') default NULL,
-  `author` int(11) NOT NULL default '0',
-  `assign` int(11) NOT NULL default '0',
-  `assign_type` tinyint(4) NOT NULL default '0',
-  `device_type` int(11) NOT NULL default '1',
-  `computer` int(11) default NULL,
-  `contents` text,
-  `priority` tinyint(4) NOT NULL default '1',
-  `is_group` enum('no','yes') NOT NULL default 'no',
-  `uemail` varchar(100) default NULL,
-  `emailupdates` varchar(4) default NULL,
-  `realtime` float NOT NULL default '0',
-  `category` int(11) NOT NULL default '0',
-  PRIMARY KEY  (`ID`),
-  KEY `computer` (`computer`),
-  KEY `author` (`author`),
-  KEY `assign` (`assign`),
-  KEY `date` (`date`),
-  KEY `closedate` (`closedate`),
-  KEY `status` (`status`),
-  KEY `category` (`category`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_tracking_planning` (
-  `ID` bigint(20) NOT NULL auto_increment,
-  `id_tracking` int(11) NOT NULL default '0',
-  `id_assign` int(11) NOT NULL default '0',
-  `begin` datetime NOT NULL default '0000-00-00 00:00:00',
-  `end` datetime NOT NULL default '0000-00-00 00:00:00',
-  PRIMARY KEY  (`ID`),
-  KEY `id_tracking` (`id_tracking`),
-  KEY `begin` (`begin`),
-  KEY `end` (`end`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_type_computers` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=30 ;
-
-
-INSERT INTO `glpi_type_computers` (`ID`, `name`) VALUES 
-(26, 'SuperDupfer'),
-(27, 'Server'),
-(18, 'System tester'),
-(19, 'Windows workstation'),
-(21, 'Network device'),
-(28, 'Microcontroller');
-
-
-
-CREATE TABLE `glpi_type_docs` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) NOT NULL default '',
-  `ext` varchar(10) NOT NULL default '',
-  `icon` varchar(255) NOT NULL default '',
-  `mime` varchar(100) NOT NULL default '',
-  `upload` enum('Y','N') NOT NULL default 'Y',
-  `date_mod` datetime default NULL,
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `extension` (`ext`),
-  KEY `upload` (`upload`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=54 ;
-
-
-INSERT INTO `glpi_type_docs` (`ID`, `name`, `ext`, `icon`, `mime`, `upload`, `date_mod`) VALUES 
-(1, 'JPEG', 'jpg', 'jpg-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(2, 'PNG', 'png', 'png-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(3, 'GIF', 'gif', 'gif-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(4, 'BMP', 'bmp', 'bmp-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(5, 'Photoshop', 'psd', 'psd-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(6, 'TIFF', 'tif', 'tif-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(7, 'AIFF', 'aiff', 'aiff-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(8, 'Windows Media', 'asf', 'asf-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(9, 'Windows Media', 'avi', 'avi-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(44, 'C source', 'c', '', '', 'Y', '2004-12-13 19:47:22'),
-(27, 'RealAudio', 'rm', 'rm-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(16, 'Midi', 'mid', 'mid-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(17, 'QuickTime', 'mov', 'mov-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(18, 'MP3', 'mp3', 'mp3-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(19, 'MPEG', 'mpg', 'mpg-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(20, 'Ogg Vorbis', 'ogg', 'ogg-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(24, 'QuickTime', 'qt', 'qt-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(10, 'BZip', 'bz2', 'bz2-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(25, 'RealAudio', 'ra', 'ra-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(26, 'RealAudio', 'ram', 'ram-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(11, 'Word', 'doc', 'doc-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(12, 'DjVu', 'djvu', '', '', 'Y', '2004-12-13 19:47:21'),
-(42, 'MNG', 'mng', '', '', 'Y', '2004-12-13 19:47:22'),
-(13, 'PostScript', 'eps', 'ps-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(14, 'GZ', 'gz', 'gz-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(37, 'WAV', 'wav', 'wav-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(15, 'HTML', 'html', 'html-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(34, 'Flash', 'swf', '', '', 'Y', '2004-12-13 19:47:22'),
-(21, 'PDF', 'pdf', 'pdf-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(22, 'PowerPoint', 'ppt', 'ppt-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(23, 'PostScript', 'ps', 'ps-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(40, 'Windows Media', 'wmv', '', '', 'Y', '2004-12-13 19:47:22'),
-(28, 'RTF', 'rtf', 'rtf-dist.png', '', 'Y', '2004-12-13 19:47:21'),
-(29, 'StarOffice', 'sdd', 'sdd-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(30, 'StarOffice', 'sdw', 'sdw-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(31, 'Stuffit', 'sit', 'sit-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(43, 'Adobe Illustrator', 'ai', 'ai-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(32, 'OpenOffice Impress', 'sxi', 'sxi-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(33, 'OpenOffice', 'sxw', 'sxw-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(46, 'DVI', 'dvi', 'dvi-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(35, 'TGZ', 'tgz', 'tgz-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(36, 'texte', 'txt', 'txt-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(49, 'RedHat/Mandrake/SuSE', 'rpm', 'rpm-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(38, 'Excel', 'xls', 'xls-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(39, 'XML', 'xml', 'xml-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(41, 'Zip', 'zip', 'zip-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(45, 'Debian', 'deb', 'deb-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(47, 'C header', 'h', '', '', 'Y', '2004-12-13 19:47:22'),
-(48, 'Pascal', 'pas', '', '', 'Y', '2004-12-13 19:47:22'),
-(50, 'OpenOffice Calc', 'sxc', 'sxc-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(51, 'LaTeX', 'tex', 'tex-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(52, 'GIMP multi-layer', 'xcf', 'xcf-dist.png', '', 'Y', '2004-12-13 19:47:22'),
-(53, 'JPEG', 'jpeg', 'jpg-dist.png', '', 'Y', '2005-03-07 22:23:17');
-
-
-
-CREATE TABLE `glpi_type_monitors` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) default NULL,
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
-
-
-INSERT INTO `glpi_type_monitors` (`ID`, `name`) VALUES 
-(1, 'testoe');
-
-
-
-CREATE TABLE `glpi_type_networking` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) default NULL,
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_type_peripherals` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) default NULL,
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
-
-
-
-
-CREATE TABLE `glpi_type_printers` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(255) default NULL,
-  PRIMARY KEY  (`ID`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=15 ;
-
-
-INSERT INTO `glpi_type_printers` (`ID`, `name`) VALUES 
-(2, 'Tintenstrahl'),
-(3, 'Farb Laser'),
-(5, 'Not known'),
-(6, 'Nadeldrucker Farbe'),
-(10, 'Nadeldrucker'),
-(11, 'Laser'),
-(12, 'Photodrucker A3'),
-(14, 'Tintentrahl');
-
-
-
-CREATE TABLE `glpi_users` (
-  `ID` int(11) NOT NULL auto_increment,
-  `name` varchar(80) NOT NULL default '',
-  `password` varchar(80) NOT NULL default '',
-  `password_md5` varchar(80) NOT NULL default '',
-  `email` varchar(80) NOT NULL default '',
-  `phone` varchar(100) default NULL,
-  `type` enum('normal','admin','post-only','super-admin') NOT NULL default 'normal',
-  `realname` varchar(255) NOT NULL default '',
-  `can_assign_job` enum('yes','no') NOT NULL default 'no',
-  `location` int(11) default NULL,
-  `tracking_order` enum('yes','no') NOT NULL default 'no',
-  `language` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`ID`),
-  UNIQUE KEY `name` (`name`),
-  KEY `type` (`type`),
-  KEY `name_2` (`name`)
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=22 ;
-
-
-INSERT INTO `glpi_users` (`ID`, `name`, `password`, `password_md5`, `email`, `phone`, `type`, `realname`, `can_assign_job`, `location`, `tracking_order`, `language`) VALUES 
-(1, 'cn=GOsa main administrator admin,ou=people,dc=gonicus,dc=de', '', '', 'asdfasdf@asdfasdf.de', '333333333', 'normal', '', 'no', NULL, 'no', ''),
-(2, 'cn=Getester Hainz,ou=people,dc=gonicus,dc=de', '', '', 'gtest@blafasel.org', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(3, 'cn=adff dendnen,ou=people,dc=gonicus,dc=de', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(4, 'cn=tttttttttttt testttttttttttttttttt,ou=people,ou=Diesisteinelangeabteilung,ou=', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(5, 'cn=asdff33 asdf333,ou=people,ou=tester,ou=Vertrieb,dc=gonicus,dc=de', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(6, 'cn=Florian Schiessl,ou=people,o=Landeshauptstadt München,c=de', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(7, 'cn=blub blab,ou=people,o=Landeshauptstadt München,c=de', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(8, 'cn=Florian test,ou=people,o=Landeshauptstadt München,c=de', '', '', '', '233-92742', 'normal', '', 'no', NULL, 'no', ''),
-(9, 'uid=pppppp,ou=people,o=Landeshauptstadt München,c=de', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(10, 'cn=acltest2 acltest2,ou=people,ou=checkTheFAIStuff,ou=DasTestDep,o=Landeshauptst', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(11, 'cn=acltest acltest,ou=people,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', 'acltest@gonicus.de', '123123', 'normal', '', 'no', NULL, 'no', ''),
-(12, 'cn=Max Mustermann,ou=people,ou=PrinterLosesMember,ou=DasTestDep,o=Landeshauptsta', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(13, 'cn=Susanne Neuhaus,ou=people,ou=PrinterLosesMember,ou=DasTestDep,o=Landeshauptst', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(14, '', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(15, 'cn=Florian Meier,ou=people,ou=PrinterLosesMember,ou=DasTestDep,o=Landeshauptstad', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(16, 'cn=abtielung abtielung,ou=people,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '7890', 'normal', '', 'no', NULL, 'no', ''),
-(17, 'cn=Franz Keller,ou=people,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', 'ableis@gonicus.de', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(18, 'cn=Jan Wenzel,ou=people,o=Landeshauptstadt München,c=de', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
-(19, 'cn=acl2 acl2,ou=people,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '22222222222222', 'normal', '', 'no', NULL, 'no', ''),
-(20, 'cn=a11 a11,ou=people,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', 'a11@gonicus.de', '311112', 'normal', '', 'no', NULL, 'no', ''),
-(21, 'cn=Admin Admin,ou=people,o=Landeshauptstadt München,c=de', '', '', 'ableis@gonicus.de', '1234', 'normal', '', 'no', NULL, 'no', '');
-
diff --git a/contrib/mysql/gofax/gofax.sql b/contrib/mysql/gofax/gofax.sql
deleted file mode 100644 (file)
index 744514a..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-create database gofax;
-use gofax;
-
-CREATE TABLE faxlog (
-       id                    VARCHAR(20) NOT NULL,
-       status                INTEGER NOT NULL,
-       status_message        TEXT,
-       uid                   VARCHAR(20) NOT NULL,
-       queuing_time          TIMESTAMP NOT NULL,
-       sender_msn            VARCHAR(100),
-       sender_id             VARCHAR(100),
-       receiver_msn          VARCHAR(100),
-       receiver_id           VARCHAR(100),
-       transfer_time         INTEGER,
-       pages                 INTEGER
-       );
-
-CREATE TABLE faxdata (
-       id                    VARCHAR(20) PRIMARY KEY,
-       fax_data              BLOB
-       );
-
-GRANT INSERT,SELECT ON gofax.faxlog TO logger@localhost IDENTIFIED BY 'somemysqlpass';
-GRANT INSERT,SELECT,DELETE ON gofax.faxdata TO logger@localhost IDENTIFIED BY 'somemysqlpass';
diff --git a/contrib/mysql/gofon/gofon.sql b/contrib/mysql/gofon/gofon.sql
deleted file mode 100644 (file)
index 584bcc9..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-create database gophone;
-use gophone;
-
-create table cdr (
-  calldate datetime NOT NULL default '0000-00-00 00:00:00',
-  clid varchar(80) NOT NULL default '',
-  src varchar(80) NOT NULL default '',
-  dst varchar(80) NOT NULL default '',
-  dcontext varchar(80) NOT NULL default '',
-  channel varchar(80) NOT NULL default '',
-  dstchannel varchar(80) NOT NULL default '',
-  lastapp varchar(80) NOT NULL default '',
-  lastdata varchar(80) NOT NULL default '',
-  duration integer NOT NULL default '0',
-  billsec integer NOT NULL default '0',
-  disposition varchar(45) NOT NULL default '',
-  amaflags integer NOT NULL default '0',
-  accountcode varchar(20) NOT NULL default '',
-  uniqueid varchar(32) NOT NULL default '',
-  userfield varchar(255) NOT NULL default ''
-);
-
-GRANT INSERT,SELECT ON gophone.cdr TO asterisk@localhost IDENTIFIED BY 'somemysqlpass';
-
diff --git a/contrib/mysql/golog/golog.sql b/contrib/mysql/golog/golog.sql
deleted file mode 100644 (file)
index 0461fdc..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-
-create database golog;
-use golog;
-
-create table golog (
-       time_stamp DATETIME,
-       host VARCHAR(50),
-       message VARCHAR(255),
-       log_level VARCHAR(15),
-       matched_dn VARCHAR(255),
-       matched_ts DATETIME
-       );
-
-GRANT INSERT,SELECT,DELETE ON golog.golog TO gomon@localhost IDENTIFIED BY 'somemysqlpass';
diff --git a/contrib/mysql/logging/logging.sql b/contrib/mysql/logging/logging.sql
deleted file mode 100644 (file)
index e61472d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-create database gosa_log;
-use gosa_log;
-
-CREATE TABLE `gosa_log` (
-  `id` int(10) unsigned NOT NULL auto_increment,
-  `timestamp` int(10) NOT NULL,
-  `user` longtext NOT NULL,
-  `action` varchar(255) NOT NULL,
-  `objecttype` varchar(255) NOT NULL,
-  `object` varchar(255) NOT NULL,
-  `changes` blob NOT NULL,
-  `result` varchar(255) NOT NULL,
-  PRIMARY KEY  (`id`)
-  KEY `timestamp` (`timestamp`)
-  KEY `action` (`action`),
-) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-
diff --git a/contrib/openldap/apple.schema.README b/contrib/openldap/apple.schema.README
deleted file mode 100644 (file)
index e0e3f9a..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-
-Heya,
-
-as we don't want to run into licensing issues the apple.schema is not included
-here. In case you want to manage your apple users' homedirectories with GOsa
-please copy the apple.schema file from your MacOSX installation into the
-schema-directory of your openldap installation and include it in the slapd-
-configuration. Usually you'll have to change a few objectclasses as some
-attribute-types are missing.
-
-For example to use the apple.schema from osx 10.4 you'll have to
-- remove the objectclass authAuthorityObject
-- remove the objectclass apple-acl
-- remove the following attributes from all ObjectClasses:
-    - acctFlags
-    - pwdLastSet
-    - logonTime
-    - logoffTime
-    - kickoffTime
-    - homeDrive
-    - scriptPath
-    - profilePath
-    - userWorkstations
-    - smbHome
-    - rid
-    - primaryGroupID
-- uncomment the apple-user-homeDirectory attribute
-- add the apple-user-homeDirectory attribute to the apple-user objectclass
-
-YMMV depending on the version of the apple.schema. As far as I can remember the
-apple.schema from 10.2 does not include all neccessary attributes and object-
-classes, so you probably want to use a more recent one.
-
-
-As I actually don't have the time to provide a complete howto I've googled for
-a howto - probably http://www.spack.org/wiki/AppleOsxIntegrationWithOpenLdap
-will give you some hints how to setup your apple.
-
-The netatalk plugin was developed by Gina Haeussge <osd@foosel.net> and Bernd
-Zeimetz <osd@bzed.de> for use at the Darmstadt University of Technology,
-Department of Architecture.
-
-In case you have any questions or find any bugs feel free to contact me at
-<osd@bzed.de>.
-
-
-Best regards,
-
-
-Bernd Zeimetz
diff --git a/contrib/openldap/dhcp.schema b/contrib/openldap/dhcp.schema
deleted file mode 100644 (file)
index a0a68e9..0000000
+++ /dev/null
@@ -1,462 +0,0 @@
-attributetype ( 2.16.840.1.113719.1.203.4.1 
-       NAME 'dhcpPrimaryDN' 
-       EQUALITY distinguishedNameMatch
-       DESC 'The DN of the dhcpServer which is the primary server for the configuration.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.2 
-       NAME 'dhcpSecondaryDN' 
-       EQUALITY distinguishedNameMatch
-       DESC 'The DN of dhcpServer(s) which provide backup service for the configuration.'
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.3 
-       NAME 'dhcpStatements' 
-       EQUALITY caseIgnoreIA5Match
-       DESC 'Flexible storage for specific data depending on what object this exists in. Like conditional statements, server parameters, etc. This allows the standard to evolve without needing to adjust the schema.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.4 
-       NAME 'dhcpRange' 
-       EQUALITY caseIgnoreIA5Match
-       DESC 'The starting & ending IP Addresses in the range (inclusive), separated by a hyphen; if the range only contains one address, then just the address can be specified with no hyphen.  Each range is defined as a separate value.'
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.5 
-       NAME 'dhcpPermitList' 
-       EQUALITY caseIgnoreIA5Match
-       DESC 'This attribute contains the permit lists associated with a pool. Each permit list is defined as a separate value.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.6 
-       NAME 'dhcpNetMask' 
-       EQUALITY integerMatch
-       DESC 'The subnet mask length for the subnet.  The mask can be easily computed from this length.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.7 
-       NAME 'dhcpOption' 
-       EQUALITY caseIgnoreIA5Match
-       DESC 'Encoded option values to be sent to clients.  Each value represents a single option and contains (OptionTag, Length, OptionValue) encoded in the format used by DHCP.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.8 
-       NAME 'dhcpClassData' 
-       EQUALITY caseIgnoreIA5Match
-       DESC 'Encoded text string or list of bytes expressed in hexadecimal, separated by colons.  Clients match subclasses based on matching the class data with the results of match or spawn with statements in the class name declarations.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.9 
-       NAME 'dhcpOptionsDN' 
-       EQUALITY distinguishedNameMatch
-       DESC 'The distinguished name(s) of the dhcpOption objects containing the configuration options provided by the server.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.10 
-       NAME 'dhcpHostDN' 
-       EQUALITY distinguishedNameMatch
-       DESC 'the distinguished name(s) of the dhcpHost objects.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) 
-
-attributetype ( 2.16.840.1.113719.1.203.4.11 
-       NAME 'dhcpPoolDN' 
-       EQUALITY distinguishedNameMatch
-       DESC 'The distinguished name(s) of pools.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.12 
-       NAME 'dhcpGroupDN' 
-       EQUALITY distinguishedNameMatch
-       DESC 'The distinguished name(s)   of the groups.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.13 
-       NAME 'dhcpSubnetDN' 
-       EQUALITY distinguishedNameMatch
-       DESC 'The distinguished name(s) of the subnets.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.14 
-       NAME 'dhcpLeaseDN' 
-       EQUALITY distinguishedNameMatch
-       DESC 'The distinguished name of a client address.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE)
-
-attributetype ( 2.16.840.1.113719.1.203.4.15 
-       NAME 'dhcpLeasesDN' 
-       DESC 'The distinguished name(s) client addresses.' 
-       EQUALITY distinguishedNameMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.16 
-       NAME 'dhcpClassesDN' 
-       EQUALITY distinguishedNameMatch
-       DESC 'The distinguished name(s) of a class(es) in a subclass.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.17 
-       NAME 'dhcpSubclassesDN' 
-       EQUALITY distinguishedNameMatch
-       DESC 'The distinguished name(s) of subclass(es).' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.18 
-       NAME 'dhcpSharedNetworkDN' 
-       EQUALITY distinguishedNameMatch
-       DESC 'The distinguished name(s) of sharedNetworks.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.19 
-       NAME 'dhcpServiceDN' 
-       EQUALITY distinguishedNameMatch
-       DESC 'The DN of dhcpService object(s)which contain the configuration information. Each dhcpServer object has this attribute identifying the DHCP configuration(s) that the server is associated with.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.20 
-       NAME 'dhcpVersion'
-       DESC 'The version attribute of this object.'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.21 
-       NAME 'dhcpImplementation' 
-       EQUALITY caseIgnoreIA5Match
-       DESC 'Description of the DHCP Server implementation e.g. DHCP Servers vendor.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.22 
-       NAME 'dhcpAddressState' 
-       EQUALITY caseIgnoreIA5Match
-       DESC 'This stores information about the current binding-status of an address.  For dynamic addresses managed by DHCP, the values should be restricted to the following: "FREE", "ACTIVE", "EXPIRED", "RELEASED", "RESET", "ABANDONED", "BACKUP".  For other addresses, it SHOULD be one of the following: "UNKNOWN", "RESERVED" (an address that is managed by DHCP that is reserved for a specific client), "RESERVED-ACTIVE" (same as reserved, but address is currently in use), "ASSIGNED" (assigned manually or by some other mechanism), "UNASSIGNED", "NOTASSIGNABLE".'
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.23 
-       NAME 'dhcpExpirationTime' 
-       EQUALITY generalizedTimeMatch 
-       DESC 'This is the time the current lease for an address expires.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.24 
-       NAME 'dhcpStartTimeOfState' 
-       EQUALITY generalizedTimeMatch 
-       DESC 'This is the time of the last state change for a leased address.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.25 
-       NAME 'dhcpLastTransactionTime' 
-       EQUALITY generalizedTimeMatch 
-       DESC 'This is the last time a valid DHCP packet was received from the client.'
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.26 
-       NAME 'dhcpBootpFlag' 
-       EQUALITY booleanMatch 
-       DESC 'This indicates whether the address was assigned via BOOTP.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.27 
-       NAME 'dhcpDomainName' 
-       EQUALITY caseIgnoreIA5Match
-       DESC 'This is the name of the domain sent to the client by the server.  It is essentially the same as the value for DHCP option 15 sent to the client, and represents only the domain - not the full FQDN.  To obtain the full FQDN assigned to the client you must prepend the "dhcpAssignedHostName" to this value with a ".".' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.28 
-       NAME 'dhcpDnsStatus' 
-       EQUALITY integerMatch
-       DESC 'This indicates the status of updating DNS resource records on behalf of the client by the DHCP server for this address.  The value is a 16-bit bitmask.'
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.29 
-       NAME 'dhcpRequestedHostName' 
-       EQUALITY caseIgnoreIA5Match
-       DESC 'This is the hostname that was requested by the client.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.30 
-       NAME 'dhcpAssignedHostName' 
-       EQUALITY caseIgnoreIA5Match
-       DESC 'This is the actual hostname that was assigned to a client. It may not be the name that was requested by the client.  The fully qualified domain name can be determined by appending the value of "dhcpDomainName" (with a dot separator) to this name.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.31 
-       NAME 'dhcpReservedForClient' 
-       EQUALITY distinguishedNameMatch
-       DESC 'The distinguished name of a "dhcpClient" that an address is reserved for.  This may not be the same as the "dhcpAssignedToClient" attribute if the address is being reassigned but the current lease has not yet expired.'
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.32 
-       NAME 'dhcpAssignedToClient' 
-       EQUALITY distinguishedNameMatch
-       DESC 'This is the distinguished name of a "dhcpClient" that an address is currently assigned to.  This attribute is only present in the class when the address is leased.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.33 
-       NAME 'dhcpRelayAgentInfo' 
-       EQUALITY octetStringMatch
-       DESC 'If the client request was received via a relay agent, this contains information about the relay agent that was available from the DHCP request.  This is a hex-encoded option value.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.34 
-       NAME 'dhcpHWAddress' 
-       EQUALITY caseIgnoreIA5Match
-       DESC 'The clients hardware address that requested this IP address.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.35 
-       NAME 'dhcpHashBucketAssignment' 
-       EQUALITY octetStringMatch
-       DESC 'HashBucketAssignment bit map for the DHCP Server, as defined in DHC Load Balancing Algorithm [RFC 3074].' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.36 
-       NAME 'dhcpDelayedServiceParameter' 
-       EQUALITY integerMatch
-       DESC 'Delay in seconds corresponding to Delayed Service Parameter configuration, as defined in  DHC Load Balancing Algorithm [RFC 3074]. '
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.37 
-       NAME 'dhcpMaxClientLeadTime' 
-       EQUALITY integerMatch
-       DESC 'Maximum Client Lead Time configuration in seconds, as defined in DHCP Failover Protocol [FAILOVR]' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.38 
-       NAME 'dhcpFailOverEndpointState' 
-       EQUALITY caseIgnoreIA5Match
-       DESC 'Server (Failover Endpoint) state, as defined in DHCP Failover Protocol [FAILOVR]' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.39 
-       NAME 'dhcpErrorLog' 
-       EQUALITY caseIgnoreIA5Match
-       DESC 'Generic error log attribute that allows logging error conditions within a dhcpService or a dhcpSubnet, like no IP addresses available for lease.'
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.40 
-       NAME 'dhcpLocatorDN' 
-       EQUALITY distinguishedNameMatch 
-       DESC 'The DN of dhcpLocator object which contain the DNs of all DHCP configuration objects. There will be a single dhcpLocator object in the tree with links to all the DHCP objects in the tree' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
-
-attributetype  ( 2.16.840.1.113719.1.203.4.41 
-       NAME 'dhcpKeyAlgorithm' 
-       EQUALITY caseIgnoreIA5Match 
-       DESC 'Algorithm to generate TSIG Key' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype  ( 2.16.840.1.113719.1.203.4.42 
-       NAME 'dhcpKeySecret' 
-       EQUALITY octetStringMatch 
-       DESC 'Secret to generate TSIG Key' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.43 
-       NAME 'dhcpDnsZoneServer' 
-       EQUALITY caseIgnoreIA5Match 
-       DESC 'Master server of the DNS Zone' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 2.16.840.1.113719.1.203.4.44 
-       NAME 'dhcpKeyDN' 
-       EQUALITY distinguishedNameMatch 
-       DESC 'The DNs of TSIG Key to use in secure dynamic updates. In case of locator object, this will be list of TSIG keys.  In case of DHCP Service, Shared Network, Subnet and DNS Zone, it will be a single key.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12)
-
-attributetype ( 2.16.840.1.113719.1.203.4.45 
-       NAME 'dhcpZoneDN' 
-       EQUALITY distinguishedNameMatch 
-       DESC 'The DNs of DNS Zone. In case of locator object, this will be list of DNS Zones in the tree. In case of DHCP Service, Shared Network and Subnet, it will be a single DNS Zone.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12)
-
-attributetype ( 2.16.840.1.113719.1.203.4.46 
-       NAME 'dhcpFailOverPrimaryServer' 
-       EQUALITY caseIgnoreIA5Match 
-       DESC 'IP address or DNS name of the server playing primary role in DHC Load Balancing and Fail over.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26  )
-
-attributetype ( 2.16.840.1.113719.1.203.4.47 
-       NAME 'dhcpFailOverSecondaryServer' 
-       EQUALITY caseIgnoreIA5Match 
-       DESC 'IP address or DNS name of the server playing secondary role in DHC Load Balancing and Fail over.' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26  )
-
-attributetype ( 2.16.840.1.113719.1.203.4.48
-       NAME 'dhcpFailOverPrimaryPort' 
-       EQUALITY integerMatch 
-       DESC 'Port on which primary server listens for connections from its fail over peer (secondary server)' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27  )
-       
-attributetype ( 2.16.840.1.113719.1.203.4.49
-       NAME 'dhcpFailOverSecondaryPort' 
-       EQUALITY integerMatch 
-       DESC 'Port on which secondary server listens for connections from its fail over peer (primary server)' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27  )
-
-attributetype ( 2.16.840.1.113719.1.203.4.50
-       NAME 'dhcpFailOverResponseDelay' 
-       EQUALITY integerMatch 
-       DESC 'Maximum response time in seconds, before Server assumes that connection to fail over peer has failed' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27  )
-
-attributetype ( 2.16.840.1.113719.1.203.4.51
-       NAME 'dhcpFailOverUnackedUpdates' 
-       EQUALITY integerMatch 
-       DESC 'Number of BNDUPD messages that server can send before it receives BNDACK from its fail over peer' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27  )
-
-attributetype ( 2.16.840.1.113719.1.203.4.52
-       NAME 'dhcpFailOverSplit' 
-       EQUALITY integerMatch 
-       DESC 'Split between the primary and secondary servers for fail over purpose' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27  )
-
-attributetype ( 2.16.840.1.113719.1.203.4.53
-       NAME 'dhcpFailOverLoadBalanceTime' 
-       EQUALITY integerMatch 
-       DESC 'Cutoff time in seconds, after which load balance is disabled' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27  )
-
-attributetype ( 2.16.840.1.113719.1.203.4.54
-       NAME 'dhcpFailOverPeerDN' 
-       EQUALITY distinguishedNameMatch 
-       DESC 'The DNs of Fail over peers. In case of locator object, this will be list of fail over peers in the tree. In case of Subnet and pool, it will be a single Fail Over Peer' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) 
-
-#List of all servers in the tree
-attributetype ( 2.16.840.1.113719.1.203.4.55
-       NAME 'dhcpServerDN' 
-       EQUALITY distinguishedNameMatch 
-       DESC 'List of all  DHCP Servers in the tree. Used by dhcpLocatorObject' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
-
-attributetype ( 2.16.840.1.113719.1.203.4.56
-       NAME 'dhcpComments' 
-       EQUALITY caseIgnoreIA5Match 
-       DESC 'Generic attribute that allows coments  within any DHCP object' 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-# Classes
-
-objectclass ( 2.16.840.1.113719.1.203.6.1 
-       NAME 'dhcpService' 
-       DESC 'Service object that represents the actual DHCP Service configuration. This is a container object.' 
-       SUP top 
-       MUST (cn) 
-       MAY ( dhcpPrimaryDN $ dhcpSecondaryDN $ dhcpServerDN $ dhcpSharedNetworkDN $ dhcpSubnetDN $ dhcpGroupDN $ dhcpHostDN $  dhcpClassesDN $ dhcpOptionsDN $ dhcpZoneDN $ dhcpKeyDN $ dhcpFailOverPeerDN $ dhcpStatements $dhcpComments $ dhcpOption) )
-
-objectclass ( 2.16.840.1.113719.1.203.6.2 
-       NAME 'dhcpSharedNetwork' 
-       DESC 'This stores configuration information for a shared network.' 
-       SUP top 
-       MUST cn 
-       MAY ( dhcpSubnetDN $ dhcpPoolDN $ dhcpOptionsDN $ dhcpZoneDN $ dhcpStatements $dhcpComments $ dhcpOption) X-NDS_CONTAINMENT ('dhcpService' ) )
-
-objectclass ( 2.16.840.1.113719.1.203.6.3 
-       NAME 'dhcpSubnet' 
-       DESC 'This class defines a subnet. This is a container object.' 
-       SUP top 
-       MUST ( cn $ dhcpNetMask ) 
-       MAY ( dhcpRange $ dhcpPoolDN $ dhcpGroupDN $ dhcpHostDN $ dhcpClassesDN $ dhcpLeasesDN $ dhcpOptionsDN $ dhcpZoneDN $ dhcpKeyDN $ dhcpFailOverPeerDN $ dhcpStatements $ dhcpComments $ dhcpOption ) X-NDS_CONTAINMENT ('dhcpService' 'dhcpSharedNetwork') )
-
-objectclass ( 2.16.840.1.113719.1.203.6.4 
-       NAME 'dhcpPool' 
-       DESC 'This stores configuration information about a pool.' 
-       SUP top 
-       MUST ( cn $ dhcpRange ) 
-       MAY ( dhcpClassesDN $ dhcpPermitList $ dhcpLeasesDN $ dhcpOptionsDN $ dhcpZoneDN $dhcpKeyDN $ dhcpStatements $ dhcpComments $ dhcpOption ) 
-       X-NDS_CONTAINMENT ('dhcpSubnet' 'dhcpSharedNetwork') )
-
-objectclass ( 2.16.840.1.113719.1.203.6.5 
-       NAME 'dhcpGroup' 
-       DESC 'Group object that lists host DNs and parameters. This is a container object.' 
-       SUP top 
-       MUST cn 
-       MAY ( dhcpHostDN $ dhcpOptionsDN $ dhcpStatements $ dhcpComments $ dhcpOption )
-       X-NDS_CONTAINMENT ('dhcpSubnet' 'dhcpService' ) )
-
-objectclass ( 2.16.840.1.113719.1.203.6.6 
-       NAME 'dhcpHost' 
-       DESC 'This represents information about a particular client' 
-       SUP top 
-       MUST cn 
-       MAY  (dhcpLeaseDN $ dhcpHWAddress $ dhcpOptionsDN $ dhcpStatements $ dhcpComments $ dhcpOption) 
-       X-NDS_CONTAINMENT ('dhcpService' 'dhcpSubnet' 'dhcpGroup') )
-
-objectclass ( 2.16.840.1.113719.1.203.6.7 
-       NAME 'dhcpClass' 
-       DESC 'Represents information about a collection of related clients.' 
-       SUP top 
-       MUST cn 
-       MAY (dhcpSubClassesDN $ dhcpOptionsDN $ dhcpStatements $ dhcpComments $ dhcpOption) 
-       X-NDS_CONTAINMENT ('dhcpService' 'dhcpSubnet' ) )
-
-objectclass ( 2.16.840.1.113719.1.203.6.8 
-       NAME 'dhcpSubClass' 
-       DESC 'Represents information about a collection of related classes.' 
-       SUP top 
-       MUST cn 
-       MAY (dhcpClassData $ dhcpOptionsDN $ dhcpStatements $ dhcpComments $ dhcpOption) X-NDS_CONTAINMENT 'dhcpClass' )
-
-objectclass ( 2.16.840.1.113719.1.203.6.9 
-       NAME 'dhcpOptions' 
-       DESC 'Represents information about a collection of options defined.' 
-       SUP top AUXILIARY
-       MUST cn 
-       MAY ( dhcpOption $ dhcpComments ) 
-       X-NDS_CONTAINMENT  ('dhcpService' 'dhcpSharedNetwork' 'dhcpSubnet' 'dhcpPool' 'dhcpGroup' 'dhcpHost' 'dhcpClass' ) )
-
-objectclass ( 2.16.840.1.113719.1.203.6.10 
-       NAME 'dhcpLeases' 
-       DESC 'This class represents an IP Address, which may or may not have been leased.' 
-       SUP top 
-       MUST ( cn $ dhcpAddressState ) 
-       MAY ( dhcpExpirationTime $ dhcpStartTimeOfState $ dhcpLastTransactionTime $ dhcpBootpFlag $ dhcpDomainName $ dhcpDnsStatus $ dhcpRequestedHostName $ dhcpAssignedHostName $ dhcpReservedForClient $ dhcpAssignedToClient $ dhcpRelayAgentInfo $ dhcpHWAddress ) 
-       X-NDS_CONTAINMENT ( 'dhcpService' 'dhcpSubnet' 'dhcpPool') )
-
-objectclass ( 2.16.840.1.113719.1.203.6.11 
-       NAME 'dhcpLog' 
-       DESC 'This is the object that holds past information about the IP address. The cn is the time/date stamp when the address was assigned or released, the address state at the time, if the address was assigned or released.' 
-       SUP top 
-       MUST ( cn ) 
-       MAY ( dhcpAddressState $ dhcpExpirationTime $ dhcpStartTimeOfState $ dhcpLastTransactionTime $ dhcpBootpFlag $ dhcpDomainName $ dhcpDnsStatus $ dhcpRequestedHostName $ dhcpAssignedHostName $ dhcpReservedForClient $ dhcpAssignedToClient $ dhcpRelayAgentInfo $ dhcpHWAddress $ dhcpErrorLog) 
-       X-NDS_CONTAINMENT ('dhcpLeases' 'dhcpPool' 'dhcpSubnet' 'dhcpSharedNetwork' 'dhcpService' ) )
-
-objectclass ( 2.16.840.1.113719.1.203.6.12 
-       NAME 'dhcpServer' 
-       DESC 'DHCP Server Object' 
-       SUP top AUXILIARY 
-       MUST ( cn ) 
-       MAY (dhcpServiceDN  $ dhcpLocatorDN $ dhcpVersion $ dhcpImplementation $ dhcpHashBucketAssignment $ dhcpDelayedServiceParameter $ dhcpMaxClientLeadTime $ dhcpFailOverEndpointState $ dhcpStatements $ dhcpComments $ dhcpOption) 
-       X-NDS_CONTAINMENT ('organization' 'organizationalunit' 'domain') )
-
-objectclass ( 2.16.840.1.113719.1.203.6.13 
-       NAME 'dhcpTSigKey' 
-       DESC 'TSIG key for secure dynamic updates' 
-       SUP top 
-       MUST (cn $ dhcpKeyAlgorithm $ dhcpKeySecret ) 
-       MAY ( dhcpComments ) 
-       X-NDS_CONTAINMENT ('dhcpService' 'dhcpSharedNetwork' 'dhcpSubnet') )
-
-objectclass ( 2.16.840.1.113719.1.203.6.14 
-       NAME 'dhcpDnsZone' 
-       DESC 'DNS Zone for updating leases' 
-       SUP top 
-       MUST (cn $ dhcpDnsZoneServer ) 
-       MAY (dhcpKeyDN $ dhcpComments) 
-       X-NDS_CONTAINMENT ('dhcpService' 'dhcpSharedNetwork' 'dhcpSubnet') )
-
-objectclass ( 2.16.840.1.113719.1.203.6.15 
-       NAME 'dhcpFailOverPeer' 
-       DESC 'This class defines the Fail over peer' 
-       SUP top 
-  MUST ( cn $ dhcpFailOverPrimaryServer $ dhcpFailOverSecondaryServer $ dhcpFailoverPrimaryPort $ dhcpFailOverSecondaryPort) MAY (dhcpFailOverResponseDelay  $ dhcpFailOverUnackedUpdates $ dhcpMaxClientLeadTime $ dhcpFailOverSplit $ dhcpHashBucketAssignment $ dhcpFailOverLoadBalanceTime $ dhcpComments ) 
-       X-NDS_CONTAINMENT ('dhcpService' 'dhcpSharedNetwork' 'dhcpSubnet') )
-
-objectclass ( 2.16.840.1.113719.1.203.6.16 
-       NAME 'dhcpLocator' 
-       DESC 'Locator object for DHCP configuration in the tree. There will be a single dhcpLocator object in the tree with links to all the DHCP objects in the tree' 
-       SUP top 
-       MUST ( cn ) 
-       MAY ( dhcpServiceDN $dhcpServerDN $ dhcpSharedNetworkDN $ dhcpSubnetDN $ dhcpPoolDN $ dhcpGroupDN $ dhcpHostDN $  dhcpClassesDN $ dhcpKeyDN $ dhcpZoneDN $ dhcpFailOverPeerDN $ dhcpOption $ dhcpComments) 
-       X-NDS_CONTAINMENT ('organization' 'organizationalunit' 'domain') )
-
-
diff --git a/contrib/openldap/dnszone.schema b/contrib/openldap/dnszone.schema
deleted file mode 100644 (file)
index 0714b0b..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-# A schema for storing DNS zones in LDAP
-#
-attributetype ( 1.3.6.1.4.1.2428.20.0.0  NAME 'dNSTTL'
-       DESC 'An integer denoting time to live'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.0.1 NAME 'dNSClass'
-       DESC 'The class of a resource record'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.0.2 NAME 'zoneName'
-       DESC 'The name of a zone, i.e. the name of the highest node in the zone'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.0.3 NAME 'relativeDomainName'
-       DESC 'The starting labels of a domain name'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.12 NAME 'pTRRecord'
-       DESC 'domain name pointer, RFC 1035'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.13 NAME 'hInfoRecord'
-       DESC 'host information, RFC 1035'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.14 NAME 'mInfoRecord'
-       DESC 'mailbox or mail list information, RFC 1035'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.16 NAME 'tXTRecord'
-       DESC 'text string, RFC 1035'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.18 NAME 'aFSDBRecord'
-       DESC 'for AFS Data Base location, RFC 1183'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.24 NAME 'SigRecord'
-       DESC 'Signature, RFC 2535'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.25 NAME 'KeyRecord'
-       DESC 'Key, RFC 2535'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.28 NAME 'aAAARecord'
-       DESC 'IPv6 address, RFC 1886'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.29 NAME 'LocRecord'
-       DESC 'Location, RFC 1876'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.30 NAME 'nXTRecord'
-       DESC 'non-existant, RFC 2535'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.33 NAME 'sRVRecord'
-       DESC 'service location, RFC 2782'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.35 NAME 'nAPTRRecord'
-       DESC 'Naming Authority Pointer, RFC 2915'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.36 NAME 'kXRecord'
-       DESC 'Key Exchange Delegation, RFC 2230'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.37 NAME 'certRecord'
-       DESC 'certificate, RFC 2538'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.38 NAME 'a6Record'
-       DESC 'A6 Record Type, RFC 2874'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.39 NAME 'dNameRecord'
-       DESC 'Non-Terminal DNS Name Redirection, RFC 2672'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.43 NAME 'dSRecord'
-       DESC 'Delegation Signer, RFC 3658'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.44 NAME 'sSHFPRecord'
-       DESC 'SSH Key Fingerprint, draft-ietf-secsh-dns-05.txt'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.46 NAME 'rRSIGRecord'
-       DESC 'RRSIG, RFC 3755'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.2428.20.1.47 NAME 'nSECRecord'
-       DESC 'NSEC, RFC 3755'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-objectclass ( 1.3.6.1.4.1.2428.20.3 NAME 'dNSZone'
-        SUP top STRUCTURAL
-       MUST ( zoneName $ relativeDomainName )
-        MAY ( DNSTTL $ DNSClass $
-              ARecord $ MDRecord $ MXRecord $ NSRecord $
-             SOARecord $ CNAMERecord $ PTRRecord $ HINFORecord $
-              MINFORecord $ TXTRecord $ AFSDBRecord $ SIGRecord $
-              KEYRecord $ AAAARecord $ LOCRecord $ NXTRecord $
-              SRVRecord $ NAPTRRecord $ KXRecord $ CERTRecord $
-              A6Record $ DNAMERecord $ DSRecord $ SSHFPRecord $
-              RRSIGRecord $ NSECRecord ) )
diff --git a/contrib/openldap/fai.schema b/contrib/openldap/fai.schema
deleted file mode 100644 (file)
index 5bfbcd8..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-###############################################################################
-#                                                                             #
-#            F A I - Fully automatic installation LDAP schema file            #
-#                                                                             #
-#-----------------------------------------------------------------------------#
-# Last modified: Cajus Pollmeier / 20050902                                   #
-#-----------------------------------------------------------------------------#
-#             Copyright 2005, Cajus Pollmeier <cajus@debian.org>              #
-#                             Thomas Lange <lange@debian.org>                 #
-#-----------------------------------------------------------------------------#
-# This program is free software; you can redistribute it and/or modify        #
-# it under the terms of the GNU General Public License as published by        #
-# the Free Software Foundation; either version 2 of the License, or           #
-# (at your option) any later version.                                         #
-#                                                                             #
-# This program is distributed in the hope that it will be useful,             #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
-# GNU General Public License for more details.                                #
-#                                                                             #
-# You should have received a copy of the GNU General Public License           #
-# along with this program; if not, write to the Free Software                 #
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   #
-###############################################################################
-
-
-# This schema file has dependencies to the nis.schema. Please make sure that
-# the inclusion order in your slapd.conf is correct.
-
-
-# Here's a short list of object class / attribute relationship. For a more
-# detailed description take a look at the definitions below.
-#
-# Objectclasses        | Attributes
-# -----------------------------------------------------------------------------
-# FAIclass             | cn,description,FAIclassType
-# FAIprofile           | FAIclass
-# FAIhook              | (inherit from FAIclass)
-# FAIhookEntry         | FAIscript, FAItask
-# FAIscript            | (inherit from FAIclass)
-# FAIscriptEntry       | FAIscript, FAIpriority
-# FAIvariable          | (inherit from FAIclass)
-# FAIvariableEntry     | FAIvariableContent
-# FAItemplate          | (inherit from FAIclass)
-# FAItemplateEntry     | FAItemplateFile, FAItemplatePath, FAIowner, FAImode
-# FAIpartitionTable    | (inherit from FAIclass)
-# FAIpartitionDisk     | (inherit from FAIclass)
-# FAIpartitionEntry    | FAIpartitionType, FAIpartitionNr, FAImountOptions,
-#                      | FAIfsOptions, FAIfsType, FAImountPoint,FAIpartitionSize,
-#                      | FAIpartitionFlag
-# FAIpackageList       | FAIinstallMethod, FAIpackage
-# FAIdebconfInfo       | FAIvariable, FAIvariableContent, FAIvariableType
-# FAIobject            | FAIclass, FAIstatus, macAddress
-# FAIrepository        | FAIdebianMirror, FAIdebianRelease, FAIdebianSection
-# FAIrepositoryServer  | FAIrepository
-#
-# Rem.: Except of FAIdebconfInfo and FAIobject, all object classes are inherited
-#       from FAIclass, so ALL cn's MUST be unique in your tree.
-
-
-##
-## Attribute definitions (allocated from the GONICUS oid space)
-##
-
-# Name       : FAIclass
-# Description: Notes which FAI class name(s) are used in an FAI object
-#              or in profile definitions. No unicode here, maximum
-#              length is set to 64 characters.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.1 NAME 'FAIclass'
-               DESC 'Storage for FAI class names'
-               EQUALITY caseExactMatch
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64})
-
-# Name       : FAIpriority
-# Description: Notes which priority scripts or profiles entries get. It is used
-#              by FAI to generate a propper class list during the bootstrap
-#              process. This is an unsigned integer value. 
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.2 NAME 'FAIpriority'
-               DESC 'Storage for FAI priorities'
-               EQUALITY integerMatch
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
-
-# Name       : FAIpartitionType
-# Description: As the name says, we store the type of a (hard-disk) partition
-#              here. Type can be one of "primary" or "secondary". We did not
-#              make this bool because there may be changes to the FAI partitioner
-#              which we can't handle then. The maximum length is set to 16
-#              characters.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.3 NAME 'FAIpartitionType'
-               DESC 'Storage for FAI partition types'
-               EQUALITY caseExactMatch
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{16} SINGLE-VALUE)
-
-# Name       : FAIpartitionNr
-# Description: We use this value to store the device entries like "disk1" or
-#              "sda8" with this attribute. Currently the storage is without the
-#              leading "/dev/".
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.4 NAME 'FAIpartitionNr'
-               DESC 'Storage for FAI partition devices'
-               EQUALITY caseExactIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAImountOptions
-# Description: We use this value to store special mount options for partitions.
-#              For example some people tend to have /usr mounted as read-only.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.5 NAME 'FAImountOptions'
-               DESC 'Storage for FAI partition mount options'
-               EQUALITY caseExactIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAImountPoint
-# Description: Simply the mountpoint like found in the fstab. Examples are
-#              '/usr', '/' and '/home'.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.6 NAME 'FAImountPoint'
-               DESC 'Storage for FAI partition mount points'
-               EQUALITY caseExactIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIfsOptions
-# Description: In some cases you might want to influence the filesystem
-#              generation commands by adding flags for larger inode tables, etc.
-#              FAIfsOptions keeps the flags that are used by the mkfs workers.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.7 NAME 'FAIfsOptions'
-               DESC 'Storage for FAI partition generation options'
-               EQUALITY caseExactIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIfsType
-# Description: Keeps the type of the filessytem a partition gets formatted with.
-#              Examples are 'ext3', 'xfs', etc. Please refer to the FAI manual
-#              for valid types.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.8 NAME 'FAIfsType'
-               DESC 'Storage for FAI partition types'
-               EQUALITY caseExactMatch
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{16} SINGLE-VALUE)
-
-# Name       : FAIscript
-# Description: Store multiline text, mostly used for scripts and hooks. 
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.9 NAME 'FAIscript'
-               DESC 'General storage field for multiline text aka scripts'
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE)
-
-# Name       : FAItask
-# Description: Assign a hook to a special task. You can use it i.e. to alter
-#              partition tables, etc. The FAI manual hold a list of valid
-#              tasks for you.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.10 NAME 'FAItask'
-               DESC 'Note for which FAI tasks a hook is made for'
-               EQUALITY caseIgnoreIA5Match
-               SUBSTR caseIgnoreIA5SubstringsMatch
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIvariable
-# Description: Keeps the name of a debconf template variable. The value is
-#              stored inside of FAIvariableContent, the type inside
-#              FAIvariableType.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.11 NAME 'FAIvariable'
-               DESC 'Store debconf template variable names'
-               EQUALITY caseIgnoreIA5Match
-               SUBSTR caseIgnoreIA5SubstringsMatch
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIvariableContent
-# Description: Keeps the content of a debconf template variable. See
-#              FAIvariable for more informations.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.12 NAME 'FAIvariableContent'
-               DESC 'Store debconf template variable contents'
-               EQUALITY caseIgnoreIA5Match
-               SUBSTR caseIgnoreIA5SubstringsMatch
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIvariableType
-# Description: Keeps the type of a debconf template variable. See
-#              FAIvariable for more informations.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.13 NAME 'FAIvariableType'
-               DESC 'Store debconf template variable type'
-               EQUALITY caseIgnoreIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIinstallMethod
-# Description: Keeps a per package setting on how packages should be
-#              installed. This is the normal line you'd specify in
-#              our ordinary package lists.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.14 NAME 'FAIinstallMethod'
-               DESC 'Store debian package installation flag'
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIpackage
-# Description: Keeps an entry of a package list. Each FAIpackage object
-#              may be a parent for FAIdebconfInfo objects.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.15 NAME 'FAIpackage'
-               DESC 'Store debian package name'
-               EQUALITY caseIgnoreIA5Match
-               SUBSTR caseIgnoreIA5SubstringsMatch
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-# Name       : FAItemplateFile
-# Description: Keeps complete template files that are copied to the
-#              freshly installed system later on. The tasks path is
-#              stored in FAItemplatePath. Use ;binary for this attribute.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.16 NAME 'FAItemplateFile'
-               DESC 'Store complete template files'
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE)
-
-# Name       : FAItemplatePath
-# Description: Keeps the path used for template files. See FAItemplateFile
-#              for more informations.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.17 NAME 'FAItemplatePath'
-               DESC 'Store template file storage path'
-               EQUALITY caseIgnoreIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIowner
-# Description: Keeps the owner used for template files. Put in the unix
-#              way like user.group.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.18 NAME 'FAIowner'
-               DESC 'Store template file storage path'
-               EQUALITY caseIgnoreIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAImode
-# Description: Keeps the file mode used for template files. Put in the unix
-#              way like 775.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.19 NAME 'FAImode'
-               DESC 'Store template file storage path'
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE)
-               
-# Name       : FAIstatus
-# Desrciption: Normally the fai daemon should set the status flag to the
-#             current status. Possible states are:
-#             * update-needed
-#             * update-running
-#             * update-failed
-#             * update-ok
-#             * install-running
-#             * install-failed
-#             * install-ok
-#             Additional informations can be taken from the log files if
-#             some machine is set to -failed.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.20 NAME 'FAIstatus'
-               DESC 'Store FAI progress status'
-               EQUALITY caseIgnoreIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIpackagelistDependency
-# Description: This field stores dependency informations for package lists.
-#              It is used to install i.e. ati specific packages when the
-#              hardware detection detects ATI gfx cards.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.21 NAME 'FAIpackagelistDependency'
-               DESC 'Store package lists where we depend from'
-               EQUALITY caseIgnoreIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIpartitionSize
-# Description: Store a size or a size range for partitions. I.e. 50,
-#              50-200.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.22 NAME 'FAIpartitionSize'
-               DESC 'Store size range for partition size'
-               EQUALITY caseIgnoreIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIpartitionFlags
-# Description: Optionally this flag contains the "preserve" keyword, in
-#              order to influence partitioning.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.23 NAME 'FAIpartitionFlags'
-               DESC 'Optional flags like "preserve"'
-               EQUALITY caseIgnoreIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIdebianMirror
-# Description: Used for bootstrap sources.list settings. It contains
-#              the mirror server url.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.24 NAME 'FAIdebianMirror'
-               DESC 'TODO'
-               EQUALITY caseIgnoreIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIdebianRelease
-# Description: Used for bootstrap sources.list settings. It contains
-#              the release.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.25 NAME 'FAIdebianRelease'
-               DESC 'TODO'
-               EQUALITY caseIgnoreIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Name       : FAIdebianSection
-# Description: Used for bootstrap sources.list settings. It contains
-#              the section. Multiple Sections get appended.
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.26 NAME 'FAIdebianSection'
-               DESC 'TODO'
-               EQUALITY caseIgnoreIA5Match
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-# Name       : FAIrepository
-# Description: Used to store repository settings 
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.27 NAME 'FAIrepository'
-               DESC 'TODO'
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-               
-# Name       : FAIstate
-# Description: Used to store repository state (branched/freezed)
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.28 NAME 'FAIstate'
-               DESC 'TODO'
-                EQUALITY caseIgnoreIA5Match
-                SUBSTR caseIgnoreIA5SubstringsMatch
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-# Name       : FAIrelease
-# Description: Used to store the release
-attributetype ( 1.3.6.1.4.1.10098.1.1.5.29 NAME 'FAIrelease'
-               DESC 'TODO'
-               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-##
-## Object class definitions (allocated from the GONICUS oid space)
-##
-
-# Name       : FAIclass
-# Description: FAIclass is the basic container wich includes a
-#              common name and a description.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.1 NAME 'FAIclass'
-       SUP top STRUCTURAL
-       DESC 'Generic class parent for FAI objects'
-       MUST ( cn ) MAY  ( FAIstate $ description ) )
-
-# Name       : FAIprofile
-# Description: FAIprofile which bundles a set of FAIclass entries
-#              like FAIpartition and FAIpackageList. It is used
-#              to simplify administration tasks for so called junior
-#              administrators.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.2 NAME 'FAIprofile'
-       SUP top AUXILIARY
-       DESC 'FAI profile container for multiple class objects' 
-       MUST ( cn $ FAIclass ) MAY  ( FAIstate $ description ) )
-
-# Name       : FAIpartitionTable
-# Description: Each installation profile should contain a partition
-#              table in order to perform well. FAIpartitionTable is
-#              a container for partition entries.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.3 NAME 'FAIpartitionTable'
-       SUP top AUXILIARY
-       DESC 'Stores FAI partition tables'
-       MUST ( cn ) MAY  ( FAIstate $ description ) )
-
-# Name       : FAIpartitionDisk
-# Description: Each installation profile should contain a partition
-#              table in order to perform well. FAIpartitionTable is
-#              a container for partition entries.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.4 NAME 'FAIpartitionDisk'
-       SUP top AUXILIARY
-       DESC 'Stores FAI partition tables' 
-       MUST ( cn ) MAY  ( FAIstate $ description ) )
-
-# Name       : FAIpartitionEntry
-# Description: This object defines a single partition entry for the
-#              FAI partitioner.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.5 NAME 'FAIpartitionEntry'
-       SUP top AUXILIARY
-       DESC 'One partition table entry'
-       MUST ( FAIpartitionType $ FAIpartitionNr $ FAIfsType $
-              FAImountPoint $ FAIpartitionSize $ cn )
-       MAY  ( FAImountOptions $ FAIfsOptions $ FAIpartitionFlags $
-              description $ FAIstate ) )
-
-# Name       : FAIhook
-# Description: Container for hooks
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.6 NAME 'FAIhook'
-       SUP top AUXILIARY
-       DESC 'Stores FAI partition tables'
-       MUST ( cn ) MAY  ( FAIstate $ description ) )
-
-# Name       : FAIhookEntry
-# Description: Hooks are stored with their FAI task inside the
-#              FAIhook object.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.7 NAME 'FAIhookEntry'
-       SUP top AUXILIARY
-       DESC 'FAI hook storage'
-       MUST ( cn $ FAIscript $ FAItask ) MAY ( FAIstate $ description ) )
-
-# Name       : FAIscriptEntry
-# Description: Container for scripts
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.8 NAME 'FAIscriptEntry'
-       SUP top AUXILIARY
-       DESC 'FAI script storage'
-       MUST ( cn $ FAIscript $ FAIpriority ) MAY ( FAIstate $ description ) )
-
-# Name       : FAIscript
-# Description: Hooks and scripts are somewhat similar.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.9 NAME 'FAIscript'
-       SUP top AUXILIARY
-       DESC 'FAI script storage'
-       MUST ( cn ) MAY  ( FAIstate $ description ) )
-
-# Name       : FAIvariable
-# Description: Store a set of variables in this container.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.10 NAME 'FAIvariable'
-       SUP top AUXILIARY
-       DESC 'Stores FAI variables sub entries'
-       MUST ( cn ) MAY  ( FAIstate $ description ) )
-
-# Name       : FAIvariableEntry
-# Description: Stores a single variable.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.11 NAME 'FAIvariableEntry'
-       SUP top AUXILIARY
-       DESC 'Stores single variable entries'
-       MUST ( cn $ FAIvariableContent ) MAY ( FAIstate $ description ) )
-
-# Name       : FAIpackagelist
-# Description: Stores a complete package list and is container
-#              for several FAIdebconfInfo scripts
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.12 NAME 'FAIpackageList'
-       SUP top AUXILIARY
-       DESC 'Stores complete package lists'
-       MUST ( cn $ FAIpackage ) MAY ( FAIpackagelistDependency $ FAIinstallMethod $ description $ FAIstate ) )
-
-# Name       : FAItemplate
-# Description: Container for template objects.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.13 NAME 'FAItemplate'
-       SUP top AUXILIARY
-       DESC 'Container for template objects' 
-       MUST ( cn ) MAY  ( FAIstate $ description ) )
-
-# Name       : FAItemplateEntry
-# Description: Stores FAI templates and the corresponding path.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.14 NAME 'FAItemplateEntry'
-       SUP top AUXILIARY
-       DESC 'Stores real file templates'
-       MUST ( cn $ FAItemplateFile $ FAItemplatePath $ FAIowner $ FAImode ) 
-       MAY ( FAIstate $ description ) )
-       
-# Name       : FAIdebconfInfo
-# Description: Stores debconf information like shown in
-#              debconf-getselections.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.15 NAME 'FAIdebconfInfo'
-       SUP top STRUCTURAL
-       DESC 'Stores debconf informations for single packages'
-       MUST ( FAIpackage $ FAIvariable $ FAIvariableType ) MAY ( FAIvariableContent $ FAIstate ) )
-
-# Name       : FAIobject
-# Description: Marks objects to have a set of FAI classes.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.16 NAME 'FAIobject'
-       SUP top AUXILIARY
-       DESC 'Marks an object as an FAI object.'
-       MAY ( FAIstate $ FAIstatus $ FAIclass $ FAIdebianMirror $ macAddress) )
-
-# Name       : FAIrepository
-# Description: Marks objects to have a set of FAI classes.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.17 NAME 'FAIrepository'
-       SUP top AUXILIARY
-       DESC 'Provides per object repository informations.'
-       MUST ( FAIdebianRelease $ FAIdebianSection ) MAY ( FAIdebianMirror ) )
-
-# Name       : FAIrepositoryServer
-# Description: FAIrepositoryServer stores information about repository settings.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.18 NAME 'FAIrepositoryServer'
-       SUP top AUXILIARY
-       DESC 'Provides repository informations.'
-       MAY ( FAIrepository ) )
-
-# Name       : FAIbranch
-# Description: FAIbranch stores information about the state of a set of FAI classes.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.19 NAME 'FAIbranch'
-       SUP top AUXILIARY
-       DESC 'Provides information for versioning.'
-       MAY ( FAIstate ) )
-
-# Name       : FAIreleaseTag
-# Description: FAIreleaseTag stores information about the fai release of an object.
-objectclass (1.3.6.1.4.1.10098.1.2.1.40.20 NAME 'FAIreleaseTag'
-       SUP top AUXILIARY
-       DESC 'Provides information for versioning.'
-       MAY ( FAIrelease ) )
-
-### END of FAI schema file
diff --git a/contrib/openldap/glpi.schema b/contrib/openldap/glpi.schema
deleted file mode 100644 (file)
index 6028bfd..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-## schema file for OpenLDAP 2.x
-## Schema for storing glpi User Configuration in LDAP
-## OIDs are owned by OpenSides
-##
-#
-# $Id: glpi.schema,v 1.1 2005/11/02 16:48:16 benoit Exp $
-#
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.4.1 NAME 'glpiAccountLogin'
-        DESC 'glpi Account Login'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-#
-# all objectclass 
-#
-
-objectclass ( 1.3.6.1.4.1.22262.1.1.2.4.1 NAME 'glpiAccount' SUP top AUXILIARY
- DESC 'glpi Account'
- MAY ( glpiAccountLogin  ))
\ No newline at end of file
diff --git a/contrib/openldap/goconfig.schema b/contrib/openldap/goconfig.schema
deleted file mode 100644 (file)
index 64fbf84..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-## 
-##
-## goconfig.schema - Needed by the GONICUS System Administator
-##
-## Version 030719
-##
-##
-## Maintainer:         Lars Scheiter   (scheiter@GONICUS.de)
-##                     Cajus Pollmeier (pollmeier@GONICUS.de)
-##
-##
-
-
-# Attributes for the GONICUS server extensions
-
-# Syntax: regex
-attributetype ( 1.3.6.1.4.1.10098.1.1.10.8 NAME 'goLogcheckIgnoreMatch'
-       DESC 'Contains a regular expression to ignore'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-# Syntax: regex
-attributetype ( 1.3.6.1.4.1.10098.1.1.10.9 NAME 'goLogcheckMatch'
-       DESC 'Contains a regular expression to ignore'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-# Syntax: value
-attributetype ( 1.3.6.1.4.1.10098.1.1.10.10 NAME 'goLogcheckCategory'
-       DESC 'Contains a regular expression to ignore'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-##
-##             Objectclasses
-##
-
-# Logging object
-objectclass (1.3.6.1.4.1.10098.1.2.2.2 NAME 'goLogcheckObject' SUP top STRUCTURAL
-       DESC 'Logcheck rule container (v2.4)'
-       MUST ( cn $ goLogcheckCategory )
-       MAY  ( goLogcheckMatch $ goLogcheckIgnoreMatch ))
-
diff --git a/contrib/openldap/gofax.schema b/contrib/openldap/gofax.schema
deleted file mode 100644 (file)
index b949016..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-## 
-## Gonicus Attribute and Objectclass Definitions for GOfax
-##
-## Version: 030403
-##
-##     Maintained by:  Lars Scheiter (scheiter@GONICUS.de)
-##
-
-# Attributes 
-attributetype ( 1.3.6.1.4.1.10098.1.1.7.1 NAME 'goFaxDeliveryMode'
-       DESC 'goFax delivery mode is defined here'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.7.2 NAME 'goFaxPrinter'
-       DESC 'defines which printer is used to print a fax'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.7.3 NAME 'goFaxDivertNumber'
-       DESC 'for fax diversion services'
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.22
-       SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.7.4 NAME 'goFaxLanguage'
-       DESC 'preferred language for the users goFax entry'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.7.5 NAME 'goFaxFormat'
-       DESC 'defines the fileformat for mailattachments'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.7.6 NAME 'goFaxRBlocklist'
-       DESC 'defines faxnumbers the user is not allowed to get fax from'
-       EQUALITY caseExactIA5Match 
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.7.8 NAME 'goFaxSBlocklist'
-       DESC 'defines faxnumbers the user is not allowed to fax to'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.7.7 NAME 'goFaxRBlockgroups'
-       DESC 'defines groups of receive blocklists the user belongs to'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.7.9 NAME 'goFaxSBlockgroups'
-       DESC 'defines groups of sender blocklists the user belongs to'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.7.10 NAME 'goFaxIsEnabled'
-       DESC 'This account is enabled or not'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.7.11 NAME 'facsimileAlternateTelephoneNumber'
-       EQUALITY telephoneNumberMatch
-    SUBSTR telephoneNumberSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32} )
-
-# objectclass 
-objectclass (1.3.6.1.4.1.10098.1.2.1.11 NAME 'goFaxAccount' SUP top AUXILIARY
-       DESC 'goFax Account objectclass (v1.0.4)'
-       MUST ( goFaxDeliveryMode $ facsimileTelephoneNumber $ uid $ goFaxIsEnabled )
-       MAY ( goFaxPrinter $ goFaxDivertNumber $ goFaxLanguage $ goFaxFormat $ goFaxRBlocklist $ 
-             goFaxRBlockgroups $ goFaxSBlocklist $ goFaxSBlockgroups $ mail $
-             facsimileAlternateTelephoneNumber ))
-
-objectclass (1.3.6.1.4.1.10098.1.2.1.12 NAME 'goFaxSBlock'
-       DESC 'goFax send blocklist groups (v1.0.4)'
-       MUST ( cn )
-       MAY ( goFaxSBlocklist $ description ))
-
-objectclass (1.3.6.1.4.1.10098.1.2.1.13 NAME 'goFaxRBlock'
-       DESC 'goFax receive blocklist groups (v1.0.4)'
-       MUST ( cn )
-       MAY ( goFaxRBlocklist $ description ))
-
diff --git a/contrib/openldap/gofirewall.schema b/contrib/openldap/gofirewall.schema
deleted file mode 100644 (file)
index 3405b9d..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-##
-##
-## gofirewall.schema - Used to store some firewalling data
-##
-##
-## Version 030403
-##
-##
-## Maintainer: Cajus Pollmeier (pollmeier@GONICUS.de)
-##             Lars Scheiter   (scheiter@GONICUS.de)
-##
-##
-
-
-# Attributes for FireWall Configs
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.1 NAME 'FWdevice'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.2 NAME 'FWtype'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.3 NAME 'FWaction'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.4 NAME 'FWtable'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.5 NAME 'FWsource'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.6 NAME 'FWdest'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.7 NAME 'FWservice'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.8 NAME 'FWprotocol'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.10 NAME 'FWlog'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.11 NAME 'FWnetwork'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.12 NAME 'FWhost'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.14 NAME 'FWproto'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.15 NAME 'FWlist'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.16 NAME 'FWdisabled'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.4.17 NAME 'FWid'
-       DESC 'Firewall definitions'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-##
-##     Objectclasses
-##
-
-# ObjectClasses for Firewall Setups
-objectclass (1.3.6.1.4.1.10098.1.2.1.6 NAME 'FWRule'
-       DESC 'Firewall rule definition' SUP top AUXILIARY
-       MUST ( cn $ FWtype )
-       MAY ( FWdevice $ FWaction $ FWtable $ FWsource $ FWdest $ FWservice $ FWprotocol $
-               FWtable $ FWlog $ FWid )) 
-
-objectclass (1.3.6.1.4.1.10098.1.2.1.7 NAME 'FWGroup'
-       DESC 'Firewall group definition' SUP top AUXILIARY
-       MUST ( cn )
-       MAY ( FWnetwork $ FWhost $ FWservice $ FWproto $ FWid))
-
-objectclass (1.3.6.1.4.1.10098.1.2.1.8 NAME 'FWRuleSet'
-       DESC 'Firewall ruleset definition' SUP top AUXILIARY
-       MUST ( cn )
-       MAY ( FWlist $ FWdisabled $ FWid))
-
diff --git a/contrib/openldap/gofon.schema b/contrib/openldap/gofon.schema
deleted file mode 100644 (file)
index b16a7fe..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-## 
-## Gonicus Attribute and Objectclass Definitions for GOfon
-##
-##     Maintained by:  Cajus Pollmeier <pollmeier@gonicus.de>
-##
-
-# Attributes 
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.1 NAME 'goFonDeliveryMode'
-       DESC 'GOFon delivery mode is defined here'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.2 NAME 'goFonForwarding'
-       DESC 'defines which phone numbers get the next call'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.3 NAME 'goFonFormat'
-       DESC 'defines voicemail delivery format'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.4 NAME 'goFonHardware'
-       DESC 'defines voicemail delivery format'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.5 NAME 'goFonPIN'
-       DESC 'defines voicemail delivery format'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.6 NAME 'goFonType'
-       DESC 'sets the sip.conf type parameter'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.7 NAME 'goFonDmtfMode'
-       DESC 'sets the sip.conf dmtfmode parameter'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.8 NAME 'goFonHost'
-       DESC 'sets the sip.conf host parameter'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.9 NAME 'goFonDefaultIP'
-       DESC 'sets the sip.conf defaultip parameter'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.10 NAME 'goFonQualify'
-       DESC 'sets the sip.conf qualify parameter'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.11 NAME 'goFonAuth'
-       DESC 'sets the sip.conf auth parameter'
-       EQUALITY caseExactMatch
-       SUBSTR caseExactSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.12 NAME 'goFonSecret'
-       DESC 'sets the sip.conf secret parameter'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.13 NAME 'goFonInkeys'
-       DESC 'sets the sip.conf inkeys parameter'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.14 NAME 'goFonOutkey'
-       DESC 'sets the sip.conf outkey parameter'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.15 NAME 'goFonTrunk'
-       DESC 'sets the sip.conf trunk parameter'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.16 NAME 'goFonAccountCode'
-       DESC 'sets the sip.conf accountcode parameter'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.17 NAME 'goFonMSN'
-       DESC 'sets the sip.conf msn parameter'
-       EQUALITY telephoneNumberMatch
-       SUBSTR telephoneNumberSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32} SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.18 NAME 'goFonPermit'
-       DESC 'sets the sip.conf permit parameter'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.19 NAME 'goFonDeny'
-       DESC 'sets the sip.conf deny parameter'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.20 NAME 'goFonMacroVisible'
-       DESC 'Triggers if the macro is visible for users'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.21 NAME 'goFonMacroContent'
-       DESC 'Holds the macro'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.22 NAME 'goFonMacroParameter'
-       DESC 'Holds the macro parameter definitions'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.23 NAME 'goFonMacro'
-    DESC 'Holds the macro parameter definitions'
-    EQUALITY caseExactMatch
-    SUBSTR caseExactSubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.24 NAME 'goFonTimeOut'
-    DESC 'Holds the queue goFonTimeOut definitions'
-    EQUALITY integerMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.25 NAME 'goFonMaxLen'
-    DESC 'Holds the queue goFonMaxLen definitions'
-    EQUALITY integerMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.26 NAME 'goFonAnnounceFrequency'
-    DESC 'Holds the queue goFonAnnounceFrequency definitions'
-    EQUALITY integerMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.27 NAME 'goFonDialOption'
-    DESC 'Holds the queue goFonDialOption definitions'
-    EQUALITY caseExactMatch
-    SUBSTR caseExactSubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{16} SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.28 NAME 'goFonMusiconHold'
-    DESC 'Holds the queue goFonMusiconHold definitions'
-    EQUALITY caseExactIA5Match
-    SUBSTR caseExactIA5SubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.29 NAME 'goFonWelcomeMusic'
-    DESC 'Holds the queue goFonWelcomeMusic definitions'
-    EQUALITY caseExactIA5Match
-    SUBSTR caseExactIA5SubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.30 NAME 'goFonQueueReportHold'
-    DESC 'Holds the queue goFonQueueReportHold definitions'
-    EQUALITY caseExactIA5Match
-    SUBSTR caseExactIA5SubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.31 NAME 'goFonQueueYouAreNext'
-    DESC 'Holds the queue goFonQueueYouAreNext definitions'
-    EQUALITY caseExactIA5Match
-    SUBSTR caseExactIA5SubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.32 NAME 'goFonQueueThereAre'
-    DESC 'Holds the queue goFonQueueThereAre definitions'
-    EQUALITY caseExactIA5Match
-    SUBSTR caseExactIA5SubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.33 NAME 'goFonQueueCallsWaiting'
-    DESC 'Holds the queue goFonQueueCallsWaiting definitions'
-    EQUALITY caseExactIA5Match
-    SUBSTR caseExactIA5SubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.34 NAME 'goFonQueueThankYou'
-    DESC 'Holds the queue goFonQueueThankYou definitions'
-    EQUALITY caseExactIA5Match
-    SUBSTR caseExactIA5SubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.35 NAME 'goFonQueueMinutes'
-    DESC 'Holds the queue goFonQueueMinutes definitions'
-    EQUALITY caseExactIA5Match
-    SUBSTR caseExactIA5SubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.36 NAME 'goFonQueueSeconds'
-    DESC 'Holds the queue goFonQueueSeconds definitions'
-    EQUALITY caseExactIA5Match
-    SUBSTR caseExactIA5SubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.37 NAME 'goFonQueueLanguage'
-    DESC 'Holds the queue goFonLanguage definitions'
-    EQUALITY caseExactIA5Match
-    SUBSTR caseExactIA5SubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.38 NAME 'goFonQueueStrategy'
-    DESC 'Holds the queue goFonStrategy definitions'
-    EQUALITY caseExactIA5Match
-    SUBSTR caseExactIA5SubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.39 NAME 'goFonQueueAnnounceHoldtime'
-    DESC 'Holds the queue goFonAnnounceHoldtime definitions'
-    EQUALITY caseExactMatch
-    SUBSTR caseExactSubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4} SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.40 NAME 'goFonQueueAnnounce'
-    DESC 'Holds the queue goFonAnnounce definitions'
-    EQUALITY caseExactIA5Match
-    SUBSTR caseExactIA5SubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.41 NAME 'goFonQueueRetry'
-    DESC 'Holds the queue goFonRetry definitions'
-       EQUALITY integerMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.42 NAME 'goFonQueueLessThan'
-    DESC 'Holds the queue goFonQueueLessThan definitions'
-    EQUALITY caseExactIA5Match
-    SUBSTR caseExactIA5SubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.43 NAME 'goFonConferenceOption'
-    DESC 'Holds the queue goFonConferenceOptions definitions'
-    EQUALITY caseExactMatch
-    SUBSTR caseExactSubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{16} SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.44 NAME 'goFonConferenceTimeOut'
-    DESC 'Holds the queue goFonConferenceTimeOut definitions'
-    EQUALITY integerMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.45 NAME 'goFonConferenceOwner'
-    DESC 'Holds the queue goFonConferenceOwner definitions'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.46 NAME 'goFonVoicemailPIN'
-       DESC 'defines voicemail delivery format'
-       EQUALITY caseExactIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.13.47 NAME 'goFonHomeServer'
-       DESC 'defines voicemail delivery format'
-       EQUALITY caseExactMatch
-       SUBSTR caseExactSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
-
-# objectclass 
-objectclass (1.3.6.1.4.1.10098.1.2.3.11 NAME 'goFonAccount' SUP top AUXILIARY
-       DESC 'GOFon Account objectclass (v1.0)'
-       MUST ( goFonDeliveryMode $ telephoneNumber $ uid )
-       MAY ( goFonFormat $ goFonForwarding $ goFonHardware $ goFonPIN $ goFonVoicemailPIN $ goFonMacro $ goFonHomeServer ))
-
-objectclass (1.3.6.1.4.1.10098.1.2.3.12 NAME 'goFonHardware' SUP top STRUCTURAL
-       DESC 'defines a telephone (v1.0)'
-       MUST ( cn $ macAddress $ ipHostNumber )
-       MAY (description $ goFonType $ goFonDmtfMode $ goFonHost $ goFonDefaultIP $
-                goFonQualify $ goFonAuth $ goFonSecret $ goFonInkeys $ goFonOutkey $
-                goFonTrunk $ goFonAccountCode $ goFonMSN $ goFonPermit $ goFonDeny ) )
-
-objectclass (1.3.6.1.4.1.10098.1.2.3.13 NAME 'goFonPickupGroup' SUP top AUXILIARY
-       DESC 'Additive for posixGroups (v1.0)'
-       MUST ( cn $ gidNumber ) )
-
-objectclass (1.3.6.1.4.1.10098.1.2.3.14 NAME 'goFonMacro' SUP top STRUCTURAL
-       DESC 'Macro definitions for asterisk machines (v1.0)'
-       MUST ( cn ) 
-       MAY ( goFonMacroVisible $ displayName $ goFonMacroContent $ description $
-                 goFonMacroParameter ))
-
-objectclass (1.3.6.1.4.1.10098.1.2.3.15 NAME 'goFonQueue' SUP top AUXILIARY
-       DESC 'Queue definitions for asterisk machines (v1.0)'
-       MUST ( cn ) 
-       MAY ( goFonTimeOut $ goFonMaxLen $ goFonAnnounceFrequency $ goFonDialOption $
-                 goFonMusiconHold $ goFonWelcomeMusic $ goFonQueueReportHold $
-                 goFonQueueYouAreNext $ goFonQueueThereAre $ goFonQueueCallsWaiting $
-                 goFonQueueThankYou $ goFonQueueMinutes $ goFonQueueSeconds $ telephoneNumber $
-                 goFonQueueLanguage $ goFonQueueStrategy $ goFonQueueAnnounceHoldtime $ goFonQueueAnnounce $
-                 goFonQueueRetry $ goFonQueueLessThan $ goFonHomeServer ))
-
-objectclass (1.3.6.1.4.1.10098.1.2.3.16 NAME 'goFonConference' SUP top STRUCTURAL
-       DESC 'Conference definitions for asterisk machines (v1.0)'
-       MUST ( cn ) 
-       MAY ( description $ goFonConferenceOption $ goFonConferenceTimeout $ goFonPIN $
-                 goFonConferenceOwner $ telephoneNumber $ goFonHomeServer))
-
diff --git a/contrib/openldap/gosa+samba3.schema b/contrib/openldap/gosa+samba3.schema
deleted file mode 100644 (file)
index 2016066..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-##
-## Needed attributes for GOsa (GONICUS System Administrator)
-##
-## Version 030303
-##
-## Maintainer: Cajus Pollmeier (pollmeier@GONICUS.de)
-##
-
-
-# Attributes
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.1 NAME 'gosaSubtreeACL'
-        DESC 'GOsa acl entry'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.2 NAME 'gosaUser'
-        DESC 'GOsa user'
-        EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.3 NAME 'gosaObject'
-        DESC 'GOsa object'
-        EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.4 NAME 'gosaMailServer'
-        DESC 'Specify users main mail server'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.5 NAME 'gosaMailQuota'
-        DESC 'GOsa quota definitions'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.6 NAME 'gosaMailAlternateAddress'
-        DESC 'Additional mail addresses where the user is reachable'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.7 NAME 'gosaMailForwardingAddress'
-        DESC 'Addresses where to forward mail to'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.8 NAME 'gosaMailMaxSize'
-        DESC 'Block mails bigger than this value'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.9 NAME 'gosaSpamSortLevel'
-        DESC 'Spamassassins hits'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.10 NAME 'gosaSpamMailbox'
-        DESC 'Where to put spam'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.11 NAME 'gosaVacationMessage'
-        DESC 'Text to display in case of vacation'
-        EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.12 NAME 'gosaMailDeliveryMode'
-        DESC 'What to do with mails'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.13 NAME 'gosaDefaultPrinter'
-        DESC 'Defines a default printer a user owns'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.14 NAME 'gosaDefaultLanguage'
-        DESC 'Defines the default language for a user'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.15 NAME 'gosaHostACL'
-        DESC 'Defines the places where users can login'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.16 NAME 'gosaService'
-        DESC 'Defines services a certain host can provide'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.17 NAME 'gosaProxyID'
-        DESC 'Defines the proxy user id used, needed for some filters'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.18 NAME 'gosaProxyAcctFlags'
-        DESC 'Proxy Account Flags'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.19 NAME 'gosaProxyWorkingStart'
-        DESC 'Specifies the beginning of work in minutes, relative to 00:00'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.20 NAME 'gosaProxyWorkingStop'
-        DESC 'Specifies the end of work in minutes, relative to 00:00'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.21 NAME 'gosaApplicationName'
-        DESC 'Specifies the name of an application to be shown up on users desktop'
-        EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.22 NAME 'gosaApplicationExecute'
-        DESC 'Specifies the executable path of an application'
-        EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.23 NAME 'gosaApplicationFlags'
-        DESC 'Specifies the application flags G(roup only), D(esktop), M(enu)'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.31 NAME 'gosaApplicationCategory'
-       DESC 'Store application parameters'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.24 NAME 'gosaApplicationIcon'
-        DESC 'Keeps the application icon in png format'
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.28)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.25 NAME 'gosaSharedFolderTarget'
-        DESC 'Keeps the target of cyrus shared folders'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.26 NAME 'gosaMemberApplication'
-        DESC 'Like memberUid, just for applications'
-        EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.27 NAME 'gosaApplicationParameter'
-        DESC 'Store application parameters'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.28 NAME 'gosaProxyQuota'
-        DESC 'Specifies the amount of data a user may surf in a defined period of time'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.29 NAME 'gosaProxyQuotaPeriod'
-        DESC 'Specifies period of time where the counter is been reseted'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.30 NAME 'gosaGroupObjects'
-        DESC 'Takes a list of all object types that are in a gosaGroupOfNames'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.32 NAME 'gosaApplicationMimeType'
-       DESC 'Takes a list of relevant mime-type|priority settings'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.33 NAME 'gosaUnitTag'
-        DESC 'Takes a list of relevant mime-type|priority settings'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.34 NAME 'gosaAclTemplate'
-        DESC 'Takes ACL entries for gosaRoles'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.35 NAME 'gosaAclEntry'
-        DESC 'Takes ACL entries for gosaRoles'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.36 NAME 'gosaSnapshotType'
-        DESC 'Takes either undo or snapshot'
-        EQUALITY caseIgnoreMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.37 NAME 'gosaSnapshotTimestamp'
-        DESC 'Unix timestamp of snapshot'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.38 NAME 'gosaSnapshotDN'
-        DESC 'Original DN of saved object'
-        EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.39 NAME 'gosaSnapshotData'
-        DESC 'Original DN of saved object'
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.40 NAME 'gosaSetting'
-        DESC 'Original DN of saved object'
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.41 NAME 'gosaVacationStart'
-        DESC 'Timestamp for enabling current vacation message'
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.42 NAME 'gosaVacationStop'
-        DESC 'Timestamp for switching off current vacation message'
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.6.2 NAME 'academicTitle'
-        DESC 'Field to represent the academic title'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.15305.2.1 NAME ( 'gender' 'sex' )
-        DESC    'Gender: M for male, F for female'
-        EQUALITY caseIgnoreIA5Match
-        SYNTAX  1.3.6.1.4.1.1466.115.121.1.26{1}
-        SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.15305.2.2 NAME ( 'dateOfBirth' 'dob' )
-        DESC    'Date of birth in ISO 8601 format'
-        EQUALITY caseIgnoreMatch
-        SYNTAX  1.3.6.1.4.1.1466.115.121.1.15{10}
-        SINGLE-VALUE )
-
-# cyrus imapd access control list
-# acls work with users and groups
-attributetype ( 1.3.6.1.4.1.19414.2.1.651
-               NAME 'acl'
-               EQUALITY caseIgnoreIA5Match
-               SUBSTR caseIgnoreIA5SubstringsMatch
-           SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-# Objectclasses
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.1 NAME 'gosaObject' SUP top AUXILIARY
-        DESC 'Objectclass for GOsa settings (v2.4)'
-        MUST ( gosaSubtreeACL ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.2 NAME 'gosaLockEntry' SUP top STRUCTURAL
-        DESC 'Objectclass for GOsa locking (v2.4)'
-        MUST ( gosaUser $ gosaObject $ cn ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.3 NAME 'gosaCacheEntry' SUP top STRUCTURAL
-        DESC 'Objectclass for GOsa caching (v2.4)'
-       MAY  ( gosaUser )
-       MUST ( cn ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.4 NAME 'gosaDepartment' SUP top AUXILIARY
-        DESC 'Objectclass to mark Departments for GOsa (v2.4)'
-       MUST  ( ou $ description ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.5 NAME 'gosaMailAccount' SUP top AUXILIARY
-        DESC 'Objectclass to mark MailAccounts for GOsa (v2.4)'
-       MUST ( mail $ gosaMailServer $ gosaMailDeliveryMode)
-       MAY  ( gosaMailQuota $ gosaMailAlternateAddress $ gosaMailForwardingAddress $
-              gosaMailMaxSize $ gosaSpamSortLevel $ gosaSpamMailbox $
-              gosaVacationMessage $ gosaVacationStart $ gosaVacationStop $ gosaSharedFolderTarget $ acl))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.6 NAME 'gosaAccount' SUP top AUXILIARY
-        DESC 'Objectclass for GOsa Accounts (v2.4)'
-       MUST ( uid )
-        MAY ( sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ gosaDefaultPrinter $
-             gosaDefaultLanguage $ academicTitle $ personalTitle $ gosaHostACL $ dateOfBirth $
-                 sambaBadPasswordCount $ sambaBadPasswordTime $ gender ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.7 NAME 'gosaHost' SUP top AUXILIARY
-        DESC 'Objectclass for GOsa Hosts (v2.4)'
-        MUST ( cn )
-        MAY ( description $ gosaService ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.8 NAME 'gosaProxyAccount' SUP top AUXILIARY
-        DESC 'Objectclass for GOsa Proxy settings (v2.4)'
-        MUST ( gosaProxyAcctFlags )
-        MAY ( gosaProxyID $ gosaProxyWorkingStart $ gosaProxyWorkingStop $ gosaProxyQuota $
-              gosaProxyQuotaPeriod ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.9 NAME 'gosaApplication' SUP top STRUCTURAL
-        DESC 'Objectclass for GOsa applications (v2.4)'
-        MUST ( cn $ gosaApplicationExecute )
-        MAY ( gosaApplicationName $ gosaApplicationIcon $ gosaApplicationFlags $ gosaApplicationMimeType $
-              gosaApplicationParameter $ gotoLogonScript $ description $ gosaApplicationCategory ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.10 NAME 'gosaApplicationGroup' SUP top AUXILIARY
-        DESC 'Objectclass for GOsa application groups (v2.4)'
-        MUST ( cn )
-        MAY ( gosaMemberApplication $ gosaApplicationParameter ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.11 NAME 'gosaUserTemplate' SUP top AUXILIARY
-        DESC 'Objectclass for GOsa User Templates (v2.4)'
-        MUST ( cn ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.12 NAME 'gosaGroupOfNames'
-        DESC 'GOsa object grouping (v2.4)'
-               SUP top STRUCTURAL
-               MUST ( cn $ gosaGroupObjects ) MAY ( member $ description ) )
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.13 NAME 'gosaWebdavAccount'
-        DESC 'GOsa webdav enabling account (v2.4)'
-        SUP top AUXILIARY
-        MUST ( cn $ uid ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.14 NAME 'gosaIntranetAccount'
-               DESC 'GOsa Inatrent enabling account (v2.4)'
-               SUP top AUXILIARY
-               MUST ( cn $ uid )
-               MAY ( gosaDefaultLanguage ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.15 NAME 'gosaAdministrativeUnit'
-       DESC 'Marker for administrational units (v2.5)'
-           SUP top AUXILIARY
-       MUST ( gosaUnitTag ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.16 NAME 'gosaAdministrativeUnitTag'
-       DESC 'Marker for objects below administrational units (v2.5)'
-           SUP top AUXILIARY
-       MUST ( gosaUnitTag ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.17 NAME 'gosaRole'
-       DESC 'ACL container to define roles (v2.5)' SUP top STRUCTURAL
-       MUST ( gosaAclTemplate $ cn )
-       MAY  ( description ) )
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.18 NAME 'gosaAcl'
-       DESC 'ACL container to define single ACLs (v2.5)' SUP top AUXILIARY
-       MUST ( gosaAclEntry  ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.19 NAME 'gosaSnapshotObject'
-       DESC 'Container object for undo and snapshot data (v2.5)' SUP top STRUCTURAL
-       MUST ( gosaSnapshotType $ gosaSnapshotTimestamp $ gosaSnapshotDN $ gosaSnapshotData )
-       MAY  ( description ) )
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.20 NAME 'gosaConfig'
-       DESC 'Settings for gosa. Replaces parts of the gosa.conf. (v2.6)' SUP top STRUCTURAL
-       MAY  ( gosaSetting ) )
-
diff --git a/contrib/openldap/gosa.schema b/contrib/openldap/gosa.schema
deleted file mode 100644 (file)
index a11a4c5..0000000
+++ /dev/null
@@ -1,376 +0,0 @@
-##
-## Needed attributes for GOsa (GONICUS System Administrator)
-##
-## Maintainer: Cajus Pollmeier (pollmeier@GONICUS.de)
-##
-
-
-# Attributes
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.1 NAME 'gosaSubtreeACL'
-        DESC 'GOsa acl entry'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.2 NAME 'gosaUser'
-        DESC 'GOsa user'
-        EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.3 NAME 'gosaObject'
-        DESC 'GOsa object'
-        EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.4 NAME 'gosaMailServer'
-        DESC 'Specify users main mail server'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.5 NAME 'gosaMailQuota'
-        DESC 'GOsa quota definitions'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.6 NAME 'gosaMailAlternateAddress'
-        DESC 'Additional mail addresses where the user is reachable'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.7 NAME 'gosaMailForwardingAddress'
-        DESC 'Addresses where to forward mail to'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.8 NAME 'gosaMailMaxSize'
-        DESC 'Block mails bigger than this value'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.9 NAME 'gosaSpamSortLevel'
-        DESC 'Spamassassins hits'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.10 NAME 'gosaSpamMailbox'
-        DESC 'Where to put spam'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.11 NAME 'gosaVacationMessage'
-        DESC 'Text to display in case of vacation'
-        EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.12 NAME 'gosaMailDeliveryMode'
-        DESC 'What to do with mails'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.13 NAME 'gosaDefaultPrinter'
-        DESC 'Defines a default printer a user owns'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.14 NAME 'gosaDefaultLanguage'
-        DESC 'Defines the default language for a user'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.15 NAME 'gosaHostACL'
-        DESC 'Defines the places where users can login'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.16 NAME 'gosaService'
-        DESC 'Defines services a certain host can provide'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.17 NAME 'gosaProxyID'
-        DESC 'Defines the proxy user id used, needed for some filters'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.18 NAME 'gosaProxyAcctFlags'
-        DESC 'Proxy Account Flags'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.19 NAME 'gosaProxyWorkingStart'
-        DESC 'Specifies the beginning of work in minutes, relative to 00:00'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.20 NAME 'gosaProxyWorkingStop'
-        DESC 'Specifies the end of work in minutes, relative to 00:00'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.21 NAME 'gosaApplicationName'
-        DESC 'Specifies the name of an application to be shown up on users desktop'
-        EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.22 NAME 'gosaApplicationExecute'
-        DESC 'Specifies the executable path of an application'
-        EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.23 NAME 'gosaApplicationFlags'
-        DESC 'Specifies the application flags G(roup only), D(esktop), M(enu)'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.24 NAME 'gosaApplicationIcon'
-        DESC 'Keeps the application icon in png format'
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.28)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.25 NAME 'gosaSharedFolderTarget'
-        DESC 'Keeps the target of cyrus shared folders'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.26 NAME 'gosaMemberApplication'
-        DESC 'Like memberUid, just for applications'
-        EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.27 NAME 'gosaApplicationParameter'
-        DESC 'Store application parameters'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.31 NAME 'gosaApplicationCategory'
-        DESC 'Store application parameters'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.28 NAME 'gosaProxyQuota'
-        DESC 'Specifies the amount of data a user may surf in a defined period of time'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.29 NAME 'gosaProxyQuotaPeriod'
-        DESC 'Specifies period of time where the counter is been reseted'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.30 NAME 'gosaGroupObjects'
-        DESC 'Takes a list of all object types that are in a gosaGroupOfNames'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.32 NAME 'gosaApplicationMimeType'
-        DESC 'Takes a list of relevant mime-type|priority settings'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.33 NAME 'gosaUnitTag'
-        DESC 'Takes a list of relevant mime-type|priority settings'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.34 NAME 'gosaAclTemplate'
-        DESC 'Takes ACL entries for gosaRoles'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.35 NAME 'gosaAclEntry'
-        DESC 'Takes ACL entries for gosaRoles'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.36 NAME 'gosaSnapshotType'
-        DESC 'Takes either undo or snapshot'
-        EQUALITY caseIgnoreMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.37 NAME 'gosaSnapshotTimestamp'
-        DESC 'Unix timestamp of snapshot'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.38 NAME 'gosaSnapshotDN'
-        DESC 'Original DN of saved object'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.39 NAME 'gosaSnapshotData'
-        DESC 'Original DN of saved object'
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.40 NAME 'gosaSetting'
-        DESC 'Original DN of saved object'
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.41 NAME 'gosaVacationStart'
-        DESC 'Timestamp for enabling current vacation message'
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.12.42 NAME 'gosaVacationStop'
-        DESC 'Timestamp for switching off current vacation message'
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.6.2 NAME 'academicTitle'
-        DESC 'Field to represent the academic title'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
-
-attributetype ( 1.3.6.1.4.1.15305.2.1 NAME ( 'gender' 'sex' )
-       DESC    'Gender: M for male, F for female'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX  1.3.6.1.4.1.1466.115.121.1.26{1}
-       SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.15305.2.2 NAME ( 'dateOfBirth' 'dob' )
-       DESC    'Date of birth in ISO 8601 format'
-       EQUALITY caseIgnoreMatch
-       SYNTAX  1.3.6.1.4.1.1466.115.121.1.15{10}
-       SINGLE-VALUE )
-
-# cyrus imapd access control list
-# acls work with users and groups
-attributetype ( 1.3.6.1.4.1.19414.2.1.651
-       NAME 'acl'
-    EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-# Objectclasses
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.1 NAME 'gosaObject' SUP top AUXILIARY
-        DESC 'Objectclass for GOsa settings (v2.4)'
-        MUST ( gosaSubtreeACL ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.2 NAME 'gosaLockEntry' SUP top STRUCTURAL
-        DESC 'Objectclass for GOsa locking (v2.4)'
-        MUST ( gosaUser $ gosaObject $ cn ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.3 NAME 'gosaCacheEntry' SUP top STRUCTURAL
-        DESC 'Objectclass for GOsa caching (v2.4)'
-       MAY  ( gosaUser )
-       MUST ( cn ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.4 NAME 'gosaDepartment' SUP top AUXILIARY
-        DESC 'Objectclass to mark Departments for GOsa (v2.4)'
-       MUST  ( ou $ description ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.5 NAME 'gosaMailAccount' SUP top AUXILIARY
-        DESC 'Objectclass to mark MailAccounts for GOsa (v2.4)'
-       MUST ( mail $ gosaMailServer $ gosaMailDeliveryMode)
-       MAY  ( gosaMailQuota $ gosaMailAlternateAddress $ gosaMailForwardingAddress $
-              gosaMailMaxSize $ gosaSpamSortLevel $ gosaSpamMailbox $
-              gosaVacationMessage $ gosaVacationStart $ gosaVacationStop $ gosaSharedFolderTarget $ acl))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.6 NAME 'gosaAccount' SUP top AUXILIARY
-        DESC 'Objectclass for GOsa Accounts (v2.4)'
-       MUST ( uid )
-        MAY ( lmPassword $ ntPassword $ pwdLastSet $ gosaDefaultPrinter $ gosaDefaultLanguage $
-              academicTitle $ personalTitle $ gosaHostACL $ dateOfBirth $ gender ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.7 NAME 'gosaHost' SUP top AUXILIARY
-        DESC 'Objectclass for GOsa Hosts (v2.4)'
-        MUST ( cn )
-        MAY ( description $ gosaService ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.8 NAME 'gosaProxyAccount' SUP top AUXILIARY
-        DESC 'Objectclass for GOsa Proxy settings (v2.4)'
-        MUST ( gosaProxyAcctFlags )
-        MAY ( gosaProxyID $ gosaProxyWorkingStart $ gosaProxyWorkingStop $ gosaProxyQuota $
-              gosaProxyQuotaPeriod ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.9 NAME 'gosaApplication' SUP top STRUCTURAL
-        DESC 'Objectclass for GOsa applications (v2.4)'
-        MUST ( cn $ gosaApplicationExecute )
-        MAY ( gosaApplicationName $ gosaApplicationIcon $ gosaApplicationFlags $ gosaApplicationMimeType $
-              gosaApplicationParameter $ gotoLogonScript $ description $ gosaApplicationCategory ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.10 NAME 'gosaApplicationGroup' SUP top AUXILIARY
-        DESC 'Objectclass for GOsa application groups (v2.4)'
-        MUST ( cn )
-        MAY ( gosaMemberApplication $ gosaApplicationParameter ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.11 NAME 'gosaUserTemplate' SUP top AUXILIARY
-        DESC 'Objectclass for GOsa User Templates (v2.4)'
-        MUST ( cn ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.12 NAME 'gosaGroupOfNames'
-        DESC 'GOsa object grouping (v2.4)'
-        SUP top STRUCTURAL
-               MUST ( cn $ gosaGroupObjects ) MAY ( description $ member ) )
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.13 NAME 'gosaWebdavAccount'
-        DESC 'GOsa webdav enabling account (v2.4)'
-        SUP top AUXILIARY
-        MUST ( cn $ uid ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.14 NAME 'gosaIntranetAccount'
-       DESC 'GOsa Intarent enabling account (v2.4)'
-          SUP top AUXILIARY
-       MUST ( cn $ uid )
-       MAY ( gosaDefaultLanguage ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.15 NAME 'gosaAdministrativeUnit'
-       DESC 'Marker for administrational units (v2.5)'
-          SUP top AUXILIARY
-       MUST ( gosaUnitTag ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.16 NAME 'gosaAdministrativeUnitTag'
-       DESC 'Marker for objects below administrational units (v2.5)'
-          SUP top AUXILIARY
-       MUST ( gosaUnitTag ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.17 NAME 'gosaRole'
-       DESC 'ACL container to define roles (v2.5)' SUP top STRUCTURAL
-       MUST ( gosaAclTemplate $ cn )
-       MAY  ( description ) )
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.18 NAME 'gosaAcl'
-       DESC 'ACL container to define single ACLs (v2.5)' SUP top AUXILIARY
-       MUST ( gosaAclEntry  ))
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.19 NAME 'gosaSnapshotObject'
-       DESC 'Container object for undo and snapshot data (v2.5)' SUP top STRUCTURAL
-       MUST ( gosaSnapshotType $ gosaSnapshotTimestamp $ gosaSnapshotDN $ gosaSnapshotData )
-       MAY  ( description ) )
-
-objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.20 NAME 'gosaConfig'
-       DESC 'Settings for gosa. Replaces parts of the gosa.conf. (v2.6)' SUP top STRUCTURAL
-       MAY  ( gosaSetting ) )
-
diff --git a/contrib/openldap/goserver.schema b/contrib/openldap/goserver.schema
deleted file mode 100644 (file)
index 97edc9d..0000000
+++ /dev/null
@@ -1,583 +0,0 @@
-## 
-##
-## goserver.schema - Needed by the GONICUS System Administator
-##
-## Version 030403
-##
-##
-## Maintainer:         Lars Scheiter   (scheiter@GONICUS.de)
-##                     Cajus Pollmeier (pollmeier@GONICUS.de)
-##
-##
-
-
-# Attributes for the Gonicus Terminal Server Class
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.1 NAME 'goXdmcpIsEnabled'
-       DESC 'Indicates if the server is enabled for XDMCP queries'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.2 NAME 'goFontPath'
-       DESC 'Fontserver Entry'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-# Attributes for common Gonicus Server Class
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.4 NAME 'goExportEntry'
-       DESC 'Provides an export entry'
-       EQUALITY caseExactMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.9 NAME 'goSyslogSection'
-       DESC 'What sections wants the server for its syslog service? i.e. *.*'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.10 NAME 'goTimeSource'
-       DESC 'List of time sources'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.11 NAME 'goSpoolPath'
-       DESC 'Provides a spool path for printing services'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.12 NAME 'goLdapBase'
-       DESC 'Base to use for this LDAP server'
-       EQUALITY caseExactMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.13 NAME 'goImapName'
-       DESC 'Name of IMAP server appearing in GOsa'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.14 NAME 'goImapConnect'
-       DESC 'PHP connect string for IMAP server'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.15 NAME 'goImapAdmin'
-       DESC 'IMAP admin account'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.16 NAME 'goImapPassword'
-       DESC 'IMAP admin password'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.17 NAME 'goImapSieveServer'
-       DESC 'Cyrus sieve server address or name'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.18 NAME 'goImapSievePort'
-       DESC 'Cyrus sieve server port'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.19 NAME 'goKrbRealm'
-       DESC 'Default Kerberos realm to use for this server'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.20 NAME 'goKrbAdmin'
-       DESC 'Admin principal for kerberos server'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.21 NAME 'goKrbPassword'
-       DESC 'Admin password for kerberos server'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.22 NAME 'goFaxAdmin'
-       DESC 'Admin principal for fax server'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.23 NAME 'goFaxPassword'
-       DESC 'Admin password for fax server'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.24 NAME 'goLogAdmin'
-       DESC 'Admin principal for log server'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.25 NAME 'goLogPassword'
-       DESC 'Admin password for log server'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.26 NAME 'goFonAdmin'
-        DESC 'Admin principal for fon server'
-        EQUALITY caseExactIA5Match
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-        SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.27 NAME 'goFonPassword'
-        DESC 'Admin password for fon server'
-        EQUALITY caseExactIA5Match
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-        SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.28 NAME 'goFonAreaCode'
-        DESC 'Store area code'
-        EQUALITY caseExactIA5Match
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-        SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.29 NAME 'goFonCountryCode'
-        DESC 'Store country code'
-        EQUALITY caseExactIA5Match
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-        SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.30 NAME 'goGlpiAdmin'
-       DESC 'Admin principal for glpi database server'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.31 NAME 'goGlpiPassword'
-       DESC 'Admin password for glpi database server'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.32 NAME 'goGlpiDatabase'
-       DESC 'Database name for glpi extension'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.33 NAME 'goTerminalServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.34 NAME 'goNfsServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.35 NAME 'goNtpServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.36 NAME 'goSyslogServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.37 NAME 'goLdapServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.38 NAME 'goImapServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.39 NAME 'goKrbServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.40 NAME 'goFaxServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.41 NAME 'goLogDBServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.42 NAME 'goFonServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.43 NAME 'goShareServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.44 NAME 'goMailServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.45 NAME 'goGlpiServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.46 NAME 'postfixHeaderSizeLimit'
-       DESC 'Keep postfix header-size-limit variable'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.47 NAME 'postfixMailboxSizeLimit'
-       DESC 'Keep postfix mailbox-size-limit variable'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.48 NAME 'postfixMessageSizeLimit'
-       DESC 'Keep postfix message-size-limit variable'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.49 NAME 'postfixMyDestinations'
-       DESC 'Keep postfix mydestinations variable'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.50 NAME 'postfixMyDomain'
-       DESC 'Keep postfix mydomain variable'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.51 NAME 'postfixMyHostname'
-       DESC 'Keep postfix myhostname variable'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.52 NAME 'postfixMyNetworks'
-       DESC 'Keep postfix mynetworks variable'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.53 NAME 'postfixRelayhost'
-       DESC 'Keep postfix relayhost variable'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.54 NAME 'postfixTransportTable'
-       DESC 'Keep postfix transport tables'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.55 NAME 'postfixSenderRestrictions'
-       DESC 'Keep postfix sender restrictions'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.56 NAME 'postfixRecipientRestrictions'
-       DESC 'Keep postfix transport tables'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.57 NAME 'cyrusImap'
-       DESC 'Start IMAP service? true/false'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.58 NAME 'cyrusImapSSL'
-       DESC 'Start IMAP SSL service? true/false'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.59 NAME 'cyrusPop3'
-       DESC 'Start POP3 service? true/false'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.60 NAME 'cyrusPop3SSL'
-       DESC 'Start POP3 SSL service? true/false'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.61 NAME 'goCupsServerStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.62 NAME 'saRewriteHeader'
-       DESC 'Text to place in front of mail subjects'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.63 NAME 'saTrustedNetworks'
-       DESC 'List of trusted networks'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.64 NAME 'saRequiredScore'
-       DESC 'Required score to tag a mail as SPAM'
-       EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
-
-#saFlags   B:    Enable use of bayes filtering
-#          b:    Enable bayes auto learning
-#          C:    Enable RBL checks
-#          R:    Enable use of Razor
-#          D:    Enable use of DDC
-#          P:    Enable use of Pyzor
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.65 NAME 'saFlags'
-       DESC 'Flags for spamassassin'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.66 NAME 'saRule'
-       DESC 'Base64 encoded rule text for spamassassin'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.67 NAME 'saStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.68 NAME 'avMaxThreads'
-       DESC 'Number of AV scanning threads'
-       EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.69 NAME 'avMaxDirectoryRecursions'
-       DESC 'Number of recursions done with directories'
-       EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.70 NAME 'avUser'
-       DESC 'Username to run with'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# avFlags         D       Debug
-#                 S       Scan Mail
-#                 A       Scan Archive
-#                 E       Archive block encrypted
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.71 NAME 'avFlags'
-       DESC 'Special flags for the scan engine'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.72 NAME 'avArchiveMaxFileSize'
-       DESC 'Maximum archive file size'
-       EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.73 NAME 'avArchiveMaxRecursion'
-       DESC 'Maximum number of archive nestings'
-       EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.74 NAME 'avArchiveMaxCompressionRatio'
-       DESC 'Maximum compression ratio'
-       EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.75 NAME 'avDatabaseMirror'
-       DESC 'Where to find updates'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.76 NAME 'avHttpProxyURL'
-       DESC 'How to get the updates'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.77 NAME 'avStatus'
-       DESC 'Server status container - on / off / fail'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.78 NAME 'avChecksPerDay'
-        DESC 'Update checks per day'
-        EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.79 NAME 'goLogDB'
-       DESC 'Name of logging DB'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.80 NAME 'goLogDBUser'
-       DESC 'Auth user for logging DB'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.9.81 NAME 'goLogDBPassword'
-       DESC 'Password for logging DB user'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-
-##
-##             Objectclasses
-##
-
-# Terminal Server description 
-objectclass (1.3.6.1.4.1.10098.1.2.1.16 NAME 'goTerminalServer' SUP top AUXILIARY
-       DESC 'Terminal server description (v2.4)'
-       MUST ( cn $ goXdmcpIsEnabled $ goFontPath )
-       MAY  ( description $ goTerminalServerStatus ))
-
-# NFS Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.19 NAME 'goNfsServer' SUP top AUXILIARY
-       DESC 'NFS server description (v2.4)'
-       MUST ( cn )
-       MAY  ( goExportEntry $ description $ goNfsServerStatus ))
-
-# Time Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.20 NAME 'goNtpServer' SUP top AUXILIARY
-       DESC 'Time server description (v2.4)'
-       MUST ( cn )
-        MAY  ( goTimeSource $ description $ goNtpServerStatus ))
-
-# Syslog Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.21 NAME 'goSyslogServer' SUP top AUXILIARY
-       DESC 'Syslog server description (v2.4)'
-       MUST ( cn )
-       MAY  ( goSyslogSection $ description $ goSyslogServerStatus ))
-
-# LDAP Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.22 NAME 'goLdapServer' SUP top AUXILIARY
-       DESC 'LDAP server description (v2.4)'
-       MUST ( cn )
-       MAY  ( goLdapBase $ description $ goLdapServerStatus ))
-
-# CUPS Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.23 NAME 'goCupsServer' SUP top AUXILIARY
-       DESC 'CUPS server description (v2.4)'
-       MUST ( cn )
-       MAY  ( description $ goCupsServerStatus ))
-
-# IMAP Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.24 NAME 'goImapServer' SUP top AUXILIARY
-       DESC 'IMAP server description (v2.4)'
-       MUST ( cn $ goImapName $ goImapConnect $ goImapAdmin $ goImapPassword )
-       MAY  ( goImapSieveServer $ goImapSievePort $ description $ goImapServerStatus $
-              cyrusImap $ cyrusImapSSL $ cyrusPop3 $ cyrusPop3SSL ))
-
-# Kerberos Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.25 NAME 'goKrbServer' SUP top AUXILIARY
-       DESC 'Kerberos server description (v2.4)'
-       MUST ( cn $ goKrbRealm $ goKrbAdmin $ goKrbPassword )
-       MAY  ( description $ goKrbServerStatus ))
-
-# Fax Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.26 NAME 'goFaxServer' SUP top AUXILIARY
-       DESC 'Fax server description (v2.4)'
-       MUST ( cn $ goFaxAdmin $ goFaxPassword )
-       MAY  ( description $ goFaxServerStatus ))
-
-# Common server class
-objectclass (1.3.6.1.4.1.10098.1.2.1.27 NAME 'goServer' SUP top AUXILIARY
-       DESC 'Server description (v2.4)'
-       MUST ( cn )
-       MAY  ( description $ macAddress $ ipHostNumber ))
-
-# LogDB Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.28 NAME 'goLogDBServer' SUP top AUXILIARY
-       DESC 'Log DB server description (v2.4)'
-       MUST ( cn $ goLogAdmin $ goLogPassword )
-       MAY  ( goLogDBServerStatus ))
-
-# Fon Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.29 NAME 'goFonServer' SUP top AUXILIARY
-        DESC 'Fon server description (v2.4)'
-        MUST ( cn $ goFonAdmin $ goFonPassword $ goFonAreaCode $ goFonCountryCode )
-        MAY  ( description $ goFonServerStatus ))
-
-# Share Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.33 NAME 'goShareServer' SUP top AUXILIARY
-       DESC 'Share server description (v2.4)'
-       MUST ( cn )
-       MAY  ( description $ goExportEntry $ goShareServerStatus ))
-
-# Mail Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.36 NAME 'goMailServer' SUP top AUXILIARY
-       DESC 'Mail server definition (v2.4)'
-       MUST ( cn )
-       MAY  ( description $ goMailServerStatus $ postfixHeaderSizeLimit $
-              postfixMailboxSizeLimit $ postfixMessageSizeLimit $
-              postfixMydestinations $ postfixMydomain $ postfixMyhostname $
-              postfixMynetworks $ postfixRelayhost $ postfixTransportTable $
-              postfixSenderRestrictions $ postfixRecipientRestrictions ) )
-
-# Glpi Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.37 NAME 'goGlpiServer' SUP top AUXILIARY
-       DESC 'Glpi server definition (v2.4)'
-       MUST ( cn $ goGlpiAdmin $ goGlpiDatabase)
-       MAY  ( description $ goGlpiPassword $ goGlpiServerStatus ) )
-
-# Spamassassin definitions
-objectclass (1.3.6.1.4.1.10098.1.2.1.38 NAME 'goSpamServer' SUP top AUXILIARY
-       DESC 'Spam server definition (v2.5)'
-       MUST ( cn )
-       MAY  ( saRewriteHeader $ saTrustedNetworks $ saRequiredScore $ saFlags $
-              saRule $ saStatus ) )
-
-# Clamav definitions
-objectclass (1.3.6.1.4.1.10098.1.2.1.39 NAME 'goVirusServer' SUP top AUXILIARY
-       DESC 'Virus server definition (v2.5)'
-       MUST ( cn )
-       MAY  ( avMaxThreads $ avMaxDirectoryRecursions $ avUser $ avFlags $
-               avArchiveMaxFileSize $ avArchiveMaxRecursion $ avArchiveMaxCompressionRatio $
-               avDatabaseMirror $ avChecksPerDay $ avHttpProxyURL ) )
-
-# LogDB Server description
-objectclass (1.3.6.1.4.1.10098.1.2.1.40 NAME 'gosaLogServer' SUP top AUXILIARY
-       DESC 'GOsa log server (v2.6)'
-       MUST ( cn $ goLogDB $ goLogDBUser $ goLogDBPassword ))
-
-# Environment Server
-objectclass (1.3.6.1.4.1.10098.1.2.1.41 NAME 'goEnvironmentServer' SUP top AUXILIARY
-       DESC 'Environment server definition (v2.6)'
-       MUST ( cn )
-       MAY  ( gotoKioskProfile ) )
-
diff --git a/contrib/openldap/gosystem.schema b/contrib/openldap/gosystem.schema
deleted file mode 100644 (file)
index b25e61d..0000000
+++ /dev/null
@@ -1,340 +0,0 @@
-##
-## gosystem.schema - Needed by the GONICUS Terminal concept
-##
-
-# Attributes
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.1 NAME 'gotoSyslogServer'
-       DESC 'GOto - Gonicus Terminal Concept, value syslogServer.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.2 NAME 'gotoNtpServer'
-       DESC 'GOto - Gonicus Terminal Concept, value ntpServer.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.3 NAME 'gotoSwapServer'
-       DESC 'GOto - Gonicus Terminal Concept, value swapServer.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.4 NAME 'gotoLpdServer'
-       DESC 'GOto - Gonicus Terminal Concept, value lpdServer.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.5 NAME 'gotoFontPath'
-       DESC 'GOto - Gonicus Terminal Concept, value fontPath.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.6 NAME 'gotoFilesystem'
-       DESC 'GOto - Gonicus Terminal Concept, value filesystem.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.7 NAME 'gotoFloppyEnable'
-       DESC 'GOto - Gonicus Terminal Concept, value floppyEnable.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.8 NAME 'gotoCdromEnable'
-       DESC 'GOto - Gonicus Terminal Concept, value cdromEnable.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.9 NAME 'gotoLpdEnable'
-       DESC 'GOto - Gonicus Terminal Concept, value lpdEnable.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.10 NAME 'gotoScannerEnable'
-       DESC 'GOto - Gonicus Terminal Concept, value scannerEnable.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.11 NAME 'gotoScannerClients'
-       DESC 'GOto - Gonicus Terminal Concept, value scannerClients.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.14 NAME 'gotoRootPasswd'
-       DESC 'GOto - Gonicus Terminal Concept, value rootPasswd.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.15 NAME 'gotoXdmcpServer'
-       DESC 'GOto - Gonicus Terminal Concept, value xdmcpServer.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.16 NAME 'gotoXMethod'
-       DESC 'GOto - Gonicus Terminal Concept, value xMethod.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.17 NAME 'gotoXMonitor'
-       DESC 'GOto - Gonicus Terminal Concept, value xMonitor.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.18 NAME 'gotoXHsync'
-       DESC 'GOto - Gonicus Terminal Concept, value xHsync.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.19 NAME 'gotoXVsync'
-       DESC 'GOto - Gonicus Terminal Concept, value xVsync.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.20 NAME 'gotoXResolution'
-       DESC 'GOto - Gonicus Terminal Concept, value xResolution.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.21 NAME 'gotoXColordepth'
-       DESC 'GOto - Gonicus Terminal Concept, value xColordepth.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.22 NAME 'gotoXMouseport'
-       DESC 'GOto - Gonicus Terminal Concept, value xMouseport.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.23 NAME 'gotoXMouseButtons'
-       DESC 'GOto - Gonicus Terminal Concept, value xMouseButtons.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.24 NAME 'gotoMode'
-       DESC 'GOto - Gonicus Terminal Concept, Terminal is active.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.25 NAME 'gotoXKbModel'
-       DESC 'GOto - Gonicus Terminal Concept, value xKbmodel.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.26 NAME 'gotoXKbLayout'
-       DESC 'GOto - Gonicus Terminal Concept, value xKblayout.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.27 NAME 'gotoXKbVariant'
-       DESC 'GOto - Gonicus Terminal Concept, value xKbvariant.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.28 NAME 'gotoXDriver'
-       DESC 'GOto - Gonicus Terminal Concept, value xDriver.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.29 NAME 'gotoSndModule'
-       DESC 'GOto - Gonicus Terminal Concept, value sndModules.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.30 NAME 'gotoLastUser'
-       DESC 'GOto - Gonicus Terminal Concept, value lastUser.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.31 NAME 'gotoAutoFs'
-       DESC 'GOto - Gonicus Terminal Concept, value autofs.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-       
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.32 NAME 'gotoModules'
-       DESC 'GOto - Gonicus Terminal Concept, value modules.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.33 NAME 'gotoAdaptPath'
-       DESC 'GOto - Gonicus Terminal Concept, value adaptpath.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.34 NAME 'gotoXMouseType'
-        DESC 'Hardware definitions, value Maustyp'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-        SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.35 NAME 'gotoKernelParameters'
-        DESC 'Kernel boot parameters'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-        SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.36 NAME 'gotoBootKernel'
-        DESC 'Kernel boot parameters'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-        SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.37 NAME 'gotoTerminalPath'
-        DESC 'Kernel boot parameters'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-        SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.38 NAME 'gotoLdapServer'
-        DESC 'Kernel boot parameters'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.39 NAME 'gotoScannerBackend'
-       DESC 'GOto - Gonicus Terminal Concept, value scannerBackend.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.1.40 NAME 'gotoScannerModel'
-       DESC 'GOto - Gonicus Terminal Concept, value scannerModel.'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.2.1 NAME 'ghCpuType'
-       DESC 'Hardware definitions, value cpuType'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.2.2 NAME 'ghMemSize'
-       DESC 'Hardware definitions, value memSize'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.2.3 NAME 'ghUsbSupport'
-       DESC 'Hardware definitions, value usbSupport'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.2.4 NAME 'ghIdeDev'
-       DESC 'Hardware definitions, value ideDev'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.2.5 NAME 'ghScsiDev'
-       DESC 'Hardware definitions, value scsiDev'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.2.7 NAME 'ghSoundAdapter'
-       DESC 'Hardware definitions, value soundAdapter'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.2.8 NAME 'ghNetNic'
-       DESC 'Hardware definitions, value Network Device'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.2.9 NAME 'ghGfxAdapter'
-       DESC 'Hardware definitions, value Grafikkarte'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.2.10 NAME 'ghInventoryNumber'
-       DESC 'Unique number for inclusion in an inventory'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE)
-
-
-# objectclass for Hardware definitions
-objectclass (1.3.6.1.4.1.10098.1.2.1.3 NAME 'GOhard'
-        DESC 'Gonicus Hardware definitions, objectclass (v2.5)' SUP top STRUCTURAL
-        MUST ( cn )
-        MAY ( ghGfxAdapter $ ghNetNic $ ghSoundAdapter $ ghIdeDev $ ghScsiDev $
-              macAddress $ ghUsbSupport $ ghMemSize $ ghCpuType $ ghInventoryNumber $
-              gotoSyslogServer $ gotoNtpServer $ gotoSwapServer $ gotoLpdServer $
-              gotoFontPath $ gotoFilesystem $ gotoFloppyEnable $ gotoCdromEnable $
-              gotoLpdEnable $ gotoScannerEnable $ gotoScannerClients $
-              gotoRootPasswd $ gotoXdmcpServer $ gotoXMethod $ gotoSndModule $
-              gotoLastUser $ gotoXMonitor $ gotoXHsync $ gotoXVsync $ gotoXResolution $
-              gotoXColordepth $ gotoXMouseport $ gotoXMouseButtons $ gotoMode $ gotoXKbModel $
-              gotoXKbLayout $ gotoXKbVariant $ gotoXDriver $ gotoXMouseType $ macAddress $
-              gotoAutoFs $ gotoModules $ gotoAdaptPath $ gotoKernelParameters $ gotoBootKernel $
-              gotoTerminalPath $ gotoLdapServer $ gotoScannerModel $ ipHostNumber $ l $ description ) )
-
diff --git a/contrib/openldap/goto-mime.schema b/contrib/openldap/goto-mime.schema
deleted file mode 100644 (file)
index eef9dbf..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-##
-## goto-mime.schema - Needed by the GONICUS Terminal concept
-##
-## Maintainer: Cajus Pollmeier (pollmeier@GONICUS.de)
-##
-
-# Basic list of mime groups:
-#   application audio chemical image inode message model multipart
-#   text video x-conference x-world
-attributetype ( 1.3.6.1.4.1.10098.1.1.14.1 NAME 'gotoMimeGroup'
-        DESC 'IANA defined mime group'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# File extensions without search patterns. i.e. png, jpg, xcf
-attributetype ( 1.3.6.1.4.1.10098.1.1.14.2 NAME 'gotoMimeFilePattern'
-        DESC 'File extensions for mime types'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-# Coded application and priority seperated by |. i.e. /usr/bin/gimp|1
-attributetype ( 1.3.6.1.4.1.10098.1.1.14.3 NAME 'gotoMimeApplication'
-        DESC 'Assigned application and priority'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-# Coded application and priority seperated by |.
-# i.e. cn=gimp,ou=apps,dc=gonicus,dc=de|1
-attributetype ( 1.3.6.1.4.1.10098.1.1.14.4 NAME 'gotoMimeEmbeddedApplication'
-        DESC 'Assigned application and priority for embedded applications'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-# Encoded left click action for filebrowsers, etc. This can be either:
-#  I: show in embedded viewer
-#  E: show in external viewer
-#  O: take settings from global mime group
-#  These fields are taken as OR. Additionally you can add a
-#  Q: to ask wether a question should pop up - to save it to
-#     the local disc or not.
-attributetype ( 1.3.6.1.4.1.10098.1.1.14.5 NAME 'gotoMimeLeftClickAction'
-        DESC 'GOto - Gonicus Terminal Concept, PPD data'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-# Save binary png icon here
-attributetype ( 1.3.6.1.4.1.10098.1.1.14.6 NAME 'gotoMimeIcon'
-        DESC 'Specify the mime icon'
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.28 SINGLE-VALUE)
-
-objectclass (1.3.6.1.4.1.10098.1.2.4.1 NAME 'gotoMimeType'
-        DESC 'Class to represent global mime types (v2.5)' SUP top STRUCTURAL
-        MUST ( cn $ gotoMimeFilePattern $ gotoMimeGroup )
-        MAY  ( description $ gotoMimeIcon $ gotoMimeApplication $
-              gotoMimeEmbeddedApplication $ gotoMimeLeftClickAction ))
-
diff --git a/contrib/openldap/goto.schema b/contrib/openldap/goto.schema
deleted file mode 100644 (file)
index 2840c4e..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-## 
-##
-## goto.schema - Needed by the GONICUS Terminal concept
-##
-## Version 030403
-##
-##
-## Maintainer:         Lars Scheiter   (scheiter@GONICUS.de)
-##                     Cajus Pollmeier (pollmeier@GONICUS.de)
-##
-##
-## Requires: gohard.schema
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.11.6 NAME 'gotoPrinterPPD'
-        DESC 'GOto - Gonicus Terminal Concept, PPD data'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.11.7 NAME 'gotoProfileFlags'
-        DESC 'GOto - Flags for Profile handling - C is for caching'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.11.8 NAME 'gotoProfileServer'
-        DESC 'GOto - specifies the profile server'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.11.9 NAME 'gotoShare'
-        DESC 'GOto - specifies a share'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.11.10 NAME 'gotoLogonScript'
-        DESC 'GOto - specifies a LogonScript'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.11.11 NAME 'gotoKioskProfile'
-        DESC 'GOto - specifies a kiosk profile'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.11.12 NAME 'gotoUserPrinter'
-        DESC 'GOto - keeps printers shown for this user'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.11.13 NAME 'gotoUserAdminPrinter'
-        DESC 'GOto - keeps printers we are admin for'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.11.16 NAME 'gotoGroupPrinter'
-        DESC 'GOto - keeps printers shown for this user'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.11.17 NAME 'gotoGroupAdminPrinter'
-        DESC 'GOto - keeps printers we are admin for'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.11.14 NAME 'gotoHotplugDevice'
-        DESC 'GOto - keeps hotplug devices'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.11.15 NAME 'gotoProfileQuota'
-        DESC 'GOto - save quota for home'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
-
-attributetype ( 1.3.6.1.4.1.10098.1.1.11.18 NAME 'gotoHotplugDeviceDN'
-        DESC 'GOto - points to hotplug devices'
-       EQUALITY distinguishedNameMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12)
-
-objectclass (1.3.6.1.4.1.10098.1.2.1.1 NAME 'gotoTerminal'
-        DESC 'GOto - Gonicus Terminal Concept, objectclass (v2.5)' SUP top AUXILIARY
-        MUST ( cn )
-        MAY  ( description $ macAddress $ ipHostNumber $ gotoShare $ goFonHardware ))
-
-# objectclass for the Terminal Conecept
-objectclass (1.3.6.1.4.1.10098.1.2.1.30 NAME 'gotoWorkstation'
-        DESC 'GOto - Gonicus Terminal Concept, objectclass (v2.5)' SUP top AUXILIARY
-        MUST ( cn )
-        MAY  ( description $ macAddress $ ipHostNumber $ gotoShare $ goFonHardware ))
-
-# objectclass for the Terminal Conecept
-objectclass (1.3.6.1.4.1.10098.1.2.1.31 NAME 'gotoPrinter'
-       DESC 'GOto - Gonicus Terminal Concept, objectclass (v2.2)' SUP top STRUCTURAL
-       MUST ( cn )
-       MAY ( labeledURI $ description $ l $ gotoPrinterPPD $ macAddress $ ipHostNumber $ gotoUserPrinter $
-                 gotoUserAdminPrinter $ gotoGroupPrinter $ gotoGroupAdminPrinter ) )
-
-# objectclass for the Terminal Conecept
-objectclass (1.3.6.1.4.1.10098.1.2.1.32 NAME 'gotoEnvironment'
-       DESC 'GOto - contains environment settings (v2.2)' SUP top AUXILIARY
-       MAY ( gotoProfileServer $ gotoProfileFlags $ gotoXResolution $ gotoShare $ gotoLogonScript $
-                 gotoKioskProfile $ gotoHotplugDevice $ gotoProfileQuota $ gotoHotplugDeviceDN ) )
-
-# objectclass for the Terminal Conecept
-objectclass (1.3.6.1.4.1.10098.1.2.1.34 NAME 'gotoWorkstationTemplate'
-        DESC 'GOto - Gonicus Terminal Concept, objectclass (v2.5)' SUP top AUXILIARY
-        MUST ( cn )
-        MAY  ( description $ gotoShare $ goFonHardware $
-              ghGfxAdapter $ ghNetNic $ ghSoundAdapter $ ghIdeDev $ ghScsiDev $
-              ghUsbSupport $ ghMemSize $ ghCpuType $ ghInventoryNumber $
-              gotoSyslogServer $ gotoNtpServer $ gotoSwapServer $ gotoLpdServer $
-              gotoFontPath $ gotoFilesystem $ gotoFloppyEnable $ gotoCdromEnable $
-              gotoLpdEnable $ gotoScannerEnable $ gotoScannerClients $
-              gotoRootPasswd $ gotoXdmcpServer $ gotoXMethod $ gotoSndModule $
-              gotoLastUser $ gotoXMonitor $ gotoXHsync $ gotoXVsync $ gotoXResolution $
-              gotoXColordepth $ gotoXMouseport $ gotoXMouseButtons $ gotoMode $ gotoXKbModel $
-              gotoXKbLayout $ gotoXKbVariant $ gotoXDriver $ gotoXMouseType $ macAddress $
-              gotoAutoFs $ gotoModules $ gotoAdaptPath $ gotoKernelParameters $ gotoBootKernel $
-              gotoTerminalPath $ gotoLdapServer $ gotoScannerModel ))
-
-# objectclass for the Terminal Conecept
-objectclass (1.3.6.1.4.1.10098.1.2.1.35 NAME 'gotoTerminalTemplate'
-        DESC 'GOto - Gonicus Terminal Concept, objectclass (v2.5)' SUP top AUXILIARY
-        MUST ( cn )
-        MAY  ( description $ gotoShare $ goFonHardware $
-              ghGfxAdapter $ ghNetNic $ ghSoundAdapter $ ghIdeDev $ ghScsiDev $
-              ghUsbSupport $ ghMemSize $ ghCpuType $ ghInventoryNumber $
-              gotoSyslogServer $ gotoNtpServer $ gotoSwapServer $ gotoLpdServer $
-              gotoFontPath $ gotoFilesystem $ gotoFloppyEnable $ gotoCdromEnable $
-              gotoLpdEnable $ gotoScannerEnable $ gotoScannerClients $
-              gotoRootPasswd $ gotoXdmcpServer $ gotoXMethod $ gotoSndModule $
-              gotoLastUser $ gotoXMonitor $ gotoXHsync $ gotoXVsync $ gotoXResolution $
-              gotoXColordepth $ gotoXMouseport $ gotoXMouseButtons $ gotoMode $ gotoXKbModel $
-              gotoXKbLayout $ gotoXKbVariant $ gotoXDriver $ gotoXMouseType $ macAddress $
-              gotoAutoFs $ gotoModules $ gotoAdaptPath $ gotoKernelParameters $ gotoBootKernel $
-              gotoTerminalPath $ gotoLdapServer $ gotoScannerModel ))
-
-# objectclass for the Terminal Conecept
-objectclass (1.3.6.1.4.1.10098.1.2.1.42 NAME 'gotoDevice'
-       DESC 'GOto - contains environment settings (v2.2)' SUP top STRUCTURAL
-  MUST ( cn )
-       MAY ( gotoHotplugDevice ) )
-
diff --git a/contrib/openldap/hdb.schema b/contrib/openldap/hdb.schema
deleted file mode 100644 (file)
index 6e5c0f7..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-# Definitions for a Kerberos V KDC schema
-#
-# $Id: hdb.schema 14958 2005-04-25 17:33:40Z lha $
-#
-# This version is compatible with OpenLDAP 1.8
-#
-# OID Base is iso(1) org(3) dod(6) internet(1) private(4) enterprise(1) padl(5322) kdcSchema(10)
-#
-# Syntaxes are under 1.3.6.1.4.1.5322.10.0
-# Attributes types are under 1.3.6.1.4.1.5322.10.1
-# Object classes are under 1.3.6.1.4.1.5322.10.2
-
-# Syntax definitions
-
-#krb5KDCFlagsSyntax SYNTAX ::= {
-#   WITH SYNTAX            INTEGER
-#--        initial(0),             -- require as-req
-#--        forwardable(1),         -- may issue forwardable
-#--        proxiable(2),           -- may issue proxiable
-#--        renewable(3),           -- may issue renewable
-#--        postdate(4),            -- may issue postdatable
-#--        server(5),              -- may be server
-#--        client(6),              -- may be client
-#--        invalid(7),             -- entry is invalid
-#--        require-preauth(8),     -- must use preauth
-#--        change-pw(9),           -- change password service
-#--        require-hwauth(10),     -- must use hwauth
-#--        ok-as-delegate(11),     -- as in TicketFlags
-#--        user-to-user(12),       -- may use user-to-user auth
-#--        immutable(13)           -- may not be deleted         
-#   ID                     { 1.3.6.1.4.1.5322.10.0.1 }
-#}
-
-#krb5PrincipalNameSyntax SYNTAX ::= {
-#   WITH SYNTAX            OCTET STRING
-#-- String representations of distinguished names as per RFC1510
-#   ID                     { 1.3.6.1.4.1.5322.10.0.2 }
-#}
-
-# Attribute type definitions
-attributetype ( 1.3.6.1.4.1.5322.10.1.1
-       NAME 'krb5PrincipalName'
-       DESC 'The unparsed Kerberos principal name'
-       EQUALITY caseExactIA5Match
-       SINGLE-VALUE
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.5322.10.1.2
-       NAME 'krb5KeyVersionNumber'
-       EQUALITY integerMatch
-       SINGLE-VALUE
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
-
-attributetype ( 1.3.6.1.4.1.5322.10.1.3
-       NAME 'krb5MaxLife'
-       EQUALITY integerMatch
-       SINGLE-VALUE
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
-
-attributetype ( 1.3.6.1.4.1.5322.10.1.4
-       NAME 'krb5MaxRenew'
-       EQUALITY integerMatch
-       SINGLE-VALUE
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
-
-attributetype ( 1.3.6.1.4.1.5322.10.1.5
-       NAME 'krb5KDCFlags'
-       EQUALITY integerMatch
-       SINGLE-VALUE
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
-
-attributetype ( 1.3.6.1.4.1.5322.10.1.6
-       NAME 'krb5EncryptionType'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
-
-attributetype ( 1.3.6.1.4.1.5322.10.1.7
-       NAME 'krb5ValidStart'
-       EQUALITY generalizedTimeMatch
-       ORDERING generalizedTimeOrderingMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
-       SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.5322.10.1.8
-       NAME 'krb5ValidEnd'
-       EQUALITY generalizedTimeMatch
-       ORDERING generalizedTimeOrderingMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
-       SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.5322.10.1.9
-       NAME 'krb5PasswordEnd'
-       EQUALITY generalizedTimeMatch
-       ORDERING generalizedTimeOrderingMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
-       SINGLE-VALUE )
-
-# this is temporary; keys will eventually
-# be child entries or compound attributes.
-attributetype ( 1.3.6.1.4.1.5322.10.1.10
-       NAME 'krb5Key'
-       DESC 'Encoded ASN1 Key as an octet string'
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
-
-attributetype ( 1.3.6.1.4.1.5322.10.1.11
-       NAME 'krb5PrincipalRealm'
-       DESC 'Distinguished name of krb5Realm entry'
-       SUP distinguishedName )
-
-attributetype ( 1.3.6.1.4.1.5322.10.1.12
-       NAME 'krb5RealmName'
-       EQUALITY octetStringMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )
-
-# Object class definitions
-
-objectclass ( 1.3.6.1.4.1.5322.10.2.1
-       NAME 'krb5Principal'
-       SUP top
-       AUXILIARY
-       MUST ( krb5PrincipalName )
-       MAY ( cn $ krb5PrincipalRealm ) )
-
-objectclass ( 1.3.6.1.4.1.5322.10.2.2
-       NAME 'krb5KDCEntry'
-       SUP krb5Principal
-       AUXILIARY
-       MUST ( krb5KeyVersionNumber )
-       MAY ( krb5ValidStart $ krb5ValidEnd $ krb5PasswordEnd $
-              krb5MaxLife $ krb5MaxRenew $ krb5KDCFlags $
-              krb5EncryptionType $ krb5Key ) )
-
-objectclass ( 1.3.6.1.4.1.5322.10.2.3
-       NAME 'krb5Realm'
-       SUP top
-       AUXILIARY
-       MUST ( krb5RealmName ) )
-
diff --git a/contrib/openldap/kolab2.schema b/contrib/openldap/kolab2.schema
deleted file mode 100644 (file)
index 85b22d7..0000000
+++ /dev/null
@@ -1,641 +0,0 @@
-# $Id: kolab2.schema,v 1.22 2007/02/02 15:16:45 thomas Exp $
-# (c) 2003, 2004 Tassilo Erlewein <tassilo.erlewein@erfrakon.de>
-# (c) 2003-2006  Martin Konold <martin.konold@erfrakon.de>
-# (c) 2003 Achim Frank <achim.frank@erfrakon.de>
-#
-# Redistribution and use in source and binary forms, with or without 
-# modification, are permitted provided that the following conditions are met:
-#
-# Redistributions of source code must retain the above copyright notice, this 
-# list of conditions and the following disclaimer.
-#
-# Redistributions in binary form must reproduce the above copyright notice, 
-# this list of conditions and the following disclaimer in the documentation 
-# and/or other materials provided with the distribution.
-#
-# The name of the author may not be used to endorse or promote products derived 
-# from this software without specific prior written permission.
-#
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
-# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# This schema highly depends on the core.schema, cosine.schema and the inetorgperson.schema
-# as provided by 3rd parties like OpenLDAP.
-#
-# slapd.conf then looks like
-# include /kolab/etc/openldap/schema/core.schema
-# include /kolab/etc/openldap/schema/cosine.schema
-# include /kolab/etc/openldap/schema/inetorgperson.schema
-# include /kolab/etc/openldap/schema/rfc2739.schema
-# include /kolab/etc/openldap/schema/kolab2.schema
-
-#
-####################
-# kolab attributes #
-####################
-
-# helper attribute to make the kolab root easily findable in 
-# a big ldap directory
-attributetype ( 1.3.6.1.4.1.19414.2.1.1
-  NAME ( 'k' 'kolab' )
-  DESC 'Kolab attribute'
-  SUP name )
-
-# kolabDeleteflag used to be a boolean but describes with Kolab 2 
-# the fqdn of the server which is requested to delete this objects
-# in its local store
-attributetype ( 1.3.6.1.4.1.19414.2.1.2
-  NAME 'kolabDeleteflag'
-  DESC 'Per host deletion status'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-# alias used to provide alternative rfc822 email addresses for kolab users
-attributetype ( 1.3.6.1.4.1.19414.2.1.3
-  NAME 'alias'
-  DESC 'RFC1274: RFC822 Mailbox'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-# kolabEncryptedPassword is an asymmetrically (RSA) encrypted copy of the
-# cleartext password. This is required in order to pass the password from
-# the maintainance/administration application to the kolabHomeServer running the
-# resource handler application in a secure manner.
-# Actually this attribute is deprecated as of Kolab 2.1. Instead we grant the 
-# calendar user dn: cn=calendar,cn=internal,dc=yourcompany,dc=com access to 
-# the respective calendar folder using IMAP ACLs.
-attributetype ( 1.3.6.1.4.1.19419.2.1.4
-  NAME 'kolabEncryptedPassword'
-  DESC 'base64 encoded public key encrypted Password'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-# hostname including the domain name like kolab-master.yourcompany.com
-attributetype ( 1.3.6.1.4.1.19414.2.1.5
-  NAME ( 'fqhostname' 'fqdnhostname' )
-  DESC 'Fully qualified Hostname including full domain component'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-# fqdn of all hosts in a multi-location or cluster setup
-attributetype ( 1.3.6.1.4.1.19414.2.1.6
-  NAME 'kolabHost'
-  DESC 'Multivalued -- list of hostnames in a Kolab setup'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-# fqdn of the server containg the actual user mailbox
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.1
-  NAME 'kolabHomeServer'
-  DESC 'server which keeps the users mailbox'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-# flag for allowing unrestriced length of mails
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.2
-  NAME 'unrestrictedMailSize'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
-
-# Specifies the email delegates.
-# An email delegate can send email on behalf of the account  
-# which means using the "from" of the account.
-# Delegates are specified by the syntax of rfc822 email addresses.
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.3
-  NAME 'kolabDelegate'
-  DESC 'Kolab user allowed to act as delegates - RFC822 Mailbox/Alias'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-# For user, group and resource Kolab accounts
-# Describes how to respond to invitations
-# We keep the attribute as a string, but actually it can only have one 
-# of the following values:
-#
-#  ACT_ALWAYS_ACCEPT
-#  ACT_ALWAYS_REJECT
-#  ACT_REJECT_IF_CONFLICTS
-#  ACT_MANUAL_IF_CONFLICTS
-#  ACT_MANUAL
-# In addition one of these values may be prefixed with a primary email 
-# address followed by a colon like
-# user@domain.tld: ACT_ALWAYS_ACCEPT
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.4
-  NAME ( 'kolabInvitationPolicy' 'kolabResourceAction' )
-  DESC 'defines how to respond to invitations'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-# time span from now to the future used for the free busy data
-# measured in days
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.5
-  NAME 'kolabFreeBusyFuture' 
-  DESC 'time in days for fb data towards the future'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 
-  SINGLE-VALUE )
-
-# time span from now to the past used for the free busy data
-# measured in days
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.6
-  NAME 'kolabFreeBusyPast'
-  DESC 'time in days for fb data towards the past'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-  SINGLE-VALUE )
-
-# fqdn of the server as the default SMTP MTA
-# not used in Kolab 2 currently as in Kolab 2 the
-# default MTA is equivalent to the kolabHomeServer
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.7
-  NAME 'kolabHomeMTA'
-  DESC 'fqdn of default MTA'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
-  SINGLE-VALUE )
-
-# Begin date of Kolab vacation period. Sender will
-# be notified every kolabVacationResendIntervall days 
-# that recipient is absent until kolabVacationEnd.
-# Values in this syntax are encoded as printable strings,
-# represented as specified in X.208. 
-# Note that the time zone must be specified. 
-# For Kolab we limit ourself to  GMT
-# YYYYMMDDHHMMZ e.g. 200512311458Z.
-# see also: rfc 2252.
-# Currently this attribute is not used in Kolab.
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.8
-  NAME 'kolabVacationBeginDateTime'
-  DESC 'Begin date of vacation'
-  EQUALITY generalizedTimeMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
-  SINGLE-VALUE )
-
-# End date of Kolab vacation period. Sender will
-# be notified every kolabVacationResendIntervall days
-# that recipient is absent starting from kolabVacationBeginDateTime.
-# Values in this syntax are encoded as printable strings,
-# represented as specified in X.208.
-# Note that the time zone must be specified.
-# For Kolab we limit ourself to  GMT
-# YYYYMMDDHHMMZ e.g. 200601012258Z.
-# see also: rfc 2252.
-# Currently this attribute is not used in Kolab.
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.9
-  NAME 'kolabVacationEndDateTime'
-  DESC 'End date of vacation'
-  EQUALITY generalizedTimeMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
-  SINGLE-VALUE )
-
-# Intervall in days after which senders get 
-# another vacation message.
-# Currently this attribute is not used in Kolab.
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.10
-  NAME 'kolabVacationResendInterval'
-  DESC 'Vacation notice interval in days'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-  SINGLE-VALUE )
-
-# Email recipient addresses which are handled by the
-# vacation script. There can be multiple kolabVacationAddress
-# entries for each kolabInetOrgPerson.
-# Default is the primary email address and all
-# email aliases of the kolabInetOrgPerson.
-# Currently this attribute is not used in Kolab.
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.11
-  NAME 'kolabVacationAddress'
-  DESC 'Email address for vacation to response upon'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-# Enable sending vacation notices in reaction
-# unsolicited commercial email.
-# Default is no.
-# Currently this attribute is not used in Kolab.
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.12
-  NAME 'kolabVacationReplyToUCE'
-  DESC 'Enable vacation notices to UCE'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
-  SINGLE-VALUE )
-
-# Email recipient domains which are handled by the
-# vacation script. There can be multiple kolabVacationReactDomain
-# entries for each kolabInetOrgPerson
-# Default is to handle all domains.
-# Currently this attribute is not used in Kolab.
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.13
-  NAME 'kolabVacationReactDomain'
-  DESC 'Multivalued -- Email domain for vacation to response upon'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )  
-
-# Forward all incoming emails except UCE if kolabForwardUCE
-# is not set to this email address.
-# There can be multiple kolabForwardAddress entries for 
-# each kolabInetOrgPerson.
-# Currently this attribute is not used in Kolab.
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.14
-  NAME 'kolabForwardAddress'
-  DESC 'Forward email to this address'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-# Keep local copy when forwarding emails to list of
-# kolabForwardAddress. 
-# Default is no.
-# Currently this attribute is not used in Kolab.
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.15
-  NAME 'kolabForwardKeepCopy'
-  DESC 'Keep copy when forwarding'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 
-  SINGLE-VALUE )
-
-# Enable forwarding of UCE. 
-# Default is yes.
-# Currently this attribute is not used in Kolab.
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.16
-  NAME 'kolabForwardUCE'
-  DESC 'Enable forwarding of mails known as UCE'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 
-  SINGLE-VALUE )
-
-# comment when creating or deleting a kolab object
-# a comment might be appropriate. This is most useful
-# for tracability when users get moved to the graveyard 
-# instead of being really deleted. Every entry must be prefixed
-# with an ISO 8601 date string e.g 200604301458Z. All times must 
-# be in zulu timezone.
-attributetype ( 1.3.6.1.4.1.19419.1.1.1.17
-  NAME 'kolabComment'
-  DESC 'multi-value comment'
-  EQUALITY caseIgnoreMatch
-  SUBSTR caseIgnoreSubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )
-
-# kolabFolderType describes the kind of Kolab folder
-# as defined in the kolab format specification. 
-# We will annotate all folders with an entry 
-# /vendor/kolab/folder-type containing the attribute 
-# value.shared set to: <type>[.<subtype>]. 
-# The <type> can be: mail, event, journal, task, note, 
-# or contact. The <subtype> for a mail folder can be 
-# inbox, drafts, sentitems, or junkemail (this one holds 
-# spam mails). For the other <type>s, it can only be 
-# default, or not set.  For other types of folders 
-# supported by the clients, these should be prefixed with 
-# "k-" for KMail, "h-" for Horde and "o-" for Outlook, and 
-# look like for example "kolab.o-voicemail". Other third-party
-# clients shall use the "x-" prefix.
-# We then use the ANNOTATEMORE IMAP extension to 
-# associate the folder type with a folder.
-attributetype ( 1.3.6.1.4.1.19414.2.1.7
-  NAME 'kolabFolderType'
-  DESC 'type of a kolab folder'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
-  SINGLE-VALUE )
-
-######################
-# postfix attributes #
-######################
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.501
-  NAME 'postfix-mydomain'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.502
-  NAME 'postfix-relaydomains'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.503
-  NAME 'postfix-mydestination'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.504
-  NAME 'postfix-mynetworks'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.505
-  NAME 'postfix-relayhost'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.506
-  NAME 'postfix-transport'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.507
-  NAME 'postfix-enable-virus-scan'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.508
-  NAME 'postfix-allow-unauthenticated'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.509
-  NAME 'postfix-virtual'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.510
-  NAME 'postfix-relayport'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-##########################
-# cyrus imapd attributes #
-##########################
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.601
-  NAME 'cyrus-autocreatequota'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.602
-  NAME 'cyrus-admins'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-# enable plain imap without ssl 
-attributetype ( 1.3.6.1.4.1.19414.2.1.603
-  NAME 'cyrus-imap'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 
-  SINGLE-VALUE )
-
-# enable legacy pop3
-attributetype ( 1.3.6.1.4.1.19414.2.1.604
-  NAME 'cyrus-pop3'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
-
-# user specific quota on the cyrus imap server
-attributetype ( 1.3.6.1.4.1.19414.2.1.605
-  NAME 'cyrus-userquota'
-  DESC 'Mailbox hard quota limit in MB'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
-
-# enable secure imap 
-attributetype ( 1.3.6.1.4.1.19414.2.1.606
-  NAME 'cyrus-imaps'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
-
-# enable secure pop3
-attributetype ( 1.3.6.1.4.1.19414.2.1.607
-  NAME 'cyrus-pop3s'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
-
-# enable sieve support (required for forward and vacation services)
-attributetype ( 1.3.6.1.4.1.19414.2.1.608
-  NAME 'cyrus-sieve'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
-
-# installation wide percentage which determines when to send a 
-# warning to the user
-attributetype ( 1.3.6.1.4.1.19414.2.1.609
-  NAME 'cyrus-quotawarn'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
-
-#############################
-# apache and php attributes #
-#############################
-
-# enable plain http (no ssl)
-attributetype ( 1.3.6.1.4.1.19414.2.1.701
-  NAME 'apache-http'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
-
-# Allow freebusy download without authenticating first
-attributetype ( 1.3.6.1.4.1.19414.2.1.702
-  NAME 'apache-allow-unauthenticated-fb'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
-
-##########################
-# kolabfilter attributes #
-##########################
-
-# enable trustable From:
-attributetype ( 1.3.6.1.4.1.19414.2.1.750
-  NAME 'kolabfilter-verify-from-header'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
-
-# should Sender header be allowed instead of From
-# when present?
-attributetype ( 1.3.6.1.4.1.19414.2.1.751
-  NAME 'kolabfilter-allow-sender-header'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
-
-# Should reject messages with From headers that dont match
-# the envelope? Default is to rewrite the header
-attributetype ( 1.3.6.1.4.1.19414.2.1.752
-  NAME 'kolabfilter-reject-forged-from-header'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
-
-######################
-# proftpd attributes #
-######################
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.901
-  NAME 'proftpd-defaultquota'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.902
-  NAME 'proftpd-ftp'
-  EQUALITY booleanMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
-
-attributetype ( 1.3.6.1.4.1.19414.2.1.903
-  NAME 'proftpd-userPassword'
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-########################
-# kolab object classes #
-########################
-
-# main kolab server configuration
-# storing global values and user specific default values
-# like kolabFreeBusyFuture and kolabFreeBusyPast
-objectclass ( 1.3.6.1.4.1.19414.2.2.1 
-  NAME 'kolab'
-  DESC 'Kolab server configuration'
-  SUP top STRUCTURAL
-  MUST k
-  MAY ( kolabHost $
-        postfix-mydomain $
-        postfix-relaydomains $
-        postfix-mydestination $
-        postfix-mynetworks $
-        postfix-relayhost $
-        postfix-relayport $
-        postfix-transport $
-        postfix-virtual $
-        postfix-enable-virus-scan $
-        postfix-allow-unauthenticated $
-        cyrus-quotawarn $
-        cyrus-autocreatequota $
-        cyrus-admins $
-        cyrus-imap $
-        cyrus-pop3 $
-        cyrus-imaps $
-        cyrus-pop3s $
-        cyrus-sieve $
-        apache-http $
-        apache-allow-unauthenticated-fb $
-        kolabfilter-verify-from-header $
-        kolabfilter-allow-sender-header $
-        kolabfilter-reject-forged-from-header $
-        proftpd-ftp $
-        proftpd-defaultquota $
-        kolabFreeBusyFuture $
-        kolabFreeBusyPast $
-        uid $
-        userPassword ) )
-
-# public folders are typically visible to everyone subscribed to 
-# the server without the need for an extra login. Subfolders are
-# defined using the hiarchy seperator '/' e.g. "sf/sub1". Please note
-# that the term public folder is prefered to shared folder because 
-# normal user mailboxes can also share folders using acls.
-objectclass ( 1.3.6.1.4.1.19414.2.2.9 
-  NAME 'kolabSharedFolder'
-  DESC 'Kolab public shared folder'
-  SUP top AUXILIARY
-  MUST cn
-  MAY ( acl $
-        alias $
-        cyrus-userquota $
-        kolabHomeServer $
-        kolabFolderType $
-        kolabDeleteflag ) )
-
-# kolabNamedObject is used as a plain node for the LDAP tree. 
-# In contrast to unix filesystem directories LDAP nodes can 
-# and often do also have contents/attributes. We use the 
-# kolabNamedObject in order to put some structure in the 
-# LDAP directory tree.
-objectclass ( 1.3.6.1.4.1.5322.13.1.1 
-  NAME 'kolabNamedObject'
-  SUP top STRUCTURAL
-  MAY (cn $ ou) )
-
-# kolab account
-# we use an auxiliary in order to ease integration
-# with existing inetOrgPerson objects
-# Please note that userPassword is a may 
-# attribute in the schema but is mandatory for
-# Kolab 
-objectclass ( 1.3.6.1.4.1.19414.3.2.2
-  NAME 'kolabInetOrgPerson'
-  DESC 'Kolab Internet Organizational Person'
-  SUP top AUXILIARY
-  MAY ( c $
-        alias $
-        kolabHomeServer $
-        kolabHomeMTA $
-        unrestrictedMailSize $
-        kolabDelegate $
-        kolabEncryptedPassword $
-        cyrus-userquota $
-        kolabInvitationPolicy $
-        kolabFreeBusyFuture $
-        calFBURL $
-       kolabVacationBeginDateTime $
-       kolabVacationEndDateTime $
-       kolabVacationResendInterval $
-       kolabVacationAddress $
-       kolabVacationReplyToUCE $
-       kolabVacationReactDomain $
-       kolabForwardAddress $
-       kolabForwardKeepCopy $
-        kolabForwardUCE $
-        kolabDeleteflag $
-        kolabComment ) )
-
-# kolab organization with country support
-objectclass ( 1.3.6.1.4.1.19414.3.2.3 
-  NAME 'kolabOrganization'
-  DESC 'RFC2256: a Kolab organization'
-  SUP organization STRUCTURAL
-  MAY ( c $
-        mail $
-        kolabDeleteflag $
-        alias ) )
-
-# kolab organizational unit with country support
-objectclass ( 1.3.6.1.4.1.19414.3.2.4 
-  NAME 'kolabOrganizationalUnit'
-  DESC 'a Kolab organizational unit'
-  SUP organizationalUnit STRUCTURAL
-  MAY ( c $
-        mail $
-        kolabDeleteflag $
-        alias ) )
-
-# kolab groupOfNames with extra kolabDeleteflag and the required 
-# attribute mail.    
-# The mail attribute for kolab objects of the type kolabGroupOfNames 
-# is not arbitrary but MUST be a single attribute of the form 
-# of an valid SMTP address with the CN as the local part.
-# E.g cn@kolabdomain (e.g. employees@mydomain.com). The    
-# mail attribute MUST be globally unique.    
-objectclass ( 1.3.6.1.4.1.19414.3.2.5    
-  NAME 'kolabGroupOfNames'    
-  DESC 'Kolab group of names (DNs) derived from RFC2256'    
-  SUP top AUXILIARY    
-  MAY ( mail $    
-        kolabDeleteflag ) )
diff --git a/contrib/openldap/nagios.schema b/contrib/openldap/nagios.schema
deleted file mode 100644 (file)
index caa56af..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-#
-## schema file for OpenLDAP 2.x
-## Schema for storing Nagios User Configuration in LDAP
-## OIDs are owned by OpenSides
-##
-## number from 1 to 30 are for objectclasses
-## attributeype start at 31
-#
-# $Id: nagios.schema,v 1.5 2005/09/09 10:31:55 guiguidoc Exp $
-#
-# nagios/contacts.cfg
-#
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.31 NAME 'NagiosMail'
-        DESC 'short name used to identify the contact'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.32 NAME 'NagiosPager'
-        DESC 'pager number for the contact'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.33 NAME 'NagiosAlias'
-        DESC 'longer name or description for the contact'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.34 NAME 'ServiceNotificationPeriod'
-        DESC 'time period during wich the contact can be notified'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.35 NAME 'HostNotificationPeriod'
-        DESC 'time period during which the contact can be notified'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.36 NAME 'ServiceNotificationOptions'
-        DESC 'define the service states for which notifications can be sent out'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.37 NAME 'HostNotificationOptions'
-        DESC 'define the service states for which notifications can be sent out'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.38 NAME 'ServiceNotificationCommands'
-        DESC 'commands used to notify the contact'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.39 NAME 'HostNotificationCommands'
-        DESC 'commands used to notify the contact'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-#
-# nagios/cgi.cfg
-#
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.40 NAME 'AuthorizedSystemInformation'
-        DESC 'users who can view system/process information'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.41 NAME 'AuthorizedConfigurationInformation'
-        DESC 'users who can view configuration information'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.42 NAME 'AuthorizedSystemCommands'
-        DESC 'users who can issue system/process commands'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.43 NAME 'AuthorizedAllServices'
-        DESC 'users who can view status and configuration information'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.44 NAME 'AuthorizedAllHosts'
-        DESC 'users who can view status and configuration information'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.45 NAME 'AuthorizedAllServiceCommands'
-        DESC 'users who can issue commands for all services'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.46 NAME 'AuthorizedAllHostCommands'
-        DESC 'users who can issue commands for all hosts'
-        EQUALITY caseIgnoreIA5Match
-       SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-#
-# nagios/contactgroups.cfg
-#
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.47 NAME 'ContactGroupName'
-        DESC 'name used to identify the contact group'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.48 NAME 'ContactGroupAlias'
-        DESC 'description used to identify the contact group'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.49 NAME 'ContactGroupMembers'
-        DESC 'a list of the short names of contacts'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-#
-# all objectclass 
-#
-
-objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.1 NAME 'nagiosAuth' SUP top AUXILIARY
- DESC 'nagiosAuth'
- MAY ( AuthorizedSystemInformation $ AuthorizedConfigurationInformation $ 
-       AuthorizedSystemCommands $ AuthorizedAllServices $ AuthorizedAllHosts $
-       AuthorizedAllServiceCommands $ AuthorizedAllHostCommands ) )
-
-#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.2 NAME 'nagiosHost' SUP top AUXILIARY
-# DESC 'Host'
-
-#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.3 NAME 'nagiosService' SUP top AUXILIARY
-# DESC 'Service'
-
-objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.4 NAME 'nagiosContact' SUP top AUXILIARY
- DESC 'Contact'
- MUST (        uid $ NagiosAlias $ ServiceNotificationPeriod $ HostNotificationPeriod $ 
-       ServiceNotificationOptions $ HostNotificationOptions  ) 
- MAY ( ServiceNotificationCommands $ HostNotificationCommands $ NagiosMail $ NagiosPager  ))
-
-#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.5 NAME 'nagiosHostGroup' SUP top AUXILIARY
-# DESC 'HostGroup'
-
-objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.6 NAME 'nagiosContactGroup' SUP top AUXILIARY
- DESC 'ContactGroup'
- MAY ( ContactGroupName $ ContactGroupAlias $ ContactGroupMembers  ))
-
-#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.7 NAME 'nagiosTimePeriod' SUP top AUXILIARY
-# DESC 'TimePeriod'
-
-#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.8 NAME 'nagiosCommand' SUP top AUXILIARY
-# DESC 'Command'
-
-#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.9 NAME 'nagiosServiceDependency' SUP top AUXILIARY
-# DESC 'ServiceDependency'
-
-#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.10 NAME 'nagiosServiceEscalation' SUP top AUXILIARY
-# DESC 'ServiceEscalation'
-
-#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.11 NAME 'nagiosHostDependency' SUP top AUXILIARY
-# DESC 'HostDependency'
-
-#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.12 NAME 'nagiosHostEscalation' SUP top AUXILIARY
-# DESC 'HostEscalation'
-
-#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.13 NAME 'nagiosHostGroupEscalation' SUP top AUXILIARY
-# DESC 'HostGroupEscalation'
-
diff --git a/contrib/openldap/openxchange.schema b/contrib/openldap/openxchange.schema
deleted file mode 100644 (file)
index e32e837..0000000
+++ /dev/null
@@ -1,714 +0,0 @@
-#
-# OPEN X CHANGE ORG - SCHEMA 0.1 
-#
-attributetype ( 1.1.2.1.1.1 NAME ( 'mailEnabled' )
-       DESC 'Is the user enabled or not, for pam_ldap,postfix etc. filtering...'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.2 NAME ( 'alias' )
-       DESC 'email alias'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
-
-attributetype ( 1.1.2.1.1.3 NAME ( 'imapServer' )
-       DESC 'Users Imap Server'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.4 NAME ( 'imapPort' )
-       DESC 'Users Imap Server Port'
-       SUP ipServicePort )
-
-attributetype ( 1.1.2.1.1.5 NAME ( 'sievePort' ) 
-       DESC 'Users SIEVE Server Port'
-       SUP ipServicePort )
-
-attributetype ( 1.1.2.1.1.6 NAME ( 'smtpServer' )
-       DESC 'Users SMTP Server'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.7 NAME ( 'smtpPort' )
-       DESC 'Users SMTP Server Port'
-       SUP ipServicePort )
-
-attributetype ( 1.1.2.1.1.8 NAME ( 'relClientCert' )
-       DESC 'Users Certificate for Ip Service like SMTP or IMAP'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.9 NAME ( 'userCountry' )
-        DESC 'Users country code'
-        SUP name SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.10 NAME ( 'loginDestination' )
-       DESC 'Users Destination - Groupware , Webmail, Config ...'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.11 NAME ( 'birthDay' )
-       DESC 'Users birthday'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.12 NAME ( 'colocRouteAddr' )
-       DESC 'route mail to this address'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.13 NAME ( 'reject' )
-       DESC 'Should contain the mailaddys to reject'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-attributetype ( 1.1.2.1.1.14 NAME ( 'lnetMailAccess' )
-       DESC 'Is the user able to send mail to the inet'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.15 NAME ( 'OXGroupwareStyle' )
-       DESC 'Groupware Style'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.16 NAME ( 'OXWebmailStyle' )
-       DESC 'Webmail Style'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.17 NAME 'OXGroupID'
-        DESC 'GIDs of the secondary Groups of the User'
-        EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27)
-
-attributetype ( 1.1.2.1.1.18 NAME ( 'OXAppointmentDays' )
-       DESC 'Days to display new appointments'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-
-attributetype ( 1.1.2.1.1.19 NAME ( 'OXTaskDays' )
-       DESC 'Days to display new tasks'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.20 NAME ( 'OXTimeZone' )
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.21 NAME ( 'groupwareServer' )
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.22 NAME ( 'groupwareServerPort' )
-       SUP ipServicePort )
-
-attributetype ( 1.1.2.1.1.23 NAME ( 'webmailServer' )
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.24 NAME ( 'webmailServerPort' )
-       SUP ipServicePort )
-
-attributetype ( 1.1.2.1.1.25 NAME ( 'DBServer' )
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.26 NAME ( 'DBServerPort' )
-       SUP ipServicePort SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.27 NAME ( 'DBServerType' )
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.29 NAME ( 'resourceGroupName' ) 
-       SUP name SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.30 NAME ( 'resourceGroupMember' )
-       DESC 'resource that is member of a resource group'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
-
-attributetype ( 1.1.2.1.1.31 NAME ( 'resourceGroupAvailable' )
-        DESC 'Ressource group available in OX'
-       EQUALITY booleanMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.32 NAME ( 'resourceGroupDescription' ) 
-       SUP description SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.33 NAME ( 'resourceName' ) 
-       SUP name SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.34 NAME ( 'resourceAvailable' )
-        DESC 'Ressource available in OX'
-       EQUALITY booleanMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.35 NAME ( 'resourceDescription' ) 
-       SUP description SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.36 NAME ( 'mailDomain' )
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.37 NAME ( 'vaddress' )
-       DESC 'vadress'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-attributetype ( 1.1.2.1.1.38  NAME ( 'MTALocaldomain' )
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.39 NAME ( 'mailDeliveryProgram' )
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
-
-attributetype ( 1.1.2.1.1.40 NAME ( 'deliverToUID' )
-       DESC 'direct mail delivery'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
-
-attributetype ( 1.1.2.1.1.41 NAME ( 'fn' ) SUP name )
-
-attributetype ( 1.1.2.1.1.42 NAME ( 'smtpDomainTransportNexthop' )
-       DESC 'contain transport:[nexthop] mail routing information'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.43 NAME ( 'smtpDomain' )
-       DESC 'contain host/domain name, used with smtpDomainTransportNexthop'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
-
-
-
-########### Special Attributes for new Contact Handling (OL)  ###############################
-
-attributetype ( 1.1.2.1.1.44 NAME ( 'IPPhone' )
-        DESC 'User IPPhone Address in Outlook'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.1.2.1.1.45 NAME ( 'url' )
-        DESC 'Users business Homepage'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.46 NAME ( 'otherpager' )
-        DESC 'Users Business pager'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.47 NAME ( 'otherfacsimiletelephonenumber' )
-        DESC 'Users Home fax number'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.1.2.1.1.48 NAME ( 'middleName' )
-        DESC 'Users middlename'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.49 NAME ( 'conferenceInformation' )
-        DESC 'Users n3tmeeting Info'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-########### END - Special Attributes for new Contact Handling (OL)  ###############################
-
-########### Special Attributes for new Contact Handling (OX) ##############################
-
-attributetype ( 1.1.2.1.1.50 NAME ( 'OXUserPosition' )
-        DESC 'Users position'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.51 NAME ( 'OXUserSalesVolume' )
-        DESC 'Users sales volume'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.1.2.1.1.52 NAME ( 'OXUserCity' )
-        DESC 'Users City'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.1.2.1.1.53 NAME ( 'OXUserTaxID' )
-        DESC 'Users Tax ID'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.1.2.1.1.54 NAME ( 'OXUserComReg' )
-        DESC 'Users Commercial Register'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.1.2.1.1.55 NAME ( 'OXUserBranches' )
-        DESC 'Users Branches'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.1.2.1.1.56 NAME ( 'OXUserAssistant' )
-        DESC 'Users Assistant'
-       SUP manager )
-
-attributetype ( 1.1.2.1.1.57 NAME ( 'OXUserCategories' )
-        DESC 'Users Categories'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.58 NAME ( 'OXUserOtherStreet' )
-        DESC 'Users alternative Street'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.1.2.1.1.59 NAME ( 'OXUserOtherPostalCode' )
-        DESC 'Users alternative postal code'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.60 NAME ( 'OXUserOtherCity' )
-        DESC 'Users alternative city'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.61 NAME ( 'OXUserOtherState' )
-        DESC 'Users alternative State'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.1.2.1.1.62 NAME ( 'OXUserOtherCountry' )
-        DESC 'Users alternative Country'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.63 NAME ( 'OXUserTeleAssistant' )
-        DESC 'Users Assistant TelephoneNumber'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.1.2.1.1.64 NAME ( 'OXUserTeleBusiness2' )
-        DESC 'Users alternative business phone number'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.1.2.1.1.65 NAME ( 'OXUserTeleCallback' )
-        DESC 'Users Callback'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.1.2.1.1.66 NAME ( 'OXUserTeleCar' )
-        DESC 'Users Car Phone Number'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.67 NAME ( 'OXUserTeleCompany' )
-        DESC 'Users Company Phone'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.68 NAME ( 'OXUserTeleHome2' )
-        DESC 'Users 2nd. Home Phone '
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.69 NAME ( 'OXUserTeleMobile2' )
-        DESC 'Users 2nd mobile number'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.70 NAME ( 'OXUserTeleOther' )
-        DESC 'Users other Phone'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.71 NAME ( 'OXUserTeleFax2' )
-        DESC 'Users 2nd Telefax Number'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.72 NAME ( 'OXUserTelePrimary' )
-        DESC 'Users primary Phone'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.73 NAME ( 'OXUserTeleRadio' )
-        DESC 'Users Radio'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.74 NAME ( 'OXUserTeleTTY' )
-        DESC 'Users TTY/tdd '
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.75 NAME ( 'OXUserInstantMessenger' )
-        DESC 'Users IM'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.76 NAME ( 'OXUserInstantmessenger2' )
-        DESC 'Users 2nd IM'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.77 NAME ( 'OXUserEmail2' )
-        DESC 'Users 2nd Email'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.78 NAME ( 'OXUserEmail3' )
-        DESC 'Users 3rd Email'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.79 NAME ( 'OXUserUserUndef01' )
-        DESC 'Users custom field 01'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.80 NAME ( 'OXUserUserUndef02' )
-        DESC 'Users custom field 02'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.81 NAME ( 'OXUserUserUndef03' )
-        DESC 'Users custom field 03'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.82 NAME ( 'OXUserUserUndef04' )
-        DESC 'Users custom field 04'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.83 NAME ( 'OXUserUserUndef05' )
-        DESC 'Users custom field 05'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.84 NAME ( 'OXUserUserUndef06' )
-        DESC 'Users custom field 06'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.85 NAME ( 'OXUserUserUndef07' )
-        DESC 'Users custom field 07'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.86 NAME ( 'OXUserUserUndef08' )
-        DESC 'Users custom field 08'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.87 NAME ( 'OXUserUserUndef09' )
-        DESC 'Users custom field 09'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.88 NAME ( 'OXUserUserUndef10' )
-        DESC 'Users custom field 10'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.89 NAME ( 'OXUserUserUndef11' )
-        DESC 'Users custom field 11'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.90 NAME ( 'OXUserUserUndef12' )
-        DESC 'Users custom field 12'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.91 NAME ( 'OXUserUserUndef13' )
-        DESC 'Users custom field 13'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.92 NAME ( 'OXUserUserUndef14' )
-        DESC 'Users custom field 14'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.93 NAME ( 'OXUserUserUndef15' )
-        DESC 'Users custom field 15'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.94 NAME ( 'OXUserUserUndef16' )
-        DESC 'Users custom field 16'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.95 NAME ( 'OXUserUserUndef17' )
-        DESC 'Users custom field 17'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.96 NAME ( 'OXUserUserUndef18' )
-        DESC 'Users custom field 18'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.97 NAME ( 'OXUserUserUndef19' )
-        DESC 'Users custom field 19'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.98 NAME ( 'OXUserUserUndef20' )
-        DESC 'Users custom field 20'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.99 NAME ( 'OXUserSuffix' )
-        DESC 'Users Suffix Name'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.100 NAME ( 'OXUserPostalCode' )
-        DESC 'Users Postal Code address'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.101 NAME ( 'OXUserState' )
-        DESC 'Users State Name'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.102 NAME ( 'OXUserMaritalStatus' )
-        DESC 'Users marital status'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.103 NAME ( 'OXUserChildren' )
-        DESC 'The number of users children '
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.1.2.1.1.104 NAME ( 'OXUserProfession' )
-        DESC 'The Users profession'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.105 NAME ( 'OXUserNickName' )
-        DESC 'Users Nick Name'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.106 NAME ( 'OXUserSpouseName' )
-        DESC 'Users Spouse Name'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.107 NAME ( 'OXUserAnniversary' )
-        DESC 'Any user anniversary'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.108 NAME ( 'OXUserComment' )
-        DESC 'A comment about the Users'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.109 NAME ( 'OXUserDistributionList' )
-        DESC 'uid for the distribution List in the Databse'
-        EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-########### ADDED FOR OX GROUPWARE DAYVIEW ############
-attributetype ( 1.1.2.1.1.110 NAME ( 'OXDayviewInterval' )
-        DESC 'interval for displaying ox appointments on the dayview'
-        EQUALITY integerMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.1.2.1.1.111 NAME ( 'OXDayviewStartTime' )
-        DESC 'starttime for displaying ox appointments on the dayview'
-       EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.1.2.1.1.112 NAME ( 'OXDayviewEndTime' )
-        DESC 'endtime for displaying ox appointments on the dayview'
-       EQUALITY caseIgnoreMatch
-        SUBSTR caseIgnoreSubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-#######################################################
-
-
-### ADDED FOR VDOMAINOBJECT ###
-
-attributetype ( 1.1.2.1.1.113 NAME ( 'domainName' )
-        DESC 'The name of domain'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseIgnoreIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
-
-###############################
-
-
-
-#########################################################################
-
-
-
-#
-# Here we go with the OX Objects ...
-#
-
-objectclass ( 1.1.2.2.1.1 NAME 'OXUserObject' SUP top AUXILIARY
-       DESC 'Additional Objectclass for OX User'
-       MAY ( alias $ imapServer $ imapPort $ sievePort $ mailDomain $ smtpServer $ smtpPort $
-       groupwareServer $ groupwareServerPort $ webmailServer $ webmailServerPort $
-       DBServer $ DBServerPort $ DBServerType $ reject $ relClientCert $ userCountry $ 
-       loginDestination $ birthDay $ colocRouteAddr $ mailEnabled $ lnetMailAccess $ vaddress $ 
-       IPPhone $ url $ otherpager $ otherfacsimiletelephonenumber $ homephone $ 
-       c $ info $ middleName $ co $ conferenceInformation $ telexNumber $
-       OXGroupwareStyle $ OXWebmailStyle $ OXGroupID $ OXAppointmentDays $ OXTaskDays $ OXDayViewInterval $ OXDayViewStartTime $ OXDayViewEndTime $ OXTimeZone $
-       OXUserSuffix $ OXUserPostalCode $ OXUserCity $ OXUserState $ OXUserMaritalStatus $ OXUserChildren $ OXUserProfession $
-       OXUserNickName $ OXUserSpouseName $ OXUserAnniversary $ OXUserComment $
-       OXUserPosition $ OXUserSalesVolume $ OXUserTaxID $ OXUserComReg $ OXUserBranches $
-       OXUserAssistant $ OXUserCategories $ OXUserOtherStreet $ OXUserOtherPostalCode $ OXUserOtherCity $
-       OXUserOtherState $ OXUserOtherCountry $ OXUserTeleAssistant $ OXUserTeleBusiness2 $ OXUserTeleCallback $
-       OXUserTeleCar $ OXUserTeleCompany $ OXUserTeleHome2 $ OXUserTeleMobile2 $ OXUserTeleOther $ OXUserTeleFax2 $
-       OXUserTelePrimary $ OXUserTeleRadio $ OXUserTeleTTY $ OXUserInstantMessenger $ OXUserInstantmessenger2 $
-       OXUserEmail2 $ OXUserEmail3 $ OXUserUserUndef01 $ OXUserUserUndef02 $ OXUserUserUndef03 $ OXUserUserUndef04 $
-       OXUserUserUndef05 $ OXUserUserUndef06 $ OXUserUserUndef07 $ OXUserUserUndef08 $ OXUserUserUndef09 $
-       OXUserUserUndef10 $ OXUserUserUndef11 $ OXUserUserUndef12 $ OXUserUserUndef13 $ OXUserUserUndef14 $
-       OXUserUserUndef15 $ OXUserUserUndef16 $ OXUserUserUndef17 $ OXUserUserUndef18 $ OXUserUserUndef19 $
-       OXUserUserUndef20 $ OXUserDistributionList
-       ))
-
-objectclass ( 1.1.2.2.1.2 NAME 'OXResourceGroupObject' SUP top STRUCTURAL
-       DESC 'Additional Objectclass for OX ResourceGroup'
-       MAY ( resourceGroupName $ resourceGroupMember $ resourceGroupAvailable $ resourceGroupDescription ))
-
-
-objectclass ( 1.1.2.2.1.3 NAME 'OXResourceObject' SUP top STRUCTURAL
-       DESC 'Additional Objectclass for OX Resource'
-       MAY ( resourceName $ resourceAvailable $ resourceDescription ))
-
-objectclass ( 1.1.2.2.1.4 NAME 'OXVDomainObject' SUP top STRUCTURAL
-        DESC 'virtual domains, can be used for lookups for MTA'
-        MUST ( MTALocaldomain $ domainName ))
-
-objectclass ( 1.1.2.2.1.5 NAME 'OXIMAPFolderObject' SUP top STRUCTURAL
-       DESC 'Shared IMAP Folder'
-       MUST fn
-       MAY ( mailDeliveryProgram $ description $ mailEnabled $
-             deliverToUID))
-
-objectclass ( 1.1.2.2.1.6 NAME 'OXMailTransportObject' SUP top STRUCTURAL
-       DESC 'Transport maps in LDAP'
-       MUST ( smtpDomainTransportNexthop $ smtpDomain $ cn )
-       MAY   description )
diff --git a/contrib/openldap/phpgwaccount.schema b/contrib/openldap/phpgwaccount.schema
deleted file mode 100644 (file)
index 3edd263..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-# $Id egroupware : phpgwaccount.schema,v 1.0 2000/07/29 01:53:16 milosch Exp $
-
-# (C) 2001-2004 Miles Lott <milos@groupwhere.org>
-# Redistribution and use in original text and binary forms, with or
-# without modification, are permitted provided that the following
-# conditions are met:
-#
-# 1. Redistributions of this schema and/or documentation must retain
-#    the above copyright notice, this list of conditions and the
-#    following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright notice,
-#    this list of conditions and the following disclaimer in the documentation
-#    and/or other materials provided with the distribution.
-# 3. The name of the author may not be used to endorse or promote products
-#    derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-# lastlogin
-attributetype ( 1.3.6.1.4.1.9554.1
-       NAME 'phpgwAccountLastLogin'
-       DESC 'timestamp of last login'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-       SINGLE-VALUE )
-
-# lastloginfrom
-attributetype ( 1.3.6.1.4.1.9554.2
-       NAME 'phpgwAccountLastLoginFrom'
-       DESC 'IP address as a dotted decimal, eg. 192.168.1.1, omitting leading zeros'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
-
-# lastpasswdchange
-attributetype ( 1.3.6.1.4.1.9554.3
-       NAME 'phpgwLastPasswdChange'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-       SINGLE-VALUE )
-
-# accounttype
-attributetype ( 1.3.6.1.4.1.9554.4
-       NAME 'phpgwAccountType'
-       DESC 'Single-char u/g for user/group'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE )
-
-# status
-attributetype ( 1.3.6.1.4.1.9554.5
-       NAME 'phpgwAccountStatus'
-       DESC 'Single-char A/L for active/inactive'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-       SINGLE-VALUE )
-
-# expires
-attributetype ( 1.3.6.1.4.1.9554.6
-       NAME 'phpgwAccountExpires'
-       DESC 'timestamp for account expiration'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-       SINGLE-VALUE )
-
-# Objectclass definition for phpgwAccount
-objectclass ( 1.3.6.1.4.1.9554.0 NAME 'phpgwAccount' SUP top AUXILIARY
-       DESC 'Abstraction of an account with phpgw attributes'
-       MAY ( phpgwAccountLastLogin $ phpgwAccountLastLoginFrom $ phpgwLastPasswdChange $ phpgwAccountType $ phpgwAccountStatus $ phpgwAccountExpires) )
-
diff --git a/contrib/openldap/phpscheduleit.schema b/contrib/openldap/phpscheduleit.schema
deleted file mode 100644 (file)
index b7450ba..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-## schema file for OpenLDAP 2.x
-## Schema for storing PHPscheduleit User Configuration in LDAP
-## OIDs are owned by OpenSides
-##
-## number from 1 to 50 are for objectclasses
-## attributeype start at 50
-#
-# $Id: phpscheduleit.schema,v 1.1 2005/11/02 16:48:16 guiguidoc Exp $
-#
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.3.1 NAME 'phpscheduleitAccountLogin'
-        DESC 'PHPscheduleit Account Login'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-#
-# all objectclass 
-#
-
-objectclass ( 1.3.6.1.4.1.22262.1.1.2.3.1 NAME 'phpscheduleitAccount' SUP top AUXILIARY
- DESC 'PHPscheduleit Account'
- MAY ( phpscheduleitAccountLogin  ))
\ No newline at end of file
diff --git a/contrib/openldap/pptp.schema b/contrib/openldap/pptp.schema
deleted file mode 100644 (file)
index bf580c4..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#
-## schema file for OpenLDAP 2.x
-## Schema for storing PPTP User Configuration in LDAP
-## OIDs are owned by OpenSides
-##
-## number from 1 to 50 are for objectclasses
-## attributeype start at 50
-#
-# $Id: pptp.schema,v 1.5 2005/11/02 16:47:22 guiguidoc Exp $
-#
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.2.1 NAME 'pptpAccount'
-        DESC 'PPTP Server Account'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.2.2 NAME 'pptpAccountLogin'
-        DESC 'PPTP Server Account Login'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.2.3 NAME 'pptpAccountPassword'
-        DESC 'PPTP Server Account Password'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.4.1.22262.1.1.1.2.4 NAME 'pptpAccountServerIP'
-        DESC 'PPTP Server Account Server IP'
-        EQUALITY caseIgnoreIA5Match
-        SUBSTR caseExactIA5SubstringsMatch
-        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-#
-# all objectclass 
-#
-
-objectclass ( 1.3.6.1.4.1.22262.1.1.2.2.1 NAME 'pptpServerAccount' SUP top AUXILIARY
- DESC 'PPTP Server Account'
- MAY ( pptpAccount  ))
-
diff --git a/contrib/openldap/pureftpd.schema b/contrib/openldap/pureftpd.schema
deleted file mode 100644 (file)
index 1cf95ea..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-# $Id: pureftpd.schema,v 1.2 2004/02/04 15:25:01 cajus Exp $
-#
-# pureftpd.schema
-#
-# Pure-FTPd User LDAP Schema
-# See README.LDAP in the Pure-FTPd documentation for more information.
-#
-# Written 2002-01-24 by Ben Gertzfield <che =AT= debian -DOT- org>
-#
-
-## Pure-FTPd-related LDAP attributes
-
-attributetype ( 1.3.6.1.4.1.6981.11.3.1 NAME 'FTPQuotaFiles'
-       DESC 'Quota (in number of files) for an FTP user'
-        EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.6981.11.3.2 NAME 'FTPQuotaMBytes'
-       DESC 'Quota (in megabytes) for an FTP user'
-        EQUALITY integerMatch        
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.6981.11.3.3 NAME 'FTPUploadRatio'
-       DESC 'Ratio (compared with FTPRatioDown) for uploaded files'
-        EQUALITY integerMatch        
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.6981.11.3.4 NAME 'FTPDownloadRatio'
-       DESC 'Ratio (compared with FTPRatioUp) for downloaded files'
-        EQUALITY integerMatch        
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.6981.11.3.5 NAME 'FTPUploadBandwidth'
-       DESC 'Bandwidth (in KB/s) to limit upload speeds to'
-        EQUALITY integerMatch        
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.6981.11.3.6 NAME 'FTPDownloadBandwidth'
-       DESC 'Bandwidth (in KB/s) to limit download speeds to'
-        EQUALITY integerMatch        
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.6981.11.3.7 NAME 'FTPStatus'
-       DESC 'Account status: enabled or disabled'
-        EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.6981.11.3.8 NAME 'FTPuid'
-       DESC 'System uid (overrides uidNumber if present)'
-        EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.6981.11.3.9 NAME 'FTPgid'
-       DESC 'System uid (overrides gidNumber if present)'
-        EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-## New Pure-FTPd object type
-
-objectclass ( 1.3.6.1.4.1.6981.11.2.3 NAME 'PureFTPdUser' SUP top AUXILIARY
-       DESC 'PureFTPd user with optional quota, throttling, and ratio'
-       MAY ( FTPStatus $ FTPQuotaFiles $ FTPQuotaMBytes $ FTPUploadRatio $ 
-              FTPDownloadRatio $ FTPUploadBandwidth $ FTPDownloadBandwidth $
-              FTPuid $ FTPgid ) )
diff --git a/contrib/openldap/rfc2307bis.schema b/contrib/openldap/rfc2307bis.schema
deleted file mode 100644 (file)
index db34365..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-# builtin
-#
-#attributetype ( 1.3.6.1.1.1.1.0 NAME 'uidNumber'
-#  DESC 'An integer uniquely identifying a user in an administrative domain'
-#  EQUALITY integerMatch
-#  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-#  SINGLE-VALUE )
-
-# builtin
-#
-#attributetype ( 1.3.6.1.1.1.1.1 NAME 'gidNumber'
-#  DESC 'An integer uniquely identifying a group in an
-#        administrative domain'
-#  EQUALITY integerMatch
-#  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-#  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.2 NAME 'gecos'
-  DESC 'The GECOS field; the common name'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.3 NAME 'homeDirectory'
-  DESC 'The absolute path to the home directory'
-  EQUALITY caseExactIA5Match
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.4 NAME 'loginShell'
-  DESC 'The path to the login shell'
-  EQUALITY caseExactIA5Match
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.6 NAME 'shadowMin'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.7 NAME 'shadowMax'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.8 NAME 'shadowWarning'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.9 NAME 'shadowInactive'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.10 NAME 'shadowExpire'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.11 NAME 'shadowFlag'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.12 NAME 'memberUid'
-  EQUALITY caseExactIA5Match
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.1.1.1.13 NAME 'memberNisNetgroup'
-  EQUALITY caseExactIA5Match
-  SUBSTR caseExactIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
-  DESC 'Netgroup triple'
-  EQUALITY caseIgnoreIA5Match
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.1.1.1.15 NAME 'ipServicePort'
-  DESC 'Service port number'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.16 NAME 'ipServiceProtocol'
-  DESC 'Service protocol name'
-  SUP name )
-
-attributetype ( 1.3.6.1.1.1.1.17 NAME 'ipProtocolNumber'
-  DESC 'IP protocol number'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.18 NAME 'oncRpcNumber'
-  DESC 'ONC RPC number'
-  EQUALITY integerMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-  SINGLE-VALUE )
-attributetype ( 1.3.6.1.1.1.1.19 NAME 'ipHostNumber'
-  DESC 'IPv4 addresses as a dotted decimal omitting leading
-        zeros or IPv6 addresses as defined in RFC2373'
-  SUP name )
-
-attributetype ( 1.3.6.1.1.1.1.20 NAME 'ipNetworkNumber'
-  DESC 'IP network as a dotted decimal, eg. 192.168,
-        omitting leading zeros'
-  SUP name
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.21 NAME 'ipNetmaskNumber'
-  DESC 'IP netmask as a dotted decimal, eg. 255.255.255.0,
-        omitting leading zeros'
-  EQUALITY caseIgnoreIA5Match
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.22 NAME 'macAddress'
-  DESC 'MAC address in maximal, colon separated hex
-        notation, eg. 00:00:92:90:ee:e2'
-  EQUALITY caseIgnoreIA5Match
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.1.1.1.23 NAME 'bootParameter'
-  DESC 'rpc.bootparamd parameter'
-  EQUALITY caseExactIA5Match
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.1.1.1.24 NAME 'bootFile'
-  DESC 'Boot image name'
-  EQUALITY caseExactIA5Match
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-attributetype ( 1.3.6.1.1.1.1.26 NAME 'nisMapName'
-  DESC 'Name of a A generic NIS map'
-  SUP name )
-
-attributetype ( 1.3.6.1.1.1.1.27 NAME 'nisMapEntry'
-  DESC 'A generic NIS entry'
-  EQUALITY caseExactIA5Match
-  SUBSTR caseExactIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.28 NAME 'nisPublicKey'
-  DESC 'NIS public key'
-  EQUALITY octetStringMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.29 NAME 'nisSecretKey'
-  DESC 'NIS secret key'
-  EQUALITY octetStringMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.30 NAME 'nisDomain'
-  DESC 'NIS domain'
-  EQUALITY caseIgnoreIA5Match
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
-
-attributetype ( 1.3.6.1.1.1.1.31 NAME 'automountMapName'
-  DESC 'automount Map Name'
-  EQUALITY caseExactIA5Match
-  SUBSTR caseExactIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.32 NAME 'automountKey'
-  DESC 'Automount Key value'
-  EQUALITY caseExactIA5Match
-  SUBSTR caseExactIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.33 NAME 'automountInformation'
-  DESC 'Automount information'
-  EQUALITY caseExactIA5Match
-  SUBSTR caseExactIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount' SUP top AUXILIARY
-  DESC 'Abstraction of an account with POSIX attributes'
-  MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
-  MAY ( userPassword $ loginShell $ gecos $
-        description ) )
-
-objectclass ( 1.3.6.1.1.1.2.1 NAME 'shadowAccount' SUP top AUXILIARY
-  DESC 'Additional attributes for shadow passwords'
-  MUST uid
-  MAY ( userPassword $ description $
-        shadowLastChange $ shadowMin $ shadowMax $
-        shadowWarning $ shadowInactive $
-        shadowExpire $ shadowFlag ) )
-
-objectclass ( 1.3.6.1.1.1.2.2 NAME 'posixGroup' SUP top AUXILIARY
-  DESC 'Abstraction of a group of accounts'
-  MUST gidNumber
-  MAY ( userPassword $ memberUid $
-        description ) )
-
-objectclass ( 1.3.6.1.1.1.2.3 NAME 'ipService' SUP top STRUCTURAL
-  DESC 'Abstraction an Internet Protocol service.
-        Maps an IP port and protocol (such as tcp or udp)
-        to one or more names; the distinguished value of
-        the cn attribute denotes the services canonical
-        name'
-  MUST ( cn $ ipServicePort $ ipServiceProtocol )
-  MAY description )
-
-objectclass ( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' SUP top STRUCTURAL
-  DESC 'Abstraction of an IP protocol. Maps a protocol number
-        to one or more names. The distinguished value of the cn
-        attribute denotes the protocols canonical name'
-  MUST ( cn $ ipProtocolNumber )
-  MAY description )
-
-objectclass ( 1.3.6.1.1.1.2.5 NAME 'oncRpc' SUP top STRUCTURAL
-  DESC 'Abstraction of an Open Network Computing (ONC)
-       [RFC1057] Remote Procedure Call (RPC) binding.
-       This class maps an ONC RPC number to a name.
-       The distinguished value of the cn attribute denotes
-       the RPC services canonical name'
-  MUST ( cn $ oncRpcNumber )
-  MAY description )
-
-objectclass ( 1.3.6.1.1.1.2.6 NAME 'ipHost' SUP top AUXILIARY
-  DESC 'Abstraction of a host, an IP device. The distinguished
-        value of the cn attribute denotes the hosts canonical
-        name. Device SHOULD be used as a structural class'
-  MUST ( cn $ ipHostNumber )
-  MAY ( userPassword $ l $ description $ manager ) )
-
-objectclass ( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' SUP top STRUCTURAL
-  DESC 'Abstraction of a network. The distinguished value of
-        the cn attribute denotes the networks canonical name'
-  MUST ipNetworkNumber
-  MAY ( cn $ ipNetmaskNumber $ l $ description $ manager ) )
-
-objectclass ( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL
-  DESC 'Abstraction of a netgroup. May refer to other netgroups'
-  MUST cn
-  MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) )
-
-objectclass ( 1.3.6.1.1.1.2.9 NAME 'nisMap' SUP top STRUCTURAL
-  DESC 'A generic abstraction of a NIS map'
-  MUST nisMapName
-  MAY description )
-
-objectclass ( 1.3.6.1.1.1.2.10 NAME 'nisObject' SUP top STRUCTURAL
-  DESC 'An entry in a NIS map'
-  MUST ( cn $ nisMapEntry $ nisMapName )
-  MAY description )
-
-objectclass ( 1.3.6.1.1.1.2.11 NAME 'ieee802Device' SUP top AUXILIARY
-  DESC 'A device with a MAC address; device SHOULD be
-        used as a structural class'
-  MAY macAddress )
-
-objectclass ( 1.3.6.1.1.1.2.12 NAME 'bootableDevice' SUP top AUXILIARY
-  DESC 'A device with boot parameters; device SHOULD be
-        used as a structural class'
-  MAY ( bootFile $ bootParameter ) )
-
-objectclass ( 1.3.6.1.1.1.2.14 NAME 'nisKeyObject' SUP top AUXILIARY
-  DESC 'An object with a public and secret key'
-  MUST ( cn $ nisPublicKey $ nisSecretKey )
-  MAY ( uidNumber $ description ) )
-
-objectclass ( 1.3.6.1.1.1.2.15 NAME 'nisDomainObject' SUP top AUXILIARY
-  DESC 'Associates a NIS domain with a naming context'
-  MUST nisDomain )
-
-objectclass ( 1.3.6.1.1.1.2.16 NAME 'automountMap' SUP top STRUCTURAL
-  MUST ( automountMapName )
-  MAY description )
-
-objectclass ( 1.3.6.1.1.1.2.17 NAME 'automount' SUP top STRUCTURAL
-  DESC 'Automount information'
-  MUST ( automountKey $ automountInformation )
-  MAY description )
-## namedObject is needed for groups without members
-objectclass ( 1.3.6.1.4.1.5322.13.1.1 NAME 'namedObject' SUP top
-       STRUCTURAL MAY cn )
-
diff --git a/contrib/openldap/rfc2739.schema b/contrib/openldap/rfc2739.schema
deleted file mode 100644 (file)
index 668628e..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-# (c) 2004 Martin Konold <martin.konold@erfrakon.de>
-
-# This schema is derived from RFC 2739 and may act as a substitute
-# when used with OpenLDAP as the original schema from RFC 2739 
-# is syntactically not accepted by OpenLDAP 2.2.14
-#
-# Copyright (C) The Internet Society (2000).  All Rights Reserved.
-#
-#  This document and translations of it may be copied and furnished to
-#  others, and derivative works that comment on or otherwise explain it
-#  or assist in its implementation may be prepared, copied, published
-#  and distributed, in whole or in part, without restriction of any
-#  kind, provided that the above copyright notice and this paragraph are
-#  included on all such copies and derivative works.  However, this
-#  document itself may not be modified in any way, such as by removing
-#  the copyright notice or references to the Internet Society or other
-#  Internet organizations, except as needed for the purpose of
-#  developing Internet standards in which case the procedures for
-#  copyrights defined in the Internet Standards process must be
-#  followed, or as required to translate it into languages other than
-#  English.
-#
-#  The limited permissions granted above are perpetual and will not be
-#  revoked by the Internet Society or its successors or assigns.
-#
-#  This document and the information contained herein is provided on an
-#  "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
-#  TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
-#  BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
-#  HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
-#  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-# slapd.conf then looks like
-#  include /kolab/etc/openldap/schema/core.schema
-#  include /kolab/etc/openldap/schema/cosine.schema
-#  include /kolab/local/etc/openldap/schema/inetorgperson.schema
-#  include /kolab/local/etc/openldap/schema/rfc2739.schema
-#  include /kolab/local/etc/openldap/schema/kolab2.schema
-
-#
-################################
-# rfc 2739 calendar attributes #
-################################
-
-# contains the URI to a snapshot of the user's entire
-# default calendar
-attributetype ( 1.2.840.113556.1.4.478
-  NAME 'calCalURI'
-  DESC 'RFC2739: URI of entire default calendar'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  USAGE userApplications )
-
-# contains the URI to the user's default
-# busy time data
-attributetype (1.2.840.113556.1.4.479
-  NAME 'calFBURL'
-  DESC 'RFC2739: URI to the users default freebusy data'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  USAGE userApplications )
-
-# contains a URI that can be used to communicate with 
-# the user's calendar
-attributetype (1.2.840.113556.1.4.480
-  NAME 'calCAPURI'
-  DESC 'RFC2739: URI used to communicate with the users calendar'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  USAGE userApplications )
-
-# contains a URI that points to the location to which event
-# requests should be sent for that user
-attributetype (1.2.840.113556.1.4.481
-  NAME 'calCalAdrURI'
-  DESC 'RFC2739: URI for event equests destination'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  USAGE userApplications )
-
-# multi-valued property containing URIs to snapshots of 
-# other calendars that the user may have
-attributetype (1.2.840.113556.1.4.482
-  NAME 'calOtherCalURIs'
-  DESC 'RFC2739: multi-value URI for snapshots of other calendars'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  USAGE userApplications )
-
-# multi-valued property containing URIs to snapshots of other 
-# free/busy data that the user may have
-attributetype (1.2.840.113556.1.4.483
-  NAME 'calOtherFBURLs'
-  DESC 'RFC2739: multi-value URI for other free/busy data'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  USAGE userApplications )
-
-# multi-valued property containing URI to other calendars that
-# the user may have
-attributetype (1.2.840.113556.1.4.484
-  NAME 'calOtherCAPURIs'
-  DESC 'RFC2739: multi-value URI to other calendars'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  USAGE userApplications )
-
-#  URIs to other locations that a user may want
-#   event requests sent to
-attributetype (1.2.840.113556.1.4.485
-  NAME 'calOtherCalAdrURIs'
-  DESC 'RFC2739: multi-value URI to other request destinations'
-  EQUALITY caseIgnoreIA5Match
-  SUBSTR caseIgnoreIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  USAGE userApplications )
-
-objectclass (1.2.840.113556.1.5.87
-  NAME 'calEntry'
-  DESC 'RFC2739: Calendar Entry'
-  SUP top AUXILIARY
-  MAY ( calCalURI $ 
-        calFBURL $
-        calOtherCalURIs $
-        calOtherFBURLs $
-        calCAPURI $
-        calOtherCAPURIs ) )
diff --git a/contrib/openldap/samba.schema b/contrib/openldap/samba.schema
deleted file mode 100644 (file)
index f71c344..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-##
-## schema file for OpenLDAP 2.0.x
-## Schema for storing Samba's smbpasswd file in LDAP
-## OIDs are owned by the Samba Team
-##
-## Prerequisite schemas - uid (cosine.schema)
-##                      - displayName (inetorgperson.schema)
-##
-## 1.3.6.1.4.1.7165.2.1.x - attributetypes
-## 1.3.6.1.4.1.7165.2.2.x - objectclasses
-##
-
-##
-## Password hashes
-##
-attributetype ( 1.3.6.1.4.1.7165.2.1.1 NAME 'lmPassword'
-       DESC 'LanManager Passwd'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.2 NAME 'ntPassword'
-       DESC 'NT Passwd'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
-
-##
-## Account flags in string format ([UWDX     ])
-##
-attributetype ( 1.3.6.1.4.1.7165.2.1.4 NAME 'acctFlags'
-       DESC 'Account Flags'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE )
-
-## 
-## Password timestamps & policies
-##
-attributetype ( 1.3.6.1.4.1.7165.2.1.3 NAME 'pwdLastSet'
-       DESC 'NT pwdLastSet'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.5 NAME 'logonTime'
-       DESC 'NT logonTime'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.6 NAME 'logoffTime'
-       DESC 'NT logoffTime'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.7 NAME 'kickoffTime'
-       DESC 'NT kickoffTime'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.8 NAME 'pwdCanChange'
-       DESC 'NT pwdCanChange'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.9 NAME 'pwdMustChange'
-       DESC 'NT pwdMustChange'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-##
-## string settings
-##
-attributetype ( 1.3.6.1.4.1.7165.2.1.10 NAME 'homeDrive'
-       DESC 'NT homeDrive'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.11 NAME 'scriptPath'
-       DESC 'NT scriptPath'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.12 NAME 'profilePath'
-       DESC 'NT profilePath'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.13 NAME 'userWorkstations'
-       DESC 'userWorkstations'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.17 NAME 'smbHome'
-       DESC 'smbHome'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.18 NAME 'domain'
-       DESC 'Windows NT domain to which the user belongs'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
-
-##
-## user and group RID
-##
-attributetype ( 1.3.6.1.4.1.7165.2.1.14 NAME 'rid'
-       DESC 'NT rid'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.15 NAME 'primaryGroupID'
-       DESC 'NT Group RID'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-##
-## The smbPasswordEntry objectclass has been depreciated in favor of the
-## sambaAccount objectclass
-##
-#objectclass ( 1.3.6.1.4.1.7165.2.2.1 NAME 'smbPasswordEntry' SUP top AUXILIARY
-#        DESC 'Samba smbpasswd entry'
-#        MUST ( uid $ uidNumber )
-#        MAY  ( lmPassword $ ntPassword $ pwdLastSet $ acctFlags ))
-
-#objectclass ( 1.3.6.1.4.1.7165.2.2.2 NAME 'sambaAccount' SUP top STRUCTURAL
-#      DESC 'Samba Account'
-#      MUST ( uid $ rid ) 
-#      MAY  ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
-#               logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $ 
-#               displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
-#               description $ userWorkstations $ primaryGroupID $ domain ))
-
-## The X.500 data model (and therefore LDAPv3) says that each entry can 
-## only have one structural objectclass.  OpenLDAP 2.0 does not enforce 
-## this currently but will in v2.1
-
-objectclass ( 1.3.6.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY
-       DESC 'Samba Auxilary Account'
-       MUST ( uid $ rid ) 
-       MAY  ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
-               logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $ 
-               displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
-               description $ userWorkstations $ primaryGroupID $ domain ))
-
-##
-## Used for Winbind experimentation
-##
-#objectclass ( 1.3.6.1.4.1.7165.1.2.2.3 NAME 'uidPool' SUP top AUXILIARY
-#      DESC 'Pool for allocating UNIX uids'
-#      MUST ( uidNumber $ cn ) )
-
-#objectclass ( 1.3.6.1.4.1.7165.1.2.2.4 NAME 'gidPool' SUP top AUXILIARY
-#      DESC 'Pool for allocating UNIX gids'
-#      MUST ( gidNumber $ cn ) )
-
diff --git a/contrib/openldap/samba3.schema b/contrib/openldap/samba3.schema
deleted file mode 100644 (file)
index 7dc4de5..0000000
+++ /dev/null
@@ -1,480 +0,0 @@
-##
-## schema file for OpenLDAP 2.x
-## Schema for storing Samba user accounts and group maps in LDAP
-## OIDs are owned by the Samba Team
-##
-## Prerequisite schemas - uid         (cosine.schema)
-##                      - displayName (inetorgperson.schema)
-##                      - gidNumber   (nis.schema)
-##
-## 1.3.6.1.4.1.7165.2.1.x - attributetypes
-## 1.3.6.1.4.1.7165.2.2.x - objectclasses
-##
-## Printer support
-## 1.3.6.1.4.1.7165.2.3.1.x - attributetypes
-## 1.3.6.1.4.1.7165.2.3.2.x - objectclasses
-##
-## ----- READ THIS WHEN ADDING A NEW ATTRIBUTE OR OBJECT CLASS ------
-##
-## Run the 'get_next_oid' bash script in this directory to find the 
-## next available OID for attribute type and object classes.
-##
-##   $ ./get_next_oid
-##   attributetype ( 1.3.6.1.4.1.7165.2.1.XX NAME ....
-##   objectclass ( 1.3.6.1.4.1.7165.2.2.XX NAME ....
-##
-## Also ensure that new entries adhere to the declaration style
-## used throughout this file
-##
-##    <attributetype|objectclass> ( 1.3.6.1.4.1.7165.2.XX.XX NAME ....
-##                               ^ ^                        ^
-##
-## The spaces are required for the get_next_oid script (and for 
-## readability).
-##
-## ------------------------------------------------------------------
-
-# objectIdentifier SambaRoot 1.3.6.1.4.1.7165
-# objectIdentifier Samba3 SambaRoot:2
-# objectIdentifier Samba3Attrib Samba3:1
-# objectIdentifier Samba3ObjectClass Samba3:2
-
-########################################################################
-##                            HISTORICAL                              ##
-########################################################################
-
-##
-## Password hashes
-##
-#attributetype ( 1.3.6.1.4.1.7165.2.1.1 NAME 'lmPassword'
-#      DESC 'LanManager Passwd'
-#      EQUALITY caseIgnoreIA5Match
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.2 NAME 'ntPassword'
-#      DESC 'NT Passwd'
-#      EQUALITY caseIgnoreIA5Match
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
-
-##
-## Account flags in string format ([UWDX     ])
-##
-#attributetype ( 1.3.6.1.4.1.7165.2.1.4 NAME 'acctFlags'
-#      DESC 'Account Flags'
-#      EQUALITY caseIgnoreIA5Match
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE )
-
-##
-## Password timestamps & policies
-##
-#attributetype ( 1.3.6.1.4.1.7165.2.1.3 NAME 'pwdLastSet'
-#      DESC 'NT pwdLastSet'
-#      EQUALITY integerMatch
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.5 NAME 'logonTime'
-#      DESC 'NT logonTime'
-#      EQUALITY integerMatch
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.6 NAME 'logoffTime'
-#      DESC 'NT logoffTime'
-#      EQUALITY integerMatch
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.7 NAME 'kickoffTime'
-#      DESC 'NT kickoffTime'
-#      EQUALITY integerMatch
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.8 NAME 'pwdCanChange'
-#      DESC 'NT pwdCanChange'
-#      EQUALITY integerMatch
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.9 NAME 'pwdMustChange'
-#      DESC 'NT pwdMustChange'
-#      EQUALITY integerMatch
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-##
-## string settings
-##
-#attributetype ( 1.3.6.1.4.1.7165.2.1.10 NAME 'homeDrive'
-#      DESC 'NT homeDrive'
-#      EQUALITY caseIgnoreIA5Match
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.11 NAME 'scriptPath'
-#      DESC 'NT scriptPath'
-#      EQUALITY caseIgnoreIA5Match
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.12 NAME 'profilePath'
-#      DESC 'NT profilePath'
-#      EQUALITY caseIgnoreIA5Match
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.13 NAME 'userWorkstations'
-#      DESC 'userWorkstations'
-#      EQUALITY caseIgnoreIA5Match
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.17 NAME 'smbHome'
-#      DESC 'smbHome'
-#      EQUALITY caseIgnoreIA5Match
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.18 NAME 'domain'
-#      DESC 'Windows NT domain to which the user belongs'
-#      EQUALITY caseIgnoreIA5Match
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
-
-##
-## user and group RID
-##
-#attributetype ( 1.3.6.1.4.1.7165.2.1.14 NAME 'rid'
-#      DESC 'NT rid'
-#      EQUALITY integerMatch
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-#attributetype ( 1.3.6.1.4.1.7165.2.1.15 NAME 'primaryGroupID'
-#      DESC 'NT Group RID'
-#      EQUALITY integerMatch
-#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-##
-## The smbPasswordEntry objectclass has been depreciated in favor of the
-## sambaAccount objectclass
-##
-#objectclass ( 1.3.6.1.4.1.7165.2.2.1 NAME 'smbPasswordEntry' SUP top AUXILIARY
-#        DESC 'Samba smbpasswd entry'
-#        MUST ( uid $ uidNumber )
-#        MAY  ( lmPassword $ ntPassword $ pwdLastSet $ acctFlags ))
-
-#objectclass ( 1.3.6.1.4.1.7165.2.2.2 NAME 'sambaAccount' SUP top STRUCTURAL
-#      DESC 'Samba Account'
-#      MUST ( uid $ rid )
-#      MAY  ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
-#               logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
-#               displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
-#               description $ userWorkstations $ primaryGroupID $ domain ))
-
-#objectclass ( 1.3.6.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY
-#      DESC 'Samba Auxiliary Account'
-#      MUST ( uid $ rid )
-#      MAY  ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
-#              logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
-#              displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
-#              description $ userWorkstations $ primaryGroupID $ domain ))
-
-########################################################################
-##                        END OF HISTORICAL                           ##
-########################################################################
-
-#######################################################################
-##                Attributes used by Samba 3.0 schema                ##
-#######################################################################
-
-##
-## Password hashes
-##
-attributetype ( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword'
-       DESC 'LanManager Password'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword'
-       DESC 'MD4 hash of the unicode password'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
-
-##
-## Account flags in string format ([UWDX     ])
-##
-attributetype ( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags'
-       DESC 'Account Flags'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE )
-
-##
-## Password timestamps & policies
-##
-attributetype ( 1.3.6.1.4.1.7165.2.1.27 NAME 'sambaPwdLastSet'
-       DESC 'Timestamp of the last password update'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.28 NAME 'sambaPwdCanChange'
-       DESC 'Timestamp of when the user is allowed to update the password'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.29 NAME 'sambaPwdMustChange'
-       DESC 'Timestamp of when the password will expire'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.30 NAME 'sambaLogonTime'
-       DESC 'Timestamp of last logon'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.31 NAME 'sambaLogoffTime'
-       DESC 'Timestamp of last logoff'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime'
-       DESC 'Timestamp of when the user will be logged off automatically'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.48 NAME 'sambaBadPasswordCount'
-       DESC 'Bad password attempt count'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.49 NAME 'sambaBadPasswordTime'
-       DESC 'Time of the last bad password attempt'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.55 NAME 'sambaLogonHours'
-       DESC 'Logon Hours'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{42} SINGLE-VALUE )
-
-##
-## string settings
-##
-attributetype ( 1.3.6.1.4.1.7165.2.1.33 NAME 'sambaHomeDrive'
-       DESC 'Driver letter of home directory mapping'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.34 NAME 'sambaLogonScript'
-       DESC 'Logon script path'
-       EQUALITY caseIgnoreMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.35 NAME 'sambaProfilePath'
-       DESC 'Roaming profile path'
-       EQUALITY caseIgnoreMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.36 NAME 'sambaUserWorkstations'
-       DESC 'List of user workstations the user is allowed to logon to'
-       EQUALITY caseIgnoreMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.37 NAME 'sambaHomePath'
-       DESC 'Home directory UNC path'
-       EQUALITY caseIgnoreMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName'
-       DESC 'Windows NT domain to which the user belongs'
-       EQUALITY caseIgnoreMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial'
-       DESC ''
-       EQUALITY caseExactMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.54 NAME 'sambaPasswordHistory'
-       DESC 'Concatenated MD4 hashes of the unicode passwords used on this account'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} )
-
-##
-## SID, of any type
-##
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.20 NAME 'sambaSID'
-       DESC 'Security ID'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
-
-
-##
-## Primary group SID, compatible with ntSid
-##
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.23 NAME 'sambaPrimaryGroupSID'
-       DESC 'Primary Group Security ID'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.51 NAME 'sambaSIDList'
-       DESC 'Security ID List'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} )
-
-##
-## group mapping attributes
-##
-attributetype ( 1.3.6.1.4.1.7165.2.1.19 NAME 'sambaGroupType'
-       DESC 'NT Group Type'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-##
-## Store info on the domain
-##
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.21 NAME 'sambaNextUserRid'
-       DESC 'Next NT rid to give our for users'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid'
-       DESC 'Next NT rid to give out for groups'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid'
-       DESC 'Next NT rid to give out for anything'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase'
-       DESC 'Base at which the samba RID generation algorithm should operate'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName'
-       DESC 'Share Name'
-       EQUALITY caseIgnoreMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName'
-       DESC 'Option Name'
-       EQUALITY caseIgnoreMatch
-       SUBSTR caseIgnoreSubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption'
-       DESC 'A boolean option'
-       EQUALITY booleanMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption'
-       DESC 'An integer option'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption'
-       DESC 'A string option'
-       EQUALITY caseExactIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption'
-       DESC 'A string list option'
-       EQUALITY caseIgnoreMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.50 NAME 'sambaPrivName' 
-       SUP name )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.52 NAME 'sambaPrivilegeList'
-       DESC 'Privileges List'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} )
-
-attributetype ( 1.3.6.1.4.1.7165.2.1.53 NAME 'sambaTrustFlags'
-       DESC 'Trust Password Flags'
-       EQUALITY caseIgnoreIA5Match
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-
-#######################################################################
-##              objectClasses used by Samba 3.0 schema               ##
-#######################################################################
-
-## The X.500 data model (and therefore LDAPv3) says that each entry can
-## only have one structural objectclass.  OpenLDAP 2.0 does not enforce
-## this currently but will in v2.1
-
-##
-## added new objectclass (and OID) for 3.0 to help us deal with backwards
-## compatibility with 2.2 installations (e.g. ldapsam_compat)  --jerry
-##
-objectclass ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY
-       DESC 'Samba 3.0 Auxilary SAM Account'
-       MUST ( uid $ sambaSID )
-       MAY  ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $
-              sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $
-              sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $
-               displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $
-              sambaProfilePath $ description $ sambaUserWorkstations $
-              sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $
-              sambaBadPasswordCount $ sambaBadPasswordTime $
-              sambaPasswordHistory $ sambaLogonHours))
-
-##
-## Group mapping info
-##
-objectclass ( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY
-       DESC 'Samba Group Mapping'
-       MUST ( gidNumber $ sambaSID $ sambaGroupType )
-       MAY  ( displayName $ description $ sambaSIDList ))
-
-##
-## Trust password for trust relationships (any kind)
-##
-objectclass ( 1.3.6.1.4.1.7165.2.2.14 NAME 'sambaTrustPassword' SUP top STRUCTURAL
-       DESC 'Samba Trust Password'
-       MUST ( sambaDomainName $ sambaNTPassword $ sambaTrustFlags )
-       MAY ( sambaSID $ sambaPwdLastSet ))
-
-##
-## Whole-of-domain info
-##
-objectclass ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL
-       DESC 'Samba Domain Information'
-       MUST ( sambaDomainName $ 
-              sambaSID ) 
-       MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $
-             sambaAlgorithmicRidBase ) )
-
-##
-## used for idmap_ldap module
-##
-objectclass ( 1.3.6.1.4.1.7165.2.2.7 NAME 'sambaUnixIdPool' SUP top AUXILIARY
-        DESC 'Pool for allocating UNIX uids/gids'
-        MUST ( uidNumber $ gidNumber ) )
-
-
-objectclass ( 1.3.6.1.4.1.7165.2.2.8 NAME 'sambaIdmapEntry' SUP top AUXILIARY
-        DESC 'Mapping from a SID to an ID'
-        MUST ( sambaSID )
-       MAY ( uidNumber $ gidNumber ) )
-
-objectclass ( 1.3.6.1.4.1.7165.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL
-       DESC 'Structural Class for a SID'
-       MUST ( sambaSID ) )
-
-objectclass ( 1.3.6.1.4.1.7165.1.2.2.10 NAME 'sambaConfig' SUP top AUXILIARY
-       DESC 'Samba Configuration Section'
-       MAY ( description ) )
-
-objectclass ( 1.3.6.1.4.1.7165.2.2.11 NAME 'sambaShare' SUP top STRUCTURAL
-       DESC 'Samba Share Section'
-       MUST ( sambaShareName )
-       MAY ( description ) )
-
-objectclass ( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURAL
-       DESC 'Samba Configuration Option'
-       MUST ( sambaOptionName )
-       MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ 
-             sambaStringListoption $ description ) )
-
-
-objectclass ( 1.3.6.1.4.1.7165.2.2.13 NAME 'sambaPrivilege' SUP top AUXILIARY
-       DESC 'Samba Privilege'
-       MUST ( sambaSID )
-       MAY ( sambaPrivilegeList ) )
-
diff --git a/contrib/openldap/slapd.conf b/contrib/openldap/slapd.conf
deleted file mode 100644 (file)
index ba0c986..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-# This is the main ldapd configuration file. See slapd.conf(5) for more
-# info on the configuration options.
-
-##
-## NOTE: This is an example. You should use the template shipped
-##       with your distribution and adapt it to your needs.
-##
-
-# Schema and objectClass definitions, depending on your
-# LDAP setup
-include                /etc/ldap/schema/core.schema
-include                /etc/ldap/schema/cosine.schema
-include        /etc/ldap/schema/inetorgperson.schema
-include        /etc/ldap/schema/openldap.schema
-include                /etc/ldap/schema/nis.schema
-include                /etc/ldap/schema/misc.schema
-include          /etc/ldap/schema/trust.schema
-#include       /etc/ldap/schema/krb5-kdc.schema
-
-# These should be present for GOsa. In case of samba3,
-# replace samba.schema and gosa.schema by samba3.schema
-# and gosa+samba3.schema. Don't include both and remember
-# to adjust the indexing and acl stuff below!
-include                /etc/ldap/schema/samba.schema
-include                /etc/ldap/schema/pureftpd.schema
-include                /etc/ldap/schema/gofon.schema
-include                /etc/ldap/schema/gosystem.schema
-include                /etc/ldap/schema/goto.schema
-include                /etc/ldap/schema/gosa+samba3.schema
-include                /etc/ldap/schema/gofax.schema
-include                /etc/ldap/schema/goserver.schema
-include                /etc/ldap/schema/goto-mime.schema
-
-# Schema check allows for forcing entries to
-# match schemas for their objectClasses's
-schemacheck            on
-
-# Security settings
-# Parameters: sasl, ssf, tls, transport, update_sasl, update_ssf,
-#             update_tls, update_transport
-#security              update_sasl=128,uptate_tls=128
-
-# Require settings
-# Paramters: none, authc, bind, LDAPv3, SASL (strong)
-#require                       authc, LDAPv3
-
-# Allow settings
-# Parameters: none, bind_v2, tls_2_anon, bind_anon_cred, bind_anon_dn,
-#             update_anon
-#allow                 bind_v2
-
-# Disallow settings
-# Parameters: bind_anon, bind_simple_unprotected, tls_2_anon,
-#             bind_simple, bind_krbv4, tls_authc
-
-# Password hash default value
-# Parameters: {SHA}, {SMD5}, {MD4}, {CRYPT}, {CLEARTEXT}
-password-hash          {CRYPT}
-
-# Search base
-defaultsearchbase      dc=gonicus,dc=de
-
-
-# Where clients are refered to if no
-# match is found locally
-#referral      ldap://some.other.ldap.server
-
-## TLS setup, needs certificates
-#TLSCipherSuite HIGH:MEDIUM:+SSLv2
-#TLSCertificateFile /etc/ssl/certs/slapd.pem
-#TLSCertificateKeyFile /etc/ssl/certs/slapd.pem
-
-## SASL setup
-#sasl-authz-policy
-#sasl-host     gosa.gonicus.local
-#sasl-realm    GONICUS.LOCAL
-#sasl-regexp   cn=(.*),ou=(.*) cn=$1,ou=$2,ou=People,dc=gonicus,dc=de
-#sasl-secprops noanonymous
-
-## Kerberos setup
-#srvtab                /etc/krb5.keytab.ldap
-
-# Where the pid file is put. The init.d script
-# will not stop the server if you change this.
-pidfile                /var/run/slapd.pid
-
-# List of arguments that were passed to the server
-argsfile       /var/run/slapd.args
-
-# Read slapd.conf(5) for possible values
-loglevel       1024
-
-# Where the dynamically loaded modules are stored
-modulepath      /usr/lib/ldap
-moduleload      back_hdb
-moduleload      back_monitor
-#moduleload      back_shell
-
-# Some tuning parameters
-#threads               64
-#concurrency           32
-#conn_max_pending      100
-#conn_max_pending_auth 250
-#reverse-lookup                off
-#sizelimit             1000
-#timelimit             30
-#idletimeout           30
-
-# Limits
-#limits        anonymous       size.soft=500 time.soft=5
-#limits user           size=none time.soft=30
-
-access to dn.base=""
-        by * read
-
-access to dn.subtree=cn=Monitor
-        by * read
-
-# Access to schema information
-#access to dn.subtree=""
-#        by * read
-
-# The userPassword/shadow Emtries by default can be
-# changed by the entry owning it if they are authenticated.
-# Others should not be able to see it, except the admin
-# entry below
-access to attrs=userPassword,sambaPwdLastSet,sambaPwdMustChange,sambaPwdCanChange,shadowMax,shadowExpire
-       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
-       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
-       by anonymous auth
-       by self write
-       by * none 
-
-# Deny access to imap/fax/kerberos admin passwords stored
-# in ldap tree
-access to attrs=goImapPassword
-       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
-       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
-       by * none 
-access to attrs=goKrbPassword
-       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
-       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
-       by * none 
-access to attrs=goFaxPassword
-       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
-       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
-       by * none 
-
-# Let servers write last user attribute
-access to attrs=gotoLastUser
-       by * write
-
-# Samba passwords by default can be changed
-# by the entry owning it if they are authenticated.
-# Others should not be able to see it, except the
-# admin entry below
-access to attrs=sambaLmPassword,sambaNtPassword
-       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
-       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
-       by anonymous auth
-       by self write
-       by * none 
-
-# Enable write create access for the terminal admin
-access to dn="ou=incoming,dc=gonicus,dc=de"
-       by dn="cn=terminal-admin,dc=gonicus,dc=de" write
-       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
-       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
-       by * none
-
-access to dn.sub="ou=incoming,dc=gonicus,dc=de"
-       by dn="cn=terminal-admin,dc=gonicus,dc=de" write
-       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
-       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
-       by * none
-
-# What trees should be readable, depends on your policy. Either
-# use this entry and specify what should be readable, or leave
-# the access to * => by * read below untouched
-#access to dn="ou=(people|groups)"
-#      by * read
-
-# The admin dn has full write access
-access to *
-       by dn="cn=ldapadmin,dc=gonicus,dc=de" =wrscx
-       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" =wrscx
-       by * read
-#      by peername="ip=127\.0\.0\.1" read
-#      by * none
-
-#######################################################################
-# database definitions
-#######################################################################
-
-# Monitor backend
-database       monitor
-
-# The backend type, ldbm, is the default standard
-database       hdb
-cachesize 5000
-mode             0600
-
-# The base of your directory
-suffix         "dc=gonicus,dc=de"
-checkpoint     512 720
-
-# Sample password is "tester", generate a new one using the mkpasswd
-# utility and put the string after {crypt}
-rootdn "cn=ldapadmin,dc=gonicus,dc=de"
-rootpw  {crypt}OuorOLd3VqvC2
-
-# Indexing
-index   default                                                sub
-index   uid,mail                                               eq
-index   gosaSnapshotDN                                         eq
-index   gosaSnapshotTimestamp                                  eq,sub
-index   gosaMailAlternateAddress,gosaMailForwardingAddress     eq
-index   cn,sn,givenName,ou                                     pres,eq,sub
-index   objectClass                                            pres,eq
-index   uidNumber,gidNumber,memberuid                          eq
-index   gosaSubtreeACL,gosaObject,gosaUser                     pres,eq
-
-# Indexing for Kolab
-#index alias                                                   eq,sub
-#index kolabDeleteFlag                                         eq
-#index kolabHomeServer                                         eq
-#index  member                                                 pres,eq
-
-# Indexing for Samba 3
-index   sambaSID                                               eq
-index   sambaPrimaryGroupSID                                   eq
-index   sambaDomainName                                        eq
-
-# Indexing for DHCP
-#index  dhcpHWAddress                                          eq
-#index  dhcpClassData                                          eq
-
-# Indexing for DNS
-#index  zoneName                                               eq
-#index  relativeDomainName                                     eq
-
-# Where the database file are physically stored
-directory      "/var/lib/ldap"
-
-# Log modifications and write entryUUID
-lastmod on
-
-
-# Example replication using admin account. This will require taking the
-# out put of this database using slapcat(8C), and then importing that into
-# the replica using slapadd(8C).
-
-# Replication setup
-#replogfile /var/log/ldap-replicalog
-#replica host=ldap-2.gonicus.local
-#      binddn="cn=replicator,dc=gonicus,dc=de" bindmethod=simple credentials=secret
-
-# Dummy database for config replication
-#database        shell
-#suffix          "dc=gonicus,dc=shell"
-#search          /etc/ldap/shell/process.pl
-#add            /etc/ldap/shell/process.pl
-
-# End of ldapd configuration file
-
diff --git a/contrib/openldap/trust.schema b/contrib/openldap/trust.schema
deleted file mode 100644 (file)
index 6b6fab0..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# this file goes into /etc/openldap/schema or into your schema directory for your LDAP v3 server
-# make sure you have it, otherwise, Directory administrator will complain when changing user accounts
-# unless you don't do schema checking
-
-attributetype ( 5.3.6.1.1.1.1.0 NAME 'trustModel'
-       DESC 'Access scheme'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-
-attributetype ( 5.3.6.1.1.1.1.1 NAME 'accessTo'
-       DESC 'Access to which servers user is allowed'
-       EQUALITY caseIgnoreIA5Match
-       SUBSTR caseIgnoreIA5SubstringsMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-
-objectclass ( 5.3.6.1.1.1.2.0 NAME 'trustAccount' SUP top AUXILIARY
-       DESC 'Sets trust accounts information'
-       MUST ( trustModel )
-       MAY ( accessTo ) )
-
diff --git a/contrib/opensides/README.OpenSides b/contrib/opensides/README.OpenSides
deleted file mode 100644 (file)
index cfd8453..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-goSamba.pl - This script will help you populate your ldap tree with
-            the correct attribute when using the smbldap-tools
-            from idealx.
-
-goNagios.pl - This script will help you to manage the authentification
-              users inside of the cgi.cfg, contacts.cfg, contactgroups.cfg
-slapd.conf - The slapd.conf confg for openldap 2.2
-
-nagios.README - how to make the nagios plugin work
-
-pptp.README - how to make the pptp connectivity extension work
-
-phpscheduleit.README - how to make the phpscheduleit extension work
-
-xls-export.README - how to make the xls export xork
-
-
-The php_writeexcel library is coming from
-
-http://www.bettina-attack.de/jonny/projects/php_writeexcel/
-
-Author : <jonny@1409.org>
-
-LICENSE : GNU LESSER GENERAL PUBLIC LICENSE
-
-Bug: 
-
-It doesn't work on php5 we are working on it.
-
-Benoit Mortier <benoit.mortier@opensides.be>
-Guillaume Delecourt <guillaume.delecourt@opensides.be>
-Vincent Seynhaeve <vincent.seynhaeve@opensides.be>
diff --git a/contrib/opensides/glpi.README b/contrib/opensides/glpi.README
deleted file mode 100644 (file)
index 52cfcf2..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-To use the glpi connectivity extension
-
-1) Add the glpi.schema to your schema directory
-
-2) Remove the comment in front of glpiAccount in gosa.conf
-
-<!--    <tab class="glpiAccount" /> -->
-
-Benoit Mortier
-OpenSides November 2005
-
-
-
diff --git a/contrib/opensides/goNagios.pl b/contrib/opensides/goNagios.pl
deleted file mode 100755 (executable)
index 754681d..0000000
+++ /dev/null
@@ -1,391 +0,0 @@
-#!/usr/bin/perl -w
-
-
-# Copyright (C) 2005 Guillaume Delecourt <guillaume.delecourt@opensides.be>
-# Copyright (C) 2005 Vincent Senave <vincent.senave@opensides.be>
-#
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-#
-
-use Net::LDAP;
-use Getopt::Std;
-use Net::LDAP::Schema;
-use Net::LDAP::LDIF;
-use Data::Dumper;
-use MIME::Lite;
-use Sys::Syslog;
-use Switch; 
-use strict;
-
-# Variables a config
-
-my $admindef="admin";
-
-my $cgi_file="cgi.cfg";
-my $contacts_file="contacts.cfg";
-my $contacts_groups_file="contactgroups.cfg";
-
-my $TS_FILE='/tmp/gosa_timestamp';
-my %Options;
-my $nb_user=0;
-my $nb_groupe=0;
-
-my ($i,$file,$ldap,@nagiosmail,
-       $line,$text,$mesg,$entry,$userlist1,$userlist2,$userlist3,$userlist4,
-       $userlist5,$userlist6,$userlist7,$msg,@groupname,@groupmembers,@contactlias,
-       @groupdescription,@servicenotificationoptions,@servicenotificationperiod,
-       @hostnotificationoptions,@hostnotificationperiod,$stdout,
-       $usercontact,$members,@contactname,@nagiosalias,$j,@entries
-);
-
-# Les parametres de connexion proviennent du fichier smbldap-bind.conf
-my $gosa_bind_conf="/etc/gosa_bind.conf";
-my $gosa_ldap_conf="/etc/gosaldap.conf";
-my %config_bind = &read_conf($gosa_bind_conf);
-my %config = &read_conf($gosa_ldap_conf);
-
-my $peopleou=$config{peopleou};
-my $groupeou=$config{groupeou};
-my $base=$config{base};
-my $scope=$config{scope};# par defaut
-my $server=$config{server};
-
-my $admin=$config_bind{masterDN};
-my $password=$config_bind{masterPw};
-
-
-       $stdout.="\n\nSearch new Nagios attribute in user list\n";
-       $stdout.="-"x55;$stdout.="\n";
-       #my $ts = getTS;
-
-#      $ldap = &anonBind;
-#      $mesg = $ldap->search(
-#      base => $LDAP_BASE,
-#      filter => "(&(modifyTimestamp>=$ts)(!(objectClass=gosaUserTemplate)))"
-#      );
-
-       # Put timestamp to file
-       #putTS;
-
-       # Work if changes is present
-       #if($mesg->count > 0)
-       #{
-       #$stdout.="Processing records modified after $ts\n\n";
-       $ldap = Net::LDAP->new($server);
-       $mesg = $ldap->bind($admin,password=>$password) or syslog('error',$mesg->err) && print $mesg->code && die $mesg->error;
-
-       
-
-       #Partie pour l'objectClass NAgios Contact
-       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosContact))", base=>$peopleou,scope=>$scope);
-       @entries = $mesg->entries;
-       $i=0;
-       foreach $entry (@entries) {
-       $stdout.="\nContact $i : \nName\t\t\t";$contactname[$i]=$entry->get_value('uid');$stdout.=$contactname[$i];
-       $stdout.="\n\n\tmail:\t\t\t\t";$nagiosmail[$i]=$entry->get_value('NagiosMail');$stdout.=$nagiosmail[$i];
-       $stdout.="\n\talias:\t\t\t\t";$nagiosalias[$i]=$entry->get_value('NagiosAlias');$stdout.=$nagiosalias[$i];
-       $stdout.="\n\tHostNotificationPeriod:\t\t";$hostnotificationperiod[$i]=$entry->get_value('HostNotificationPeriod');$stdout.=$hostnotificationperiod[$i];
-       $stdout.="\n\tServiceNotificationPeriod:\t";$servicenotificationperiod[$i]=$entry->get_value('ServiceNotificationPeriod');$stdout.=$servicenotificationperiod[$i];
-       $stdout.="\n\tHostNotificationOptions:\t";$hostnotificationoptions[$i]=$entry->get_value('HostNotificationOptions');$stdout.=$hostnotificationoptions[$i];
-       $stdout.="\n\tServiceNotificationOptions:\t";$servicenotificationoptions[$i]=$entry->get_value('ServiceNotificationOptions');$stdout.=$servicenotificationoptions[$i];
-       $stdout.="\n"." "x15;$stdout.="-"x20;$stdout.=" "x 15;                          
-       $usercontact.=$entry->get_value('uid')."  ,";
-       $i++;
-       }
-       $nb_user=$i;
-               
-               
-       #Partie pour l'objectClass NAgios Group
-       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosContactGroup))", base=>$groupeou,scope=>$scope);
-       @entries = $mesg->entries;
-       $i=0;
-       foreach $entry (@entries) {
-       $stdout.="\nGroupe $i : \nName\t\t";$groupname[$i]=$entry->get_value('cn');$stdout.=$groupname[$i];
-       $stdout.="\n\n\talias:\t\t";$groupdescription[$i]=$entry->get_value('description');$stdout.=$groupdescription[$i];
-       $stdout.="\n\tmembers:\t";
-       $j=0;
-       foreach $members($entry->get_value('memberUid'))
-       {
-       $stdout.=$members." ";
-       $groupmembers[$i][$j]=$members;
-       $j++;
-       }
-       $stdout.="\n"." "x15;$stdout.="-"x20;$stdout.=" "x 15;                  
-       $i++;
-       }
-       $nb_groupe=$i;
-
-               $userlist1.=$admindef;
-
-       #Partie pour l'objectClass NagiosAuth
-       $stdout.="\n\n\n\n\nAuthorization for the different Information in Nagios\n"."-" x 53;$stdout.="\n";
-       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedSystemInformation~=checked))", base=>$peopleou,scope=>$scope);
-       @entries = $mesg->entries;
-       $stdout.="\nSystem infos :\t\t";
-       foreach $entry (@entries) {
-       $stdout.= $entry->get_value('uid')."\t";
-       $userlist1.=$entry->get_value('uid')."  ,";
-       }
-       $userlist1.=$admindef;
-
-       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedConfigurationInformation~=checked))", base=>$peopleou,scope=>$scope);
-       @entries = $mesg->entries;
-       $stdout.="\nConfiguration infos :\t";
-       foreach $entry (@entries) {
-       $stdout.= $entry->get_value('uid')."\t";
-       $userlist2.=$entry->get_value('uid')." , ";
-       }
-       $userlist2.=$admindef;
-
-       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedSystemCommands~=checked))", base=>$peopleou,scope=>$scope);
-       @entries = $mesg->entries;
-       $stdout.="\nSystem commands : \t";
-       foreach $entry (@entries) {
-       $stdout.= $entry->get_value('uid')."\t";
-       $userlist3.=$entry->get_value('uid')." , ";
-       }
-       $userlist3.=$admindef;
-
-       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedAllServices~=checked))", base=>$peopleou,scope=>$scope);
-       @entries = $mesg->entries;
-       $stdout.="\nAll services :\t\t";
-       foreach $entry (@entries) {
-       $stdout.= $entry->get_value('uid')."\t";
-       $userlist4.=$entry->get_value('uid')." ,";
-       }
-       $userlist4.=$admindef;
-
-       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedAllHosts~=checked))", base=>$peopleou,scope=>$scope);
-       @entries = $mesg->entries;
-       $stdout.="\nAll hosts :\t\t";
-       foreach $entry (@entries) {
-       $stdout.= $entry->get_value('uid')."\t";
-       $userlist5.=$entry->get_value('uid').",";
-       }
-       $userlist5.=$admindef;
-
-
-       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedAllServiceCommands~=checked))", base=>$peopleou,scope=>$scope);
-       @entries = $mesg->entries;
-       $stdout.="\nAll services commands :\t";
-       foreach $entry (@entries) {
-       $stdout.= $entry->get_value('uid')."\t";
-       $userlist6.=$entry->get_value('uid').",";
-       }
-       $userlist6.=$admindef;
-
-       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedAllHostCommands~=checked))",base=>$peopleou,scope=>$scope);
-       @entries = $mesg->entries;
-       $stdout.="\nAll host commands :\t";
-       foreach $entry (@entries) {
-       $stdout.= $entry->get_value('uid')."\t";
-       $userlist7.=$entry->get_value('uid').",";
-       }
-       $userlist7.=$admindef;
-
-
-       &modiffile_cgi($cgi_file);
-       &modiffile_contact($contacts_file);
-       &modiffile_group($contacts_groups_file);
-       
-       $ldap->unbind;
-       $stdout.="\n";
-       switch($config{stdout})
-       {
-       case "mail"     {&mail()}
-       case "log"      {&writelog()}
-       case "normal"   {print $stdout}
-       }
-       exit(0);
-
-sub modiffile_contact()
-{
-       $file=$_[0];
-       my $text="";
-       open(FH,"$file") || die "Probleme d'ouverture du fichier $file";
-       $stdout.="\n\n"; $stdout.=" "x10;$stdout.="-"x25;$stdout.=" "x10;
-       $stdout.="\n\n$nb_user utilisateur(s) ajouté(s) dans le fichier $file\n";
-       for($i=0;$i<$nb_user;$i++)
-       {
-               $text.="\n\ndefine contact{\n";
-               $text.="\n\tcontact_name \t\t\t".$contactname[$i];
-               $text.="\n\talias \t\t\t\t".$nagiosalias[$i];
-               $text.="\n\thost_notification_period \t".$hostnotificationperiod[$i];
-               $text.="\n\thost_notification_options \t".$hostnotificationoptions[$i];
-               $text.="\n\tservice_notification_period \t".$servicenotificationperiod[$i];
-               $text.="\n\tservice_notification_options \t".$servicenotificationoptions[$i];
-               $text.="\n\temail \t\t\t\t".$nagiosmail[$i];
-               $text.="\n}\n\n";
-       }
-       close(FH);
-       open(FH,"> $file") || die "Probleme d'ouverture du fichier $file";
-       print  FH "$text";
-       close(FH);
-       
-}
-
-sub modiffile_group()
-{
-       $file=$_[0];
-       $text="";
-       $j=0;
-       $i=0;
-       open(FH,"$file") || die "Probleme d'ouverture du fichier $file";
-       $stdout.="\n\n"; $stdout.=" "x10;$stdout.="-"x25;$stdout.=" "x10;
-       $stdout.="\n\n$nb_groupe groupe(s) ajouté(s) dans le fichier $file\n";
-       for($i=0;$i<$nb_groupe;$i++)
-       {
-               $text.="\n\ndefine contact{\n";
-               $text.="\n\tcontactgroup_name \t".$groupname[$i];
-               $text.="\n\talias \t\t\t".$groupdescription[$i];
-               $text.="\n\tmembers \t\t";
-               while(defined($groupmembers[$i][$j]))
-               {
-                       $text.=$groupmembers[$i][$j]." ";
-                       $j++;
-               }
-               $text.="\n}\n\n";
-       }
-       
-       close(FH);
-       open(FH,"> $file") || die "Probleme d'ouverture du fichier $file";
-       print FH "$text";
-       close(FH);
-       
-}
-
-sub modiffile_cgi()
-{
-       $file=$_[0];
-       $text="";
-       open(FH,"$file") || die "Probleme d'ouverture du fichier $file";
-       while(<FH>)
-       {       
-               $line=$_;
-               #$stdout.="$line";
-               if($line =~ /^authorized_for_system_information=*/i){$text.="authorized_for_system_information=".$userlist1}
-               elsif($line =~ /^authorized_for_configuration_information=*/i){$text.="authorized_for_configuration_information=".$userlist2}
-               elsif($line =~ /^authorized_for_system_commands=*/i){$text.="authorized_for_system_commands=".$userlist3}
-               elsif($line =~ /^authorized_for_all_services=*/i){$text.="authorized_for_all_services=".$userlist4."\n"}
-               elsif($line =~ /^authorized_for_all_hosts=*/i){$text.="authorized_for_all_hosts=".$userlist5}
-               elsif($line =~ /^authorized_for_all_service_commands=*/i){$text.="authorized_for_all_host_commands=".$userlist6."\n"}
-               elsif($line =~ /^authorized_for_all_host_commands=*/i){$text.="authorized_for_all_service_commands=".$userlist7}
-               else {$text.=$line};
-       }
-       close(FH);
-       open(FH,"> $file") || die "Probleme d'ouverture du fichier $file";
-       print FH "$text";
-       close(FH);
-       
-}
-
-sub read_conf()
-{
-        my %conf;
-        open (CONFIGFILE, "$_[0]") || die "Unable to open $_[0] for reading !\n";
-        while (<CONFIGFILE>) {
-                chomp($_);
-                ## throw away comments
-                next if ( /^\s*#/ || /^\s*$/ || /^\s*\;/);
-                ## check for a param = value
-                my ($parameter,$value)=read_parameter($_);
-                $value = &subst_configvar($value,\%conf);
-                $conf{$parameter}=$value;
-          }
-        close (CONFIGFILE);
-        return(%conf);
-}
-
-
-
-
-sub read_parameter
-{
-        my $line=shift;
-        ## check for a param = value
-        if ($_=~/=/) {
-          my ($param,$val);
-          if ($_=~/"/) {
-                #my ($param,$val) = ($_=~/(.*)\s*=\s*"(.*)"/);
-                ($param,$val) = /\s*(.*?)\s*=\s*"(.*)"/;
-          } elsif ($_=~/'/) {
-                ($param,$val) = /\s*(.*?)\s*=\s*'(.*)'/;
-          } else {
-                ($param,$val) = /\s*(.*?)\s*=\s*(.*)/;
-          }
-          return ($param,$val);
-        }
-}
-
-sub subst_configvar
-{
-        my $value = shift;
-        my $vars = shift;
-
-        $value =~ s/\$\{([^}]+)\}/$vars->{$1} ? $vars->{$1} : $1/eg;
-        return $value;
-}
-
-sub mail
-{
-
-if($config{email}eq ""){$config{email}="root"}
-
-$msg = MIME::Lite->new(
-             From     => 'monperl@opensides.be',
-             To       => $config{email},
-             Subject  => "Plugin Nagios Gosa",
-             Data     => $stdout
-             );
-
-
-$msg->send;
-}
-
-sub writelog
-{
-       open(F, "> $config{logfile}");
-       print F $stdout;
-       close(F);
-}
-
-# Read timestamp
-sub getTS
-{
-       open(F, "< $TS_FILE");
-       my $ts = <F>;
-       chop $ts;
-       $ts ||= "19700101000000Z";
-       return $ts;
-}
-
-# save timestamp
-sub putTS
-{
-       my $ts = `date -u '+%Y%m%d%H%M%SZ'`;
-       open(F, "> $TS_FILE");
-       $stdout.= F $ts;
-}
-
-#connexion anonyme
-sub anonBind
-{
-       my $ldap = Net::LDAP->new( $server);
-       my $mesg = $ldap->bind();
-       $mesg->code && die $mesg->error;
-       return $ldap;
-}
diff --git a/contrib/opensides/goSamba.pl b/contrib/opensides/goSamba.pl
deleted file mode 100755 (executable)
index ef7b210..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-#!/usr/bin/perl
-
-
-# Copyright (C) 2005 Guillaume Delecourt <guillaume.delecourt@opensides.be>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-#
-
-use Net::LDAP;
-use Getopt::Std;
-use Net::LDAP::Schema;
-use Net::LDAP::LDIF;
-
-# Variables a config
-$admin="cn=ldapadmin,dc=example,dc=be";
-$password="";
-$peopleou="ou=People,dc=example,dc=be";
-$base="dc=example,dc=be";
-$scope="one"; # par defaut
-$dump_file="myldaptree.ldif";
-$server="localhost";
-
-
-my %Options;
-
-my $ok = getopts('?', \%Options);
-
-#Verifying if help is needed
-if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
-       &help();
-}
-
-print "We backup the whole tree before every operation\n";
-&dump();
-
-$comm=$ARGV[0];
-
-if($comm eq "del" && @ARGV >1 )
-{      
-       print "You asked to delete attribute : ";
-       $i=1;
-       while($ARGV[$i] ne "")
-       {       
-                       print $ARGV[$i]." ";
-                       $i++;
-       }
-       print "\n";
-       $ldap = Net::LDAP->new($server);
-       $ldap->bind($admin,password=>$password);
-
-
-       print "ldap connection" .$ldap;
-
-       $mesg = $ldap->search(filter=>"(objectClass=*)",base=>$peopleou,scope=>$scope);
-       @entries = $mesg->entries;
-
-       foreach $entry (@entries) {
-               $i=1;
-               print $entry->dn()."\n";
-               while($ARGV[$i] ne "")
-               {       
-                       if($ARGV[$i] eq "obj"){$obj=1;$i++;next}
-                       if($obj==1)
-                       {
-                               $mesg = $ldap->modify($entry->dn(), delete => {"ObjectClass"=>"$ARGV[$i]"});
-                               print "\t objectClass: ".$ARGV[$i];
-                       }
-                       else
-                       {
-                               $mesg = $ldap->modify($entry->dn(), delete => [$ARGV[$i]]);
-                               print "\t attribut: ".$ARGV[$i];
-                       }
-                       $obj=0;
-                       $i++;
-               }
-               
-               print "\n";
-       }
-       $ldap->unbind;
-       exit(0);
-}
-elsif($comm eq "gosa" && @ARGV ==1)
-{
-       print "Add GOsa attribute for the following users\n";
-       print "---------------------------------------------\n";
-       $ldap = Net::LDAP->new($server);
-       $ldap->bind($admin,password=>$password);
-       $mesg = $ldap->search(filter=>"&(!(objectClass~=gosaAccount))", base=>$peopleou,scope=>$scope);
-       @entries = $mesg->entries;
-
-       foreach $entry (@entries) {
-               $mesg = $ldap->modify($entry->dn(), add => { "ObjectClass" => "gosaAccount"});
-               $mesg = $ldap->modify($entry->dn(), add => { "ObjectClass" => "organizationalPerson"});
-               $mesg = $ldap->modify($entry->dn(), add => { "ObjectClass" => "Person"});
-               print $entry->dn();
-               print "\n";
-       }
-       $ldap->unbind;
-       exit(0);
-}
-elsif($comm eq "modif" && @ARGV >1)
-{
-       print "Modifications asked\n";
-       print "------------------------\n";
-       $ldap = Net::LDAP->new($server);
-       $ldap->bind($admin,password=>$password);
-
-       $mesg = $ldap->search(filter=>"(objectClass=*)",base=>$peopleou,scope=>$scope);
-       @entries = $mesg->entries;
-       foreach $entry (@entries) {
-       $mesg = $ldap->modify($entry->dn(), replace => { "$ARGV[1]" => "$ARGV[2]" } );
-       print $entry->dn()."\n\tattribut $ARGV[1] modifié avec la valeur $ARGV[2]\n";
-       }
-       $ldap->unbind;
-       exit(0);
-}
-elsif($comm eq "dump" && @ARGV ==1)
-{
-       &dump();
-}
-else
-{
-       &help();
-}
-
-sub help()
-{
-    print_banner;
-    print "Usage: $0 [-?] command\n";
-    print "\t-?        show this help message\n";
-    print "\tgosa -> add GOsa attributes for the whole the people branch !\n";
-    print "\tdel attribut  -> Remove an attribute for the whole people branch !\n";
-    print "\tmodif <attribute> <attribute value> -> to modify the attribute\n";
-    print "\tdump to dump the whole ldap tree\n";
-    exit (1);
-}
-
-sub dump()
-{
-    $ldap = Net::LDAP->new($server) or die "$@";
-    $ldap->bind($admin,password=>$password);
-    my $ldif = Net::LDAP::LDIF->new($dump_file,'w') ;
-    $mesg = $ldap->search ( 
-                               base   => "$base",
-                               filter => "(objectclass=*)"
-                       );
-    $ldif->write_entry($mesg->entries) ;
-    $ldap->unbind;
-}
diff --git a/contrib/opensides/nagios.README b/contrib/opensides/nagios.README
deleted file mode 100644 (file)
index 5878e40..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-To use the nagios plugin
-
-1) Add the nagios schema to your schema directory
-
-2) Remove the comment in front of nagiosAccount in gosa.conf
-
-<!--                     <plugin acl="default" class="nagiosAccount" icon="monitoring.png"
-                                path="plugins/personal/nagios" /> -->
-
-
-<!--    <nagios>
-                <tab class="nagiosAccount" />
-        </nagios> -->
-
-Benoit Mortier
-Guillaume Delecourt
-OpenSides October-November 2005
-
-
-
diff --git a/contrib/opensides/phpscheduleit.README b/contrib/opensides/phpscheduleit.README
deleted file mode 100644 (file)
index 4b634c8..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-To use the phpscheduleit connectivity extension
-
-1) Add the schema phpscheduleit.schema in your schema directory
-
-2) Remove the comment in front of phpscheduleitAccount in gosa.conf
-
-<!--    <tab class="pptpAccount" /> -->
-
-Guillaume Delecourt
-OpenSides November 2005
diff --git a/contrib/opensides/pptp.README b/contrib/opensides/pptp.README
deleted file mode 100644 (file)
index 556e274..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-To use the pptp connectivity extension
-
-1) Add the pptp.schema to your schema directory
-
-2) Remove the comment in front of pptpAccount in gosa.conf
-
-<!--    <tab class="pptpAccount" /> -->
-
-Guillaume Delecourt
-OpenSides November 2005
-
-
-
diff --git a/contrib/opensides/xls-export.README b/contrib/opensides/xls-export.README
deleted file mode 100644 (file)
index e9b0606..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-To use the xls export ldapamanager addon uncomment the following line in your gosa.conf :
-
-<!--            <tab class="xlsexport" name="Excel Export" />   -->
-
-Guillaume Delecourt
-Vincent Seynhaeve
-OpenSides October 2005
diff --git a/contrib/openxchange/README.openxchange b/contrib/openxchange/README.openxchange
deleted file mode 100644 (file)
index 52effd8..0000000
+++ /dev/null
@@ -1,437 +0,0 @@
-### Small tutorial for use GOsa with open-xchange ###
-
-Once installed open-xchange (http://www.open-xchange.org) and php4-pgsql 
-module we must do some changes to get open-xchange running with GOsa.
-
-- php.ini must have extension=pg_sql.so
-
-- The webserver must have access to the Postgresql server.
-
-- In the connectivity section of gosa.conf must have something like this:
-                <tab class="oxchangeAccount"
-                        pghost="server"
-                        pguser="openexchange"
-                        pgpasswd="test"
-                        pgdbname="openexchange"
-               />
-
-
-
-We suppose that openxchage is installed in /usr/local/openxchange, 
-and the base for GOsa ldap tree is dc=example,dc=org
-
-
-- Make changes to admintools.conf (/usr/local/openxchange/etc/admintools.conf):
-
-OXBASE="dc=example,dc=org"
-OX_LEAF="$OXBASE"
-# Where are the OX Users
-USER_BASEDN="ou=people,$OX_LEAF"
-# Where are the OX Groups
-GROUP_BASEDN="ou=groups,$OX_LEAF"
-# Where are the OX Resources
-RESOURCES_BASEDN="ou=Resources,ou=ResourceObjects,ou=OxObjects,$OX_LEAF"
-# Where are the OX Resource Groups
-RESOURCE_GROUPS_BASEDN="ou=ResourceGroups,ou=ResourceObjects,ou=OxObjects,$OX_LEAF"
-# Where is the Global Adressbook
-GLOBAL_ADDRESSBOOKDN="o=AddressBook,ou=OxObjects,$OX_LEAF"
-# where are the adressbook admins
-GLOBAL_ADDRESSBOOK_ADMINSDN="cn=AddressAdmins,ou=OxObjects,$GLOBAL_ADDRESSBOOKDN"
-
-- Make changes in login.pm (usually in /usr/lib/cgi-bin/login.pm):
-my $ldap_userBase = 'ou=Users,ou=OxObjects,';
-to
-my $ldap_userBase = 'ou=people,';
-
-- Put the Base in ldap.conf (/usr/local/openxchange/etc/groupware/ldap.conf)
-BASE    dc=example,dc=org
-
-- If you are using as GOsa dnmode "uid", You must change in ldap.properties 
-(/usr/local/openxchange/etc/groupware/ldap.properties):
-
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeuserCountryName=userCountry
- to
-com.openexchange.groupware.ldap.OXUserObjectAttributeuserCountryName=st
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeimapServerName=imapServer
- to
-com.openexchange.groupware.ldap.OXUserObjectAttributeimapServerName=gosaMailServer
-
-com.openexchange.groupware.ldap.OXUserObjectAttributesmtpServerName=smtpServer
- to 
-com.openexchange.groupware.ldap.OXUserObjectAttributesmtpServerName=gosaMailServer
-
-com.openexchange.groupware.ldap.userBaseDN=ou\u003DUsers,ou\u003DOxObjects
-to
-com.openexchange.groupware.ldap.userBaseDN=ou\u003Dpeople
-
-
-
-- If you are using as GOsa dnmode "cn", the ldap.properties  
-(/usr/local/openxchange/etc/groupware/ldap.properties) 
-configuration of open-xchange must be like this:
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributebusinessCategoryName=businessCategory
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributecnName=cn
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeCountryName=c
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributedescriptionName=description
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributedisplayNameName=displayName
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributeemployeeNumberName=employeeNumber
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributeemployeeTypeName=employeeType
-
-com.openexchange.groupware.ldap.OXUserObjectAttributecoName=co
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributehomePhoneName=homePhone
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributehomePostalAddressName=homePostalAddress
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeInfoName=info
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributeinitialsName=initials
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributeinternationaliSDNNumberName=internationaliSDNNumber
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeIPPhoneName=IPPhone
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeotherfacsimiletelephonenumberName=otherfacsimiletelephonenumber
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributeroomNumberName=roomNumber
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributetelexNumberName=telexNumber
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributeuidName=uid
-
-com.openexchange.groupware.ldap.inetOrgPersonClassName=inetOrgPerson
-
-com.openexchange.groupware.ldap.OXUserObjectAttributebirthDayName=birthDay
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeDistributionListName=OXUserDistributionList
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeAnniversaryName=OXUserAnniversary
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeBranchesName=OXUserBranches
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeCategoriesName=OXUserCategories
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeChildrenName=OXUserChildren
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeCityName=OXUserCity
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeCommentName=OXUserComment
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeComRegName=OXUserComReg
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeEmail2Name=OXUserEmail2
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeEmail3Name=OXUserEmail3
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeInstantMessenger2Name=OXUserInstantMessenger2
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeInstantMessengerName=OXUserInstantMessenger
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeMaritalStatusName=OXUserMaritalStatus
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeNickNameName=OXUserNickName
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeOtherCityName=OXUserOtherCity
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeOtherCountryName=OXUserOtherCountry
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeOtherPostalCodeName=OXUserOtherPostalCode
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeOtherStateName=OXUserOtherState
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeOtherStreetName=OXUserOtherStreet
-
-com.openexchange.groupware.ldap.OXUserObjectAttributePositionName=OXUserPosition
-
-com.openexchange.groupware.ldap.OXUserObjectAttributePostalCodeName=OXUserPostalCode
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeProfessionName=OXUserProfession
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeSalesVolumeName=OXUserSalesVolume
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeSpouseNameName=OXUserSpouseName
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeStateName=OXUserState
-
-com.openexchange.groupware.ldap.OXUserObjectAttributesuffixName=OXUserSuffix
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeTaxIDName=OXUserTaxID
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeTeleAssistantName=OXUserTeleAssistant
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeTeleBusiness2Name=OXUserTeleBusiness2
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeTeleCallbackName=OXUserTeleCallback
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeTeleCarName=OXUserTeleCar
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeTeleCompanyName=OXUserTeleCompany
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeTeleFax2Name=OXUserTeleFax2
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeTeleHome2Name=OXUserTeleHome2
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeTeleMobile2Name=OXUserTeleMobile2
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeTeleOtherName=OXUserTeleOther
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeTelePrimaryName=OXUserTelePrimary
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeTeleRadioName=OXUserTeleRadio
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeTeleTTYName=OXUserTeleTTY
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeurlName=url
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef01Name=OXUserUserUndef01
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef02Name=OXUserUserUndef02
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef03Name=OXUserUserUndef03
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef04Name=OXUserUserUndef04
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef05Name=OXUserUserUndef05
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef06Name=OXUserUserUndef06
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef07Name=OXUserUserUndef07
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef08Name=OXUserUserUndef08
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef09Name=OXUserUserUndef09
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef10Name=OXUserUserUndef10
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef11Name=OXUserUserUndef11
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef12Name=OXUserUserUndef12
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef13Name=OXUserUserUndef13
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef14Name=OXUserUserUndef14
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef15Name=OXUserUserUndef15
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef16Name=OXUserUserUndef16
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef17Name=OXUserUserUndef17
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef18Name=OXUserUserUndef18
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef19Name=OXUserUserUndef19
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef20Name=OXUserUserUndef20
-
-com.openexchange.groupware.ldap.OXUserObjectClassName=OXUserObject
-
-com.openexchange.groupware.ldap.AllContactUIDSearch=(&(objectClass\u003DinetOrgPerson)(objectClass\u003DOXUserObject))
-
-!com.openexchange.groupware.ldap.AllContactUIDSearchScope=1
-
-com.openexchange.groupware.ldap.credentialsBaseDN=[credentialsBaseDN]
-
-com.openexchange.groupware.ldap.credentialsDN=cn\u003D[uid],[userBaseDN],[credentialsBaseDN]
-
-com.openexchange.groupware.ldap.groupOfNamesAttributememberName=member
-
-com.openexchange.groupware.ldap.AddressAdminsDN=cn\u003DAddressAdmins,[globalAddressBookBaseDN]
-
-com.openexchange.groupware.ldap.globalAddressBookBaseDN=o\u003DAddressBook
-
-com.openexchange.groupware.ldap.GlobalAddressBookEntryDN=cn\u003D[contactid],[globalAddressBookBaseDN]
-
-com.openexchange.groupware.ldap.InternalUsersForeSureNameUIDPatternSearchFilter=(&(objectClass\u003DinetOrgPerson)(objectClass\u003DOXUserObject)(|(sn\u003D[pattern])(givenname\u003D[pattern])(cn\u003D[pattern]))(mailEnabled\u003Dok))
-
-com.openexchange.groupware.ldap.InternalUsersStartingLetterSearchFilter=(&(objectClass\u003DinetOrgPerson)(objectClass\u003DOXUserObject)(sn\u003D[letter]*)(mailEnabled\u003Dok))
-
-com.openexchange.groupware.ldap.UserAddressBookEntryDN=cn\u003D[contactid],[UserAddressBookDN]
-
-com.openexchange.groupware.ldap.localDomainsBaseDN=ou\u003DDNSObjects,ou\u003DAdminObjects
-
-com.openexchange.groupware.ldap.OXVDomainAttributedomainNameName=domainName
-
-com.openexchange.groupware.ldap.LocalDomainsSearchFilter=(&(objectClass\u003DOXVDomainObject)(MTALocaldomain\u003Dtrue))
-
-com.openexchange.groupware.ldap.OXIMAPFolderAttributefnName=fn
-
-com.openexchange.groupware.ldap.sharedFolderBaseDN=ou\u003DSharedFolder
-
-com.openexchange.groupware.ldap.SharedFolderSearchFilter=(&(objectclass\u003DOXIMAPFolderObject)(mailenabled\u003Dok))
-
-!com.openexchange.groupware.ldap.sharedFolderSearchScope=1
-
-com.openexchange.groupware.ldap.OXResourceGroupAttributeresourceGroupAvailableName=resourceGroupAvailable
-
-com.openexchange.groupware.ldap.OXResourceGroupAttributeresourceGroupMemberName=resourceGroupMember
-
-com.openexchange.groupware.ldap.OXResourceGroupAttributeresourceGroupNameName=resourceGroupName
-
-com.openexchange.groupware.ldap.ResourceGroupDN=resourceGroupName\u003D[group],[resourceGroupBaseDN]
-
-com.openexchange.groupware.ldap.ResourceGroupPatternSearchFilter=(&(objectclass\u003DOXResourceGroupObject)(resourceGroupName\u003D[pattern]))
-
-com.openexchange.groupware.ldap.ResourceGroupSearchFilter=(objectclass\u003DOXResourceGroupObject)
-
-!com.openexchange.groupware.ldap.ResourceGroupSearchScope=1
-
-com.openexchange.groupware.ldap.OXResourceAttributeresourceNameName=resourceName
-
-#Where are the resources?
-com.openexchange.groupware.ldap.resourceBaseDN=ou\u003DResources,ou\u003DResourceObjects
-
-com.openexchange.groupware.ldap.ResourceDN=resourceName\u003D[resource],[resourceBaseDN]
-
-#Where are the resource groups?
-com.openexchange.groupware.ldap.resourceGroupBaseDN=ou\u003DResourceGroups,ou\u003DResourceObjects
-
-#Searches resources with the a pattern.
-com.openexchange.groupware.ldap.ResourcePatternSearchFilter=(&(objectclass\u003DOXResourceObject)(resourceName\u003D[pattern]))
-
-!com.openexchange.groupware.ldap.ResourceSearchScope=1
-
-com.openexchange.groupware.ldap.DNForDefaultMail=cn\u003Dmailadmin,[userBaseDN]
-
-com.openexchange.groupware.ldap.Factory.AuthenticationSupport=com.openexchange.groupware.ldap.DefaultAuthenticationSupport
-
-com.openexchange.groupware.ldap.Factory.ContactSupport=com.openexchange.groupware.ldap.DefaultContactSupport
-
-com.openexchange.groupware.ldap.Factory.MailSupport=com.openexchange.groupware.ldap.DefaultMailSupport
-
-com.openexchange.groupware.ldap.Factory.ResourcesHandle=com.openexchange.groupware.ldap.DefaultResourcesHandle
-
-#Class, that implementes UserGroupHandle, ResourcesHandle
-com.openexchange.groupware.ldap.Factory.UserGroupHandle=com.openexchange.groupware.ldap.DefaultUserGroupHandle
-
-#Where to search for groups?
-com.openexchange.groupware.ldap.groupBaseDN=ou\u003DGroups
-
-#Complete dn of a group.
-com.openexchange.groupware.ldap.GroupDN=cn\u003D[gid],[groupBaseDN]
-
-com.openexchange.groupware.ldap.GroupSearchFilter=(objectclass\u003DposixGroup)
-
-#Searches all groups for the user
-com.openexchange.groupware.ldap.GroupsForUserSearchFilter=(&(objectclass\u003DposixGroup)(memberUid\u003D[uid]))
-
-com.openexchange.groupware.ldap.GroupsPatternSearchFilter=(&(objectclass\u003DposixGroup)(cn\u003D[pattern]))
-
-!com.openexchange.groupware.ldap.GroupSearchScope=1
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributefacsimileName=facsimileTelephoneNumber
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributegivenNameName=givenName
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributelabeledURIName=labeledURI
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributelName=l
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributemailName=mail
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributemobileName=mobile
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributeoName=o
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributeouName=ou
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributepagerName=pager
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributepostalCodeName=postalCode
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributepreferredLanguageName=preferredLanguage
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributesnName=sn
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributestName=st
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributestreetName=street
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributetelephoneNumberName=telephoneNumber
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributetitleName=title
-
-com.openexchange.groupware.ldap.OXUserObjectAttributealiasName=alias
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeappointmentDaysName=OXAppointmentDays
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeimapServerName=gosaMailServer
-
-com.openexchange.groupware.ldap.OXUserObjectAttributemailDomainName=mailDomain
-
-com.openexchange.groupware.ldap.OXUserObjectAttributesmtpServerName=gosaMailServer
-
-com.openexchange.groupware.ldap.OXUserObjectAttributetaskDaysName=OXTaskDays
-
-com.openexchange.groupware.ldap.OXUserObjectAttributetimeZoneName=OXTimeZone
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeuserCountryName=st
-
-com.openexchange.groupware.ldap.OXUserObjectAttributevaddressName=vaddress
-
-com.openexchange.groupware.ldap.posixAccountAttributecnName=cn
-
-com.openexchange.groupware.ldap.posixAccountAttributeuidName=uid
-
-com.openexchange.groupware.ldap.posixGroupAttributecnName=cn
-
-com.openexchange.groupware.ldap.posixGroupAttributememberUidName=memberUid
-
-com.openexchange.groupware.ldap.UserAddressBookDN=ou\u003Daddr,cn\u003D[uid],[userBaseDN]
-
-com.openexchange.groupware.ldap.UserAttributeOpenLDAPaciName=OpenLDAPaci
-
-com.openexchange.groupware.ldap.userBaseDN=ou\u003Dpeople
-
-#DN to the user object
-com.openexchange.groupware.ldap.UserDN=cn\u003D[uid],[userBaseDN]
-
-com.openexchange.groupware.ldap.UsersCNPatternSearchFilter=(&(objectclass\u003DposixAccount)(objectClass\u003DinetOrgPerson)(|(cn\u003D[pattern])(givenName\u003D[pattern])(cn\u003D[pattern])))
-
-com.openexchange.groupware.ldap.UserSearchFilter=(&(cn\u003D[uid])(objectClass\u003DOXUserObject))
-
-!com.openexchange.groupware.ldap.UserSearchScope=1
-
-com.openexchange.groupware.ldap.UsersForeSureNamePatternSearchFilter=(&(objectclass\u003DposixAccount)(|(givenName\u003D[pattern])(sn\u003D[pattern])))
-
-com.openexchange.groupware.ldap.UsersForeSureNameUIDPatternSearchFilter=(&(objectclass\u003DposixAccount)(objectClass\u003DinetOrgPerson)(|(givenName\u003D[pattern])(sn\u003D[pattern])(cn\u003D[pattern])))
-
-com.openexchange.groupware.ldap.UsersPatternSearchFilter=(&(objectclass\u003DposixAccount)(cn\u003D[pattern]))
-
-#Define the objectClasses an user object should belong to if you are performing pattern searches.
-com.openexchange.groupware.ldap.UsersPatternSearchObjectClasses=posixAccount,inetOrgPerson,OXUserObject
-
-com.openexchange.groupware.ldap.GlobalAddressBookSearchScope=1
-
-com.openexchange.groupware.ldap.inetOrgPersonAttributejpegPhotoName=jpegPhoto
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeDayViewEndTimeName=OXDayViewEndTime
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeDayViewStartTimeName=OXDayViewStartTime
-
-com.openexchange.groupware.ldap.OXUserObjectAttributeDayViewIntervalName=OXDayViewInterval
-
-!com.openexchange.groupware.ldap.LocalDomainsSearchScope=1
-
-
-
-
-
-
-This configuration is based in documentation gets from 
-http://www.open-xchange.org/oxwiki/
-
-TODO:
-- more testing
-- check cn configuration
-- check addressbook
-- subtree support
-
diff --git a/contrib/patches/imap-2001a-quota.patch b/contrib/patches/imap-2001a-quota.patch
deleted file mode 100644 (file)
index 304488d..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-diff -Naur imap-2001a/src/c-client/imap4r1.c imap-2001a.patched/src/c-client/imap4r1.c
---- imap-2001a/src/c-client/imap4r1.c  Wed Nov 14 23:50:55 2001
-+++ imap-2001a.patched/src/c-client/imap4r1.c  Wed May 21 09:54:35 2003
-@@ -2358,10 +2358,12 @@
-       do {                    /* for each list item */
-       *s++ = c;               /* write prefix character */
-       if (list) {             /* sigh, QUOTA has bizarre syntax! */
--        for (t = (char *) list->text.data; *t; *s++ = *t++);
--        sprintf (s," %lu",list->text.size);
--        s += strlen (s);
--        c = ' ';              /* prefix character for subsequent strings */
-+        if (list->text.size != 0){
-+          for (t = (char *) list->text.data; *t; *s++ = *t++);
-+          sprintf (s," %lu",list->text.size);
-+          s += strlen (s);
-+          c = ' ';            /* prefix character for subsequent strings */
-+        }
-       }
-       }
-       while (list = list->next);
diff --git a/contrib/patches/php4-imap-getacl.patch b/contrib/patches/php4-imap-getacl.patch
deleted file mode 100644 (file)
index ae3a235..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
---- php-imap-4.3.9/php_imap.c.fix      2004-08-06 15:04:17 +0400
-+++ php-imap-4.3.9/php_imap.c  2004-08-06 15:11:43 +0400
-@@ -138,6 +138,7 @@ function_entry imap_functions[] = {
-       PHP_FE(imap_get_quotaroot,                                              NULL)
-       PHP_FE(imap_set_quota,                                                  NULL)
-       PHP_FE(imap_setacl,                                                             NULL)
-+        PHP_FE(imap_getacl,                                                             NULL)
- #endif
-       PHP_FE(imap_mail,                                                               NULL)
-@@ -377,6 +378,22 @@ void mail_getquota(MAILSTREAM *stream, c
- /* }}} */
- #endif
-+/* {{{ mail_getquota 
-+ *
-+ * Mail GET_ACL callback
-+ * Called via the mail_parameter function in c-client:src/c-client/mail.c
-+ */
-+void mail_getacl(MAILSTREAM *stream, char *mailbox, ACLLIST *alist)
-+{
-+      TSRMLS_FETCH();
-+
-+      /* walk through the ACLLIST */
-+      for (; alist; alist = alist->next)
-+      {
-+              add_assoc_stringl(IMAPG(imap_acl_list), alist->identifier, alist->rights, strlen(alist->rights), 1);
-+      }
-+}
-+/* }}} */
- /* {{{ php_imap_init_globals
-  */
-@@ -402,6 +419,7 @@ static void php_imap_init_globals(zend_i
-       imap_globals->folderlist_style = FLIST_ARRAY;
- #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001)
-       imap_globals->quota_return = NULL;
-+        imap_globals->imap_acl_list = NIL;
- #endif
- }
- /* }}} */
-@@ -985,6 +1003,37 @@ PHP_FUNCTION(imap_setacl)
- }
- /* }}} */
-+/* {{{ proto array imap_get_quota(int stream_id, string mailbox)
-+      Gets the ACL for a given mailbox */
-+PHP_FUNCTION(imap_getacl)
-+{
-+      zval **streamind, **mailbox;
-+      pils *imap_le_struct;
-+
-+      if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &streamind, &mailbox) == FAILURE) {
-+              ZEND_WRONG_PARAM_COUNT();
-+      }
-+
-+      ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
-+
-+      convert_to_string_ex(mailbox);
-+
-+    /* initializing the special array for the return values */
-+    array_init(return_value);
-+
-+    IMAPG(imap_acl_list) = return_value;
-+
-+      /* set the callback for the GET_ACL function */
-+      mail_parameters(NIL, SET_ACL, (void *) mail_getacl);
-+      if(!imap_getacl(imap_le_struct->imap_stream, Z_STRVAL_PP(mailbox))) {
-+              php_error(E_WARNING, "c-client imap_getacl failed");
-+              RETURN_FALSE;
-+      }
-+
-+    IMAPG(imap_acl_list) = NIL;
-+}
-+/* }}} */
-+
- #endif /* HAVE_IMAP2000 || HAVE_IMAP2001 */
---- php-imap-4.3.9/php_imap.h.fix      2004-08-06 15:09:33 +0400
-+++ php-imap-4.3.9/php_imap.h  2004-08-06 15:10:42 +0400
-@@ -172,6 +172,7 @@ PHP_FUNCTION(imap_get_quota);
- PHP_FUNCTION(imap_get_quotaroot);
- PHP_FUNCTION(imap_set_quota);
- PHP_FUNCTION(imap_setacl);
-+PHP_FUNCTION(imap_getacl);
- #endif
-@@ -202,6 +203,7 @@ ZEND_BEGIN_MODULE_GLOBALS(imap)
-       unsigned long status_uidvalidity;
- #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001)
-       zval **quota_return;
-+        pval *imap_acl_list;
- #endif
- ZEND_END_MODULE_GLOBALS(imap)
diff --git a/contrib/resolutions b/contrib/resolutions
deleted file mode 100755 (executable)
index 9233805..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-480x320
-640x480
-1024x768
-1280x1024
diff --git a/contrib/scripts/README b/contrib/scripts/README
deleted file mode 100644 (file)
index 023f428..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-goQuota.pl - run this script via cron (each 5-10 min for examle). It makes
-             cache file (quota.db) with traffic usage and user info from LDAP
-
-goQuotaView.pl - read collected data from quota.db and print it to
-                 stdout in human readable format
-
-goSquid.pl - connect this script to squid
-             redirect_program /usr/local/sbin/goSquid
-
-goAgent.pl - one script to create home directories and mailboxes on
-             filesystem. run it via cron
-  
-mkHash.pl  - create hash file for black list
-
-At this time all scripts have no config file. Please, edit source to configure.
-
-Igor Muratov <migor@altlinux.org>
diff --git a/contrib/scripts/goAgent.pl b/contrib/scripts/goAgent.pl
deleted file mode 100644 (file)
index 41b991e..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-#!/usr/bin/perl
-#
-# Igor Muratov <migor@altlinux.org>
-#
-# Find changes at LDAP and put this to filesystem
-#
-#
-# Igor Muratov <migor@altlinux.org>
-# 20041004
-# - Added rebuildVirtual function
-# 
-# Igor Muratov <migor@altlinux.org>
-# 20040617:
-# - Changed search fiter to exclude gosaUserTemplate entries
-#
-# Simon Liebold <s.liebold@gmx.de>:
-# 20040617:
-# - Changed $TS_FILE-location
-#
-# $Id: goAgent.pl,v 1.4 2004/11/19 21:46:56 migor-guest Exp $ 
-#
-
-use strict;
-use Net::LDAP;
-
-my $LDAP_HOST='localhost';
-my $LDAP_PORT='389';
-my $LDAP_BASE='dc=example,dc=com';
-#my $LDAP_USER='cn=admin,dc=example,dc=com';
-#my $LDAP_PASS='secret';
-
-my $HOME_DIR='/home';
-my $TS_FILE='/tmp/gosa_timestamp';
-my $KEYS_DIR='/etc/openssh/authorized_keys2';
-my $MAIL_DIR='/var/spool/mail';
-my $VLOCAL='/etc/postfix/virtual_local';
-my $VFORWARD='/etc/postfix/virtual_forward';
-my ($ldap, $mesg, $entry);
-my $virtuals = 0;
-
-# Anonymous bind to LDAP
-sub anonBind
-{
-       my $ldap = Net::LDAP->new( $LDAP_HOST, port => $LDAP_PORT );
-       my $mesg = $ldap->bind();
-       $mesg->code && die $mesg->error;
-       return $ldap;
-}
-
-# Bind as LDAP user
-#sub userBind
-#{
-#      my $ldap = Net::LDAP->new( $LDAP_HOST, port => $LDAP_PORT );
-#      my $mesg = $ldap->bind($LDAP_USER, password=>$LDAP_PASS);
-#      $mesg->code && die $mesg->error;
-#      return $ldap;
-#}
-
-# Read timestamp
-sub getTS
-{
-       open(F, "< $TS_FILE");
-       my $ts = <F>;
-       chop $ts;
-       $ts ||= "19700101000000Z";
-       return $ts;
-}
-
-# save timestamp
-sub putTS
-{
-       my $ts = `date -u '+%Y%m%d%H%M%SZ'`;
-       open(F, "> $TS_FILE");
-       print F $ts;
-}
-
-sub rebuildVirtuals
-{
-       print "Rebuild virtuals table for postfix\n";
-       $mesg = $ldap->search(
-               base => $LDAP_BASE,
-               filter => "(&(objectClass=gosaMailAccount)(gosaMailDeliveryMode=[*L*])(|(mail=*)(gosaMailAlternateAddress=*)))",
-               attrs =>  [
-                       'mail',
-                       'uid',
-                       'gosaMailForwardingAddress',
-                       'memberUid'
-               ],
-       );
-
-       # Work if changes is present
-       open(VIRT, "> $VLOCAL");
-       foreach my $entry ($mesg->all_entries)
-       {
-               foreach my $addr ($entry->get_value('mail'))
-               {
-                       print VIRT "$addr\t";
-                       print VIRT join(",", (
-                               $entry->get_value("uid"),
-                               $entry->get_value("gosaMailForwardingAddress"),
-                               $entry->get_value("memberUid"),
-                       ));
-                       print VIRT "\n";
-               }
-       }
-       close(VIRT);
-       `postmap $VLOCAL`;
-
-       $mesg = $ldap->search(
-               base => $LDAP_BASE,
-               filter => "(&(objectClass=gosaMailAccount)(!(gosaMailDeliveryMode=[*L*]))(|(mail=*)(gosaMailAlternateAddress=*)))",
-               attrs =>  [
-                       'gosaMailForwardingAddress',
-               ],
-       );
-
-       # Work if changes is present
-       open(VIRT, "> $VFORWARD");
-       foreach my $entry ($mesg->all_entries)
-       {
-               foreach my $addr ($entry->get_value('mail'))
-               {
-                       print VIRT "$addr\t";
-                       print VIRT join(",", (
-                               $entry->get_value("gosaMailForwardingAddress"),
-                       ));
-                       print VIRT "\n";
-               }
-       }
-       close(VIRT);
-       `postmap $VFORWARD`;
-}
-
-sub posixAccount
-{
-       my $entry = shift;
-       my $uid = ($entry->get_value('uid'))[0];
-       my $home = ($entry->get_value('homeDirectory'))[0];
-       my $uidNumber = ($entry->get_value('uidNumber'))[0];
-       my $gidNumber = ($entry->get_value('gidNumber'))[0];
-
-       print "Update posixAccount: $uid\n";
-       `install -dD -m0701 -o$uidNumber:$gidNumber $home`;
-       #`install -d -m0700 -o$uidNumber:$gidNumber $home/.ssh`;
-       #`install -d -m0751 -o$uidNumber:$gidNumber $home/.public_html`;
-       print "\tEntry ".$entry->dn()." updated\n";
-}
-
-# Get ssh keys and place to system directory
-sub strongAuthenticationUser
-{
-       my $entry = shift;
-       my $uid = ($entry->get_value('uid'))[0];
-       open(KEYS, "> $KEYS_DIR/$uid");
-       print KEYS $_ foreach ($entry->get_value('userCertificate;binary'));
-}
-
-# Create mailbox if need
-sub inetLocalMailRecipient
-{
-       my $entry = shift;
-       my $uid = ($entry->get_value('uid'))[0];
-       my $mail = ($entry->get_value('mailLocalAddress'))[0];
-       my $addr = ($entry->get_value('mailRoutingAddress'))[0];
-       my $uidNumber = ($entry->get_value('uidNumber'))[0];
-       my $mailbox = "$MAIL_DIR/$uid";
-
-       print "Update inetLocalMailRecipient: $mail\n";
-       if( $uid eq $addr )
-       {
-               if( -f "$mailbox" )
-               {
-                       print "Warning: mailbox $mailbox alredy exists. No changes.\n";
-               } else {
-                       `install -m660 -o$uidNumber -gmail /dev/null $mailbox`;
-               }
-       }
-       print "\tEntry ".$entry->dn()." updated\n";
-}
-
-sub disassemble
-{
-       my $entry = shift;
-
-       foreach my $attr ($entry->get_value('objectClass'))
-       {
-               if( $attr eq "posixAccount" ) {
-                       posixAccount($entry);
-               } elsif( $attr eq "inetLocalMailRecipient" ) {
-                       inetLocalMailRecipient($entry);
-               } elsif( $attr eq "strongAuthenticationUser" ) {
-                       strongAuthenticationUser($entry);
-               } elsif( $attr eq "gosaMailAccount" ) {
-                       $virtuals++;
-               }
-       }
-}
-
-#
-# Start main process
-#
-
-# Read timestamp from file
-my $ts = getTS;
-
-$ldap = anonBind;
-$mesg = $ldap->search(
-       base => $LDAP_BASE,
-       filter => "(&(modifyTimestamp>=$ts)(!(objectClass=gosaUserTemplate)))"
-);
-
-# Put timestamp to file
-putTS;
-
-# Work if changes is present
-if($mesg->count > 0)
-{
-       print "Processing records modified after $ts\n\n";
-
-       foreach my $entry ($mesg->all_entries)
-       {
-               disassemble($entry);
-       }
-       rebuildVirtuals if $virtuals;
-}
diff --git a/contrib/scripts/goQuota.pl b/contrib/scripts/goQuota.pl
deleted file mode 100644 (file)
index cceeffa..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-#!/usr/bin/perl
-#
-# Parse squid log and write current traffic usage by users into cache
-#
-# Igor Muratov <migor@altlinux.org>
-#
-# $Id: goQuota.pl,v 1.4 2005/04/03 00:46:14 migor-guest Exp $
-#
-
-use strict;
-use Time::Local;
-use Net::LDAP;
-use DB_File;
-use POSIX qw(strftime);
-
-my $debug = 0;
-$|=1;
-
-my $LDAP;
-my $LDAP_HOST = "localhost";
-my $LDAP_PORT = "389";
-my $LDAP_BASE = "ou=People,dc=example,dc=com";
-
-my $ACCESS_LOG = '/var/log/squid/access.log';
-my $CACHE_FILE = '/var/spool/squid/quota.db';
-my $DEFAULT_PERIOD = 'm';
-my $FORMAT = "A16 A5 S S L A5 L L L";
-
-my %cache;
-my @lines;
-
-sub timestamp
-{
-       return strftime("%a %b %X goQuota[$$]: ", localtime);
-}
-
-sub anonBind
-{
-       my $ldap = Net::LDAP->new( $LDAP_HOST, port => $LDAP_PORT );
-       if($ldap)
-       {
-               my $mesg = $ldap->bind();
-               $mesg->code && warn timestamp, "Can't bind to ldap://$LDAP_HOST:$LDAP_PORT:", $mesg->error, "\n";
-               return $ldap;
-       }
-       else
-       {
-               warn timestamp, "Can't connect to ldap://$LDAP_HOST:$LDAP_PORT\n";
-               return undef;
-       }
-}
-
-# Retrive users's data from LDAP
-sub update_userinfo
-{
-       my $user = shift;
-       my $uid = $user->{uid};
-
-       return undef unless $LDAP;
-
-       # User unknown or cache field is expired
-       my $result = $LDAP->search( base=>$LDAP_BASE,
-               filter=>"(&(objectClass=gosaProxyAccount)(uid=$uid))",
-               attrs=>[
-                       'uid',
-                       'gosaProxyAcctFlags',
-                       'gosaProxyQuota',
-                       'gosaProxyQuotaPeriod',
-                       'gosaProxyWorkingStop',
-                       'gosaProxyWorkingStart',
-                       'modifyTimestamp'
-               ]
-       );
-       $result->code && warn timestamp, "Failed to search: ", $result->error;
-
-       # Get user's data
-       if($result->count)
-       {
-               my $entry = ($result->entries)[0];
-
-               $user->{uid} = ($entry->get_value('uid'))[0];
-               $user->{modifyTimestamp} = ($entry->get_value('modifyTimestamp'))[0];
-               $user->{gosaProxyWorkingStart} = ($entry->get_value('gosaProxyWorkingStart'))[0];
-               $user->{gosaProxyWorkingStop} = ($entry->get_value('gosaProxyWorkingStop'))[0];
-               $user->{gosaProxyAcctFlags} = ($entry->get_value('gosaProxyAcctFlags'))[0];
-
-               my ($quota, $unit) = ($entry->get_value('gosaProxyQuota'))[0] =~ /(\d+)(\S)/g;
-               $user->{gosaProxyQuota} = $quota;
-               $user->{gosaProxyQuota} *= 1024 if $unit =~ /[Kk]/;
-               $user->{gosaProxyQuota} *= 1048576 if $unit =~ /[Mm]/;
-               $user->{gosaProxyQuota} *= 1073741824 if $unit =~ /[Gg]/;
-
-               $user->{gosaProxyQuotaPeriod} = ($entry->get_value('gosaProxyQuotaPeriod'))[0] || $DEFAULT_PERIOD;
-               # Return
-               warn timestamp, "User $uid found in LDAP.\n";
-               return 1;
-       } else {
-               # Unknown user
-               warn timestamp, "User $uid does not exists in LDAP.\n";
-               $user->{uid} = $uid;
-               $user->{gosaProxyAcctFlags} = '[FTB]';
-               $user->{gosaProxyQuota} = 0;
-               $user->{gosaProxyQuotaPeriod} = 'y';
-               return 0;
-       }
-}
-
-sub get_update
-{
-       my $ts = shift;
-       my %update;
-       my $result = $LDAP->search( base=>$LDAP_BASE,
-               filter=>"(&(objectClass=gosaProxyAccount)(modifyTimestamp>=$ts))",
-               attrs=>'uid'
-       );
-
-       # Get user's data
-       if($result->count)
-       {
-               my $entry = ($result->entries)[0];
-               $update{($entry->get_value('uid'))[0]}++;
-       }
-       return %update;
-}
-
-# Check quota
-sub update_quota
-{
-       my $user = shift;
-       my $uid = $user->{uid};
-
-       my $period = 0;
-       $period = 3600 if $user->{gosaProxyQuotaPeriod} eq 'h';
-       $period = 86400 if $user->{gosaProxyQuotaPeriod} eq 'd';
-       $period = 604800 if $user->{gosaProxyQuotaPeriod} eq 'w';
-       $period = 2592000 if $user->{gosaProxyQuotaPeriod} eq 'm';
-       $period = 220752000 if $user->{gosaProxyQuotaPeriod} eq 'y';
-
-       if($user->{lastRequest} - $user->{firstRequest} > $period)
-       {
-               if($user->{trafficUsage} > $user->{gosaProxyQuota})
-               {
-                       warn timestamp, "Reduce quota for $uid while $period seconds.\n";
-                       $user->{trafficUsage} -= $user->{gosaProxyQuota};
-                       $user->{firstRequest} += $period;
-               }
-               else
-               {
-                       warn timestamp, "Restart quota for $uid.\n";
-                       $user->{trafficUsage} = 0;
-                       $user->{firstRequest} = $user->{lastRequest};
-               }
-       }
-}
-
-sub dump_data
-{
-       my $user = shift;
-       print "User: ",$user->{uid},"\n";
-       print "\t",$user->{modifyTimestamp},"\n";
-       print "\t",$user->{gosaProxyAcctFlags},"\n";
-       print "\t",$user->{gosaProxyWorkingStart},"\n";
-       print "\t",$user->{gosaProxyWorkingStop},"\n";
-       print "\t",$user->{gosaProxyQuota},"\n";
-       print "\t",$user->{gosaProxyQuotaPeriod},"\n";
-       print "\t",$user->{trafficUsage},"\n";
-       print "\t",$user->{firstRequest},"\n";
-       print "\t",$user->{lastRequest},"\n";
-}
-
-sub unpack_user
-{
-       my $uid = shift;
-       my $user;
-
-       $user->{uid} = $uid;
-       (
-               $user->{modifyTimestamp},
-               $user->{gosaProxyAcctFlags},
-               $user->{gosaProxyWorkingStart},
-               $user->{gosaProxyWorkingStop},
-               $user->{gosaProxyQuota},
-               $user->{gosaProxyQuotaPeriod},
-               $user->{trafficUsage},
-               $user->{firstRequest},
-               $user->{lastRequest}
-       ) = unpack($FORMAT, $cache{$uid});
-
-       return $user;
-}
-
-sub pack_user
-{
-       my $user = shift;
-
-       $cache{$user->{uid}} = pack(
-               $FORMAT,
-               $user->{modifyTimestamp},
-               $user->{gosaProxyAcctFlags},
-               $user->{gosaProxyWorkingStart},
-               $user->{gosaProxyWorkingStop},
-               $user->{gosaProxyQuota},
-               $user->{gosaProxyQuotaPeriod},
-               $user->{trafficUsage},
-               $user->{firstRequest},
-               $user->{lastRequest}
-       );
-}
-
-#--------------------------------------
-$LDAP = anonBind or die timestamp, "No lines processed.\n";
-
-# This is a first time parsing?
-my $firstStart = 1;
-$firstStart = 0 if -e $CACHE_FILE;
-
-# Open log file and cache
-my $cache = tie(%cache, 'DB_File', $CACHE_FILE, O_CREAT|O_RDWR);
-my $log = tie(@lines, 'DB_File', $ACCESS_LOG, O_RDWR, 0640, $DB_RECNO)
-       or die "Cannot open file $ACCESS_LOG: $!\n";
-
-# Mark users which updated in LDAP
-my %updated;
-if(! $firstStart)
-{
-       my $ts = strftime("%Y%m%d%H%M%SZ", gmtime);
-       %updated = get_update($cache{MODIFY_TIMESTAMP} || "19700101000000Z");
-
-       my @count = %updated;
-       $cache{MODIFY_TIMESTAMP} = $ts if $#count;
-
-       foreach my $u (keys %updated)
-       {
-               warn timestamp, "User $u has been updated in LDAP. Refresh data.\n";
-               my $user = unpack_user($u);
-               update_userinfo($user);
-               pack_user($user);
-       }
-}
-
-# Processing log file
-my $index = $cache{TIMESTAMP} < (split / +/, $lines[0])[0]
-       ? 0 : $cache{STRING_NUMBER};
-warn timestamp, "Cache update start at line $index.\n";
-while($lines[$index])
-{
-       # There are array named lines with elements
-       # 0 - line timestamp
-       # 1 - ?? (unused)
-       # 2 - client's IP (unused)
-       # 3 - squid's cache status TEXT_CODE/num_code (unused)
-       # 4 - object size in bytes
-       # 5 - metod (unused)
-       # 6 - URL (unused)
-       # 7 - username
-       # 8 - load status TYPE/source
-       # 9 - mime type (unused)
-       my @line = split / +/, $lines[$index++];
-
-       # Skip line if have no incoming traffic
-       (my $errcode = $line[8]) =~ s/\/\S+//;
-       next if $errcode eq "NONE";
-
-       # Get data from cache
-       (my $uid = $line[7]) =~ s/^-$/anonymous/;
-       my $user = unpack_user($uid);
-
-       # Update user info from LDAP if need
-       if ( !exists($cache{$uid}) )
-       {
-               warn timestamp, "User $uid is not in cache. Go to search LDAP.\n";
-               update_userinfo($user);
-       }
-
-       # Update traffic info
-       $user->{trafficUsage} += $line[4];
-       $user->{firstRequest} |= $line[0];
-       $user->{lastRequest} = $line[0];
-
-       update_quota($user);
-       pack_user($user);
-
-       dump_data($user) if $debug;
-
-       $cache{TIMESTAMP} = $user->{lastRequest};
-}
-
-warn timestamp, $index - $cache{STRING_NUMBER}, " new lines processed.\n";
-$cache{STRING_NUMBER} = $index;
-
-$LDAP->unbind;
-untie @lines;
-untie %cache;
-
diff --git a/contrib/scripts/goQuotaView.pl b/contrib/scripts/goQuotaView.pl
deleted file mode 100644 (file)
index 7dd1497..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/perl
-#
-# Show user info from cache
-#
-# Igor Muratov <migor@altlinux.org>
-#
-# $Id: goQuotaView.pl,v 1.2 2005/04/03 00:46:14 migor-guest Exp $
-#
-
-use strict;
-use DB_File;
-
-my $CACHE_FILE = '/var/spool/squid/quota.db';
-my $FORMAT = "A16 A5 S S L A5 L L L";
-
-my %cache;
-
-sub min2time
-{
-       my $min = shift;
-       return sprintf("%2d:%02d",$min/60,$min%60);
-}
-
-sub show_user
-{
-       my $uid = shift;
-
-       my (
-               $modifyTimestamp, $gosaProxyAcctFlags, $gosaProxyWorkingStart,
-               $gosaProxyWorkingStop, $gosaProxyQuota, $gosaProxyQuotaPeriod,
-               $trafficUsage, $firstRequest, $lastRequest
-       ) = unpack($FORMAT, $cache{$uid});
-
-       my ($ts_Y, $ts_M, $ts_D, $ts_h, $ts_m, $ts_s)
-               = $modifyTimestamp =~ /(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/g;
-       my $ts = "$ts_D\.$ts_M\.$ts_Y $ts_h:$ts_m:$ts_s GMT";
-
-       $gosaProxyAcctFlags =~ s/[\[\]]//g;
-       $gosaProxyAcctFlags =~ s/F/unwanted content, /g;
-       $gosaProxyAcctFlags =~ s/T/work time, /g;
-       $gosaProxyAcctFlags =~ s/B/traffic/g;
-
-       $gosaProxyQuotaPeriod =~ s/h/hour/;
-       $gosaProxyQuotaPeriod =~ s/d/day/;
-       $gosaProxyQuotaPeriod =~ s/w/week/;
-       $gosaProxyQuotaPeriod =~ s/m/month/;
-       $gosaProxyQuotaPeriod =~ s/y/year/;
-
-       $firstRequest = localtime($firstRequest);
-       $lastRequest = localtime($lastRequest);
-
-       printf "User: %s
-  LDAP modify timestamp\t%s
-  Limited by\t\t%s
-  Work time from\t%s
-  Work time to\t\t%s
-  Quota period\t\tOne %s
-  Traffic quota size\t%s bytes
-  Current traffic usage\t%s bytes
-  First request time\t%s
-  Last request time\t%s\n",
-       $uid, $ts, $gosaProxyAcctFlags, min2time($gosaProxyWorkingStart),
-       min2time($gosaProxyWorkingStop), $gosaProxyQuotaPeriod, $gosaProxyQuota,
-       $trafficUsage, $firstRequest, $lastRequest;
-}
-
-#------------------------
-tie(%cache, 'DB_File', $CACHE_FILE, O_CREAT|O_RDWR);
-
-if($ARGV[0])
-{
-       show_user($ARGV[0]);
-}
-else
-{
-       print "eee\n";
-       printf "LAST STRING: %d\nLAST CACHE UPDATE: %s\nLDAP LAST CHANGE:  %s\n",
-               $cache{STRING_NUMBER},
-               time2str("%d.%m.%Y %H:%M:%S",$cache{TIMESTAMP}),
-               $cache{MODIFY_TIMESTAMP};
-
-       foreach my $user (keys %cache)
-       {
-               next if $user eq "TIMESTAMP";
-               next if $user eq "STRING_NUMBER";
-               next if $user eq "MODIFY_TIMESTAMP";
-               show_user($user);
-       }
-}
-
-untie %cache;
diff --git a/contrib/scripts/goSquid.pl b/contrib/scripts/goSquid.pl
deleted file mode 100644 (file)
index b91db16..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/perl
-#
-# Squid redirect programm for GOsa project
-#
-# Igor Muratov <migor@altlinux.org>
-#
-# $Id: goSquid.pl,v 1.3 2005/04/03 00:46:14 migor-guest Exp $
-#
-
-use strict;
-use POSIX qw(strftime);
-use Time::Local;
-use DB_File;
-
-my $debug = 0;
-$|=1;
-
-my $DEFAULT_URL = "http://www.squid-cache.org/Squidlogo2.gif";
-my $black_list = '/var/spool/squid/domains.db';
-my $cache_file = '/var/spool/squid/quota.db';
-my $format = "A16 A5 S S L A5 L L L";
-
-my %cache;
-my %blacklist;
-
-sub timestamp
-{
-       return strftime("%a %b %X goSquid[$$]: ", localtime);
-}
-
-# Check url in our blacklist
-sub unwanted_content
-{
-       my $url = shift;
-       my $host = (split(/\//, $url))[2];
-
-       return 1 if exists($blacklist{$host}) and $blacklist{$host} > 0;
-       return undef;
-}
-
-# Check work time limit
-sub work_time
-{
-       my $user = shift;
-       my ($min,$hour) = (localtime)[1,2];
-       my $time = $hour * 60 + $min;
-
-       return 1 if $user->{gosaProxyWorkingStart} < $time and $user->{gosaProxyWorkingStop} > $time;
-       return undef;
-}
-
-sub quota_exceed
-{
-       my $user = shift;
-
-       return 1 if $user->{trafficUsage} > $user->{gosaProxyQuota};
-       return undef;
-}
-
-sub check_access
-{
-       my ($user, $url) = @_;
-
-       $user->{timed} = 0;
-       $user->{quoted} = 0;
-       $user->{filtered} = 0;
-
-       if($user->{gosaProxyAcctFlags} =~ m/[F]/)
-       {
-               # Filter unwanted content
-               $user->{filtered} = 1 if unwanted_content($url);
-       }
-       if($user->{gosaProxyAcctFlags} =~ m/[T]/)
-       {
-               # Filter unwanted content during working hours only
-               $user->{timed} = 1 if work_time($user);
-       }
-       if($user->{gosaProxyAcctFlags} =~ m/B/)
-       {
-               $user->{quoted} = 1 if quota_exceed($user);
-       }
-}
-
-#--------------------------------------
-while (<>) {
-       my ($url, $addr, $uid, $method) = split;
-       my $time = timelocal(localtime);
-       tie(%blacklist, 'DB_File', $black_list, O_RDONLY);
-       tie(%cache, 'DB_File', $cache_file, O_RDONLY);
-
-       if( exists($cache{$uid}) )
-       {
-               my $user;
-               $user->{uid} = $uid;
-               (
-                       $user->{modifyTimestamp},
-                       $user->{gosaProxyAcctFlags},
-                       $user->{gosaProxyWorkingStart},
-                       $user->{gosaProxyWorkingStop},
-                       $user->{gosaProxyQuota},
-                       $user->{gosaProxyQuotaPeriod},
-                       $user->{trafficUsage},
-                       $user->{firstRequest},
-                       $user->{lastRequest}
-               ) = unpack($format, $cache{$uid});
-
-               check_access($user, $url);
-
-               if($user->{'disabled'})
-               {
-                       warn timestamp, "Access denied for unknown user $uid\n";
-               }
-               elsif($user->{'timed'})
-               {
-                       warn timestamp, "Access denied by worktime for $uid\n";
-               }
-               elsif($user->{'quoted'})
-               {
-                       warn timestamp, "Access denied by quota for $uid\n";
-               }
-               elsif($user->{'filtered'})
-               {
-                       warn timestamp, "Content $url filtered for $uid\n";
-               }
-               else
-               {
-                       print "$url\n";
-                       next;
-               }
-       }
-
-       untie %blacklist;
-       untie %cache;
-
-       print "$DEFAULT_URL\n";
-}
diff --git a/contrib/scripts/gosa b/contrib/scripts/gosa
deleted file mode 100755 (executable)
index d6cd93a..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/bin/sh
-# Start script for GOsa to be started via mozilla
-
-url=""
-if [ $# -ne 1 ]; then
-       echo "Usage: $(basename $0) <URL>"
-       exit 1
-fi
-
-# Check for presence of gosa profile
-if [ ! -d $HOME/.mozilla/firefox/*.gosa ]; then
-       firefox -CreateProfile gosa
-       config=`echo $HOME/.mozilla/firefox/*.gosa/`
-
-       cat << EOF > $config/prefs.js
-# Mozilla User Preferences
-
-/* Do not edit this file.
- *
- * If you make changes to this file while the browser is running,
- * the changes will be overwritten when the browser exits.
- *
- * To make a manual change to preferences, you can visit the URL about:config
- * For more information, see http://www.mozilla.org/unix/customizing.html#prefs
- */
-
-user_pref("app.update.autoUpdateEnabled", false);
-user_pref("app.update.enabled", false);
-user_pref("browser.download.folderList", 2);
-user_pref("browser.download.manager.showWhenStarting", false);
-user_pref("browser.formfill.enable", false);
-user_pref("browser.preferences.lastpanel", 1);
-user_pref("browser.search.selectedEngine", "Damnfresh");
-user_pref("browser.startup.homepage", "$url");
-user_pref("browser.startup.homepage_override.mstone", "rv:1.8.1.1");
-user_pref("extensions.disabledObsolete", true);
-user_pref("extensions.lastAppVersion", "2.0.0.1");
-user_pref("extensions.update.autoUpdateEnabled", false);
-user_pref("intl.charsetmenu.browser.cache", "ISO-8859-1");
-user_pref("network.cookie.prefsMigrated", true);
-user_pref("security.OCSP.URL", "");
-user_pref("security.OCSP.signingCA", "Builtin Object Token:IPS CLASE1 root");
-user_pref("security.warn_entering_secure", false);
-user_pref("security.warn_leaving_secure", false);
-user_pref("security.warn_submit_insecure", false);
-user_pref("security.warn_viewing_mixed", false);
-user_pref("signon.rememberSignons", false);
-user_pref("security.warn_submit_insecure", false);
-EOF
-
-       cat << EOF > $config/84795799.s
-#2c
-http://vserver-02
-.
-EOF
-
-       [ ! -d $config/chrome ] && mkdir -p $config/chrome
-       cat << EOF > $config/chrome/userChrome.css
-#main-menubar {
-        display: none;
-}
-#navigator-throbber {
-        display: none;
-}
-EOF
-
-cat << EOF > $config/localstore.rdf
-<?xml version="1.0"?>
-<RDF:RDF xmlns:NC="http://home.netscape.com/NC-rdf#"
-         xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-  <RDF:Description RDF:about="chrome://mozapps/content/downloads/unknownContentType.xul#unknownContentType"
-                   screenX="267"
-                   screenY="304" />
-  <RDF:Description RDF:about="chrome://browser/content/browser.xul#PersonalToolbar"
-                   currentset="__empty"
-                   collapsed="true" />
-  <RDF:Description RDF:about="chrome://browser/content/browser.xul#toolbar-menubar"
-                   currentset="__empty"
-                   collapsed="true" />
-  <RDF:Description RDF:about="chrome://browser/content/browser.xul#sidebar-box"
-                   collapsed="true"
-                   sidebarcommand=""
-                   width=""
-                   src="" />
-  <RDF:Description RDF:about="chrome://browser/content/browser.xul#status-bar"
-                   hidden="true" />
-  <RDF:Description RDF:about="chrome://browser/content/browser.xul">
-    <NC:persist RDF:resource="chrome://browser/content/browser.xul#main-window"/>
-    <NC:persist RDF:resource="chrome://browser/content/browser.xul#sidebar-box"/>
-    <NC:persist RDF:resource="chrome://browser/content/browser.xul#sidebar-title"/>
-    <NC:persist RDF:resource="chrome://browser/content/browser.xul#nav-bar"/>
-    <NC:persist RDF:resource="chrome://browser/content/browser.xul#PersonalToolbar"/>
-    <NC:persist RDF:resource="chrome://browser/content/browser.xul#toolbar-menubar"/>
-  </RDF:Description>
-  <RDF:Description RDF:about="chrome://mozapps/content/downloads/unknownContentType.xul">
-    <NC:persist RDF:resource="chrome://mozapps/content/downloads/unknownContentType.xul#unknownContentType"/>
-  </RDF:Description>
-  <RDF:Description RDF:about="chrome://global/content/customizeToolbar.xul">
-    <NC:persist RDF:resource="chrome://global/content/customizeToolbar.xul#CustomizeToolbarWindow"/>
-  </RDF:Description>
-  <RDF:Description RDF:about="chrome://help/content/help.xul#help"
-                   screenX="350"
-                   screenY="225"
-                   width="700"
-                   height="550" />
-  <RDF:Description RDF:about="chrome://browser/content/browser.xul#main-window"
-                   screenX="50"
-                   screenY="25"
-                   sizemode="normal"
-                   width="994"
-                   height="962" />
-  <RDF:Description RDF:about="chrome://help/content/help.xul">
-    <NC:persist RDF:resource="chrome://help/content/help.xul#help"/>
-  </RDF:Description>
-  <RDF:Description RDF:about="chrome://browser/content/browser.xul#nav-bar"
-                   currentset="__empty"
-                   collapsed="true" />
-</RDF:RDF>
-
-
-
-EOF
-fi
-
-
-# Start mozilla with GOsa profile
-firefox -P gosa
-
diff --git a/contrib/scripts/mkHash.pl b/contrib/scripts/mkHash.pl
deleted file mode 100644 (file)
index 84f4bd1..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-use DB_File;
-
-my $db = "/var/spool/squid/domains.db";
-my %db;
-
-tie(%db, 'DB_File', $db);
-
-while(<>)
-{
-       chomp;
-       unless(exists($db{$_}))
-       {
-               $db{$_} = 1;
-       }
-}
-
-untie %db;
diff --git a/contrib/scripts/net-resolver.sh b/contrib/scripts/net-resolver.sh
deleted file mode 100755 (executable)
index bd12026..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-
-# Check for number of parameters
-if [ $# -ne 1 ]; then
-       echo Usage: $(basename $0) dns-name
-       exit 1
-fi
-
-# Check for needed commands
-for cmd in /usr/bin/host /usr/bin/fping /usr/sbin/arp; do
-       if [ ! -x $cmd ]; then
-               echo $cmd command not found - aborting
-               exit 2
-       fi
-       eval $(echo ${cmd##*/}=$cmd)
-done
-
-mac=""
-ip=$(LANG=C $host $1 | grep address | head -n1 | sed 's/^.*[^0-9]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/g')
-if [ -z "$ip" ]; then
-       echo ";"
-       exit 0
-fi
-if $fping -c1 -r3 -t500 $ip &> /dev/null; then
-       mac=$($arp -n | awk "/^$ip/ {print \$3}")
-fi
-echo "$ip;$mac"
diff --git a/contrib/scripts/sieve_vacation/IMAP/Sieve.pm b/contrib/scripts/sieve_vacation/IMAP/Sieve.pm
deleted file mode 100644 (file)
index ec10808..0000000
+++ /dev/null
@@ -1,401 +0,0 @@
-# $Id: Sieve.pm,v 0.4.9b 2001/06/15 19:25:00 alain Exp $
-
-package IMAP::Sieve;
-
-use strict;
-use Carp;
-use IO::Select;
-use IO::Socket;
-use IO::Socket::INET;
-#use Text::ParseWords qw(parse_line);
-use Cwd;
-
-use vars qw($VERSION);
-
-$VERSION = '0.4.9b';
-
-sub new {
-    my $class = shift;
-    my $self = {};
-    bless $self, $class;
-    if ((scalar(@_) % 2) != 0) {
-       croak "$class called with incorrect number of arguments";
-    }
-    while (@_) {
-       my $key = shift(@_);
-       my $value = shift(@_);
-       $self->{$key} = $value;
-    }
-    $self->{'CLASS'} = $class;
-    $self->_initialize;
-    return $self;
-}
-
-sub _initialize {
-    my $self = shift;
-    my ($len,$userpass,$encode);
-    if (!defined($self->{'Server'})) {
-       croak "$self->{'CLASS'} not initialized properly : Server parameter missing";
-    }
-    if (!defined($self->{'Port'})) {
-       $self->{'Port'} = 2000; # default sieve port;
-    }
-    if (!defined($self->{'Login'})) {
-       croak "$self->{'CLASS'} not initialized properly : Login parameter missing";
-    }
-    if (!defined($self->{'Password'})) {
-       croak "$self->{'CLASS'} not initialized properly : Password parameter missing";
-    }
-    if (!defined($self->{'Proxy'})) {
-       $self->{'Proxy'} = ''; # Proxy;
-    }
-    if (defined($self->{'SSL'})) {
-       my $cwd= cwd;
-       my %ssl_defaults = (
-                         'SSL_use_cert' => 0,
-                         'SSL_verify_mode' => 0x00,
-                         'SSL_key_file' => $cwd."/certs/client-key.pem",
-                         'SSL_cert_file' => $cwd."/certs/client-cert.pem",
-                         'SSL_ca_path' => $cwd."/certs",
-                         'SSL_ca_file' => $cwd."/certs/ca-cert.pem",
-                         );
-       my @ssl_options;
-       my $ssl_key;
-       my $key;
-       foreach $ssl_key (keys(%ssl_defaults)) {
-               if (!defined($self->{$ssl_key})) {
-                       $self->{$ssl_key} = $ssl_defaults{$ssl_key};
-               }
-       }
-       foreach $ssl_key (keys(%{$self})) {
-               if ($ssl_key =~ /^SSL_/) {
-                       push @ssl_options, $ssl_key,$self->{$ssl_key};
-               }
-       }
-        my $SSL_try="use IO::Socket::SSL";
-       eval $SSL_try;
-       if (!eval {$self->{'Socket'} =
-               IO::Socket::SSL->new(PeerAddr => $self->{'Server'},
-                                    PeerPort => $self->{'Port'},
-                                    Proto => 'tcp',
-                                    Reuse => 1,
-                                    Timeout => 5,
-                                    @ssl_options);}) {
-               $self->_error("initialize", "couldn't establish a sieve SSL connection to",$self->{'Server'}, "[$!]","path=$cwd");
-               delete $self->{'Socket'};
-               return;
-       }
-     }
-     else {
-
-       if (!eval {$self->{'Socket'} = IO::Socket::INET->new(PeerAddr => $self->{'Server'},
-                                                        PeerPort => $self->{'Port'},
-                                                        Proto => 'tcp',
-                                                        Reuse => 1); })
-       {
-               $self->_error("initialize", "could'nt establish a Sieve connection to",$self->{'Server'});                              
-               return;
-       }
-    } # if SSL
-
-    my $fh = $self->{'Socket'};
-     $_ = $self->_read; #get banner
-    my $try=$_;
-    if (!/timsieved/i) {
-       $self->close;
-       $self->_error("initialize","bad response from",$self->{'Server'},$try);
-       return;
-    }
-    chomp;
-    if (/\r$/) {
-       chop;
-    }
-    if (/IMPLEMENTATION/) {
-       $self->{'Implementation'}=$1 if /^"IMPLEMENTATION" +"(.*)"/;
-       #version 2 of cyrus imap/timsieved
-       # get capability
-       # get OK as well
-       $_=$self->_read;
-        while (!/^OK/) {
-          $self->{'Capability'}=$1 if /^"SASL" +"(.*)"/;
-          $self->{'Sieve'}=$1 if /^"SIEVE" +"(.*)"/;
-          $_ = $self->_read;
-##        $_=$self->_read;
-       }
-    }
-    else {
-       $self->{'Capability'}=$_;
-    }
-    $userpass = "$self->{'Proxy'}\x00".$self->{'Login'}."\x00".$self->{'Password'};
-    $encode=encode_base64($userpass);
-    $len=length($encode);
-    print $fh "AUTHENTICATE \"PLAIN\" {$len+}\r\n";
-    print $fh "$encode\r\n";
-    
-    $_ = $self->_read;
-    $try=$_;
-    if ($try=~/NO/) {
-       $self->close;
-       $self->_error("Login incorrect while connecting to $self->{'Server'}", $try);
-       return;
-    } elsif (/OK/) {
-       $self->{'Error'}= "No Errors";
-       return;
-    } else {
-       #croak "$self->{'CLASS'}: Unknown error -- $_";
-       $self->_error("Unknown error",$try);
-       return;
-    }
-    $self->{'Error'}="No Errors";
-    return;
-}
-sub encode_base64 ($;$)
-{
-    my $res = "";
-    my $eol = $_[1];
-    $eol = "\n" unless defined $eol;
-    pos($_[0]) = 0;                          # ensure start at the beginning
-    while ($_[0] =~ /(.{1,45})/gs) {
-       $res .= substr(pack('u', $1), 1);
-       chop($res);
-    }
-    $res =~ tr|` -_|AA-Za-z0-9+/|;               # `# help emacs
-    # fix padding at the end
-    my $padding = (3 - length($_[0]) % 3) % 3;
-    $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
-    # break encoded string into lines of no more than 76 characters each
-    if (length $eol) {
-       $res =~ s/(.{1,76})/$1$eol/g;
-    }
-    $res;
-}
-
-
-sub _error {
-    my $self = shift;
-    my $func = shift;
-    my @error = @_;
-
-    $self->{'Error'} = join(" ",$self->{'CLASS'}, "[", $func, "]:", @error);
-}
-
-sub _read {
-       my $self = shift;
-       my $buffer ="";
-       my $char = "";
-       my $bytes= 1;
-       while ($bytes == 1) {
-               $bytes = sysread $self->{'Socket'},$char,1;
-               if ($bytes == 0) {
-                       if (length ($buffer) != 0) {
-                               return $buffer;
-                       }
-                       else {
-                               return;
-                       }
-               }
-               else {
-                       if (($char eq "\n") or ($char eq "\r")) {
-                               if (length($buffer) ==0) {
-                                       # remove any cr or nl leftover
-                               }
-                               else {
-                                       return $buffer;
-                               }
-                       }
-                       else {
-                               $buffer.=$char;
-                       }
-               }
-       }
-}
-                               
-                               
-sub close {
-    my $self = shift;
-     if (!defined($self->{'Socket'})) {
-       return 0;
-     }
-     my $fh =$self->{'Socket'};
-    print $fh "LOGOUT\r\n";
-    close($self->{'Socket'});
-    delete $self->{'Socket'};
-}
-
-sub putscript {
-    my $self = shift;
-    my $len;
-
-    if (scalar(@_) != 2)  {
-       $self->_error("putscript", "incorrect number of arguments");
-       return 1;
-    }
-
-    my $scriptname = shift;
-    my $script = shift;
-
-    if (!defined($self->{'Socket'})) {
-       $self->_error("putscript", "no connection open to", $self->{'Server'});
-       return 1;
-    }
-    $len=length($script);
-    my $fh = $self->{'Socket'};
-    print $fh "PUTSCRIPT \"$scriptname\" {$len+}\r\n";
-    print $fh "$script\r\n";
-    $_ = $self->_read;
-    if (/^OK/) {
-       $self->{'Error'} = 'No Errors';
-       return 0;
-    } else {
-       $self->_error("putscript", "couldn't save script", $scriptname, ":", $_);
-       return 1;
-    }
-}
-
-sub deletescript {
-    my $self = shift;
-
-    if (scalar(@_) != 1) {
-       $self->_error("deletescript", "incorrect number of arguments");
-       return 1;
-    }
-    my $script = shift;
-    if (!defined($self->{'Socket'})) {
-       $self->_error("deletescript", "no connection open to", $self->{'Server'});
-       return 1;
-    }
-    my $fh = $self->{'Socket'};
-    print $fh "DELETESCRIPT \"$script\"\r\n";
-    $_ = $self->_read;
-    if (/^OK/) {
-       $self->{'Error'} = 'No Errors';
-       return 0;
-    } else {
-       $self->_error("deletescript", "couldn't delete", $script, ":", $_);
-       return 1;
-    }
-}
-sub getscript { # returns a string
-    my $self = shift;
-    my $allscript;
-
-    if (scalar(@_) != 1) {
-       $self->_error("getscript", "incorrect number of arguments");
-       return 1;
-    }
-    my $script = shift;
-    if (!defined($self->{'Socket'})) {
-       $self->_error("getscript", "no connection open to", $self->{'Server'});
-       return 1;
-    }
-    my $fh = $self->{'Socket'};
-    print $fh "GETSCRIPT \"$script\"\r\n";
-    $_ = $self->_read;
-    if (/^{.*}/) { $_ = $self->_read;  } # remove file size line
-
-    # should probably use the file size to calculate how much to read in
-    while ((!/^OK/) && (!/^NO/)) {
-       $_.="\n" if $_ !~/\n.*$/; # replace newline that _read removes
-       $allscript.=$_; 
-       $_ = $self->_read;
-    }
-    if (/^OK/) {
-       return $allscript;
-    } else {
-       $self->_error("getscript", "couldn't get script", $script, ":", $_);
-       return;
-    }
-}
-
-sub setactive {
-    my $self = shift;
-
-    if (scalar(@_) != 1) {
-       $self->_error("setactive", "incorrect number of arguments");
-       return 1;
-    }
-    my $script = shift;
-    if (!defined($self->{'Socket'})) {
-       $self->_error("setactive", "no connection open to", $self->{'Server'});
-       return 1;
-    }
-    my $fh = $self->{'Socket'};
-    print $fh "SETACTIVE \"$script\"\r\n";
-    $_ = $self->_read;
-    if (/^OK/) {
-       $self->{'Error'} = "No Errors";
-       return 0;
-    } else {
-       $self->_error("setactive", "couldn't set as active", $script, ":", $_);
-       return 1;
-    }
-}
-
-
-sub noop {
-    my $self = shift;
-    my ($id, $acl);
-
-    if (!defined($self->{'Socket'})) {
-       $self->_error("noop", "no connection open to", $self->{'Server'});
-       return 1;
-    }
-    my $fh = $self->{'Socket'};
-    print $fh "NOOP\r\n";
-       $_ = $self->_read;
-       if (!/^OK/) {
-           $self->_error("noop", "couldn't do noop"
-                        );
-           return 1;
-       }
-    $self->{'Error'} = 'No Errors';
-    return 0;
-}
-
-
-sub listscripts {
-    my $self = shift;
-    my (@scripts);
-
-    if (!defined($self->{'Socket'})) {
-       $self->_error("listscripts", "no connection open to", $self->{'Server'});
-       return;
-    }
-
-    #send the command
-    $self->{'Socket'}->print ("LISTSCRIPTS\r\n");
-
-    # While we have more to read
-    while (defined ($_ = $self->_read)) {
-
-                       # Exit the loop if we're at the end of the text
-               last if (m/^OK.*/);
-
-                       # Select the stuff between the quotes (without the asterisk)
-               # m/^"([^"]+?)\*?"\r?$/;
-               # Select including the asterisk (to determine the default script)
-#              m/^"([^"]+?\*?)"\r?$/;
-               $_=~s/"//g;
-                       # Get the name of the script
-                       push @scripts, $_;
-     } 
-
-     if (/^OK/) {
-        return @scripts;
-     } else {
-
-
-
-    }
-    if (/^OK/) {
-       return @scripts;
-    } else {
-       $self->_error("list", "couldn't get list for",  ":", $_);
-       return;
-    }
-}
-
-1;
-__END__
-
diff --git a/contrib/scripts/sieve_vacation/update-vacation.pl b/contrib/scripts/sieve_vacation/update-vacation.pl
deleted file mode 100755 (executable)
index aeef964..0000000
+++ /dev/null
@@ -1,600 +0,0 @@
-#!/usr/bin/perl -w -I/usr/local/lib/perl
-#
-# This code is part of GOsa (https://gosa.gonicus.de)
-# Copyright (C) 2007 Frank Moeller
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-use strict;
-use IMAP::Sieve;
-use XML::Simple;
-use Data::Dumper;
-use Net::LDAP;
-use URI;
-use utf8;
-use Getopt::Std;
-use Date::Format;
-use vars qw/ %opt /;
-
-#
-# Definitions
-#
-my $gosa_config = "/etc/gosa/gosa.conf";
-my $opt_string = 'l:hs';
-my $location = "";
-my $today_gmt = time ();
-my $today = $today_gmt + 3600;
-my $server_attribute = "";
-my $alternate_address_attribute = "";
-my $gosa_sieve_script_name = "gosa";
-my $simple_bind_dn = "";
-my $simple_bind_dn_pwd = "";
-my $gosa_sieve_script_status = "FALSE";
-my $gosa_sieve_spam_header = "Sort mails with higher spam level";
-my ($ss,$mm,$hh,$day,$month,$year,$zone);
-
-#
-# Templates
-#
-my $gosa_sieve_header = "\#\#\#GOSA\nrequire\ \[\"fileinto\",\ \"reject\",\ \"vacation\"\]\;\n\n";
-my $vacation_header_template = "\# Begin vacation message";
-my $vacation_footer_template = "\# End vacation message";
-
-#
-# Placeholder
-#
-my $start_date_ph = "##STARTDATE##";
-my $stop_date_ph = "##STOPDATE##";
-
-#
-# Usage
-#
-sub usage {
-       die "Usage:\nperl $0 [option]\n
-            \twithout any option $0 uses the default location\n
-            \tOptions:
-            \t\t-l <\"location name\">\tuse special location
-            \t\t-s\t\t\tshow all locations
-            \t\t-h\t\t\tthis help \n";
-}
-
-#
-# Config import
-#
-sub read_config {
-       my $input = shift || die "need config file: $!";
-       my $stream = "";
-       open ( FILE, "< $input" ) or die "Error opening file $input: $! \n";
-       {
-               local $/ = undef;
-               $stream = <FILE>;
-       }
-       close ( FILE );
-       return $stream;
-}
-
-#
-# XML parser
-#
-sub parseconfig {
-       my $c_location = shift;
-       my $xmldata = shift;
-       chomp $c_location;
-       chomp $xmldata;
-       my $data = $xmldata;
-       my $xml = new XML::Simple ();
-       my $c_data = $xml -> XMLin( $xmldata);
-       my $config = {};
-       my $config_base;
-       my $ldap_admin;
-       my $ldap_admin_pwd;
-       my $url;
-       my $mailMethod;
-       #print Dumper ($c_data->{main}->{location}->{config});
-       if ( $c_data->{main}->{location}->{config} ) {
-               #print "IF\n";
-               $config_base = $c_data->{main}->{location}->{config};
-               $url = $c_data->{main}->{location}->{referral}->{url};
-               $ldap_admin = $c_data->{main}->{location}->{referral}->{admin};
-               $ldap_admin_pwd = $c_data->{main}->{location}->{referral}->{password};
-               $mailMethod = $c_data->{main}->{location}->{mailMethod};
-       } else {
-               #print "ELSE\n";
-               $config_base = $c_data->{main}->{location}->{$c_location}->{config};
-               $url = $c_data->{main}->{location}->{$c_location}->{referral}->{url};
-               $ldap_admin = $c_data->{main}->{location}->{$c_location}->{referral}->{admin};
-               $ldap_admin_pwd = $c_data->{main}->{location}->{$c_location}->{referral}->{password};
-               $mailMethod = $c_data->{main}->{location}->{$c_location}->{mailMethod};
-       }
-       print "$config_base -- $url -- $ldap_admin -- $ldap_admin_pwd -- $mailMethod\n";
-       $config->{config_base} = $config_base;
-       $config->{url} = $url;
-       $config->{mailMethod} = $mailMethod;
-       $config->{ldap_admin} = $ldap_admin;
-       $config->{ldap_admin_pwd} = $ldap_admin_pwd;
-
-       return $config;
-}
-
-#
-# Get default location
-#
-sub get_default_location {
-       my $xmldata = shift;
-       my $xml = new XML::Simple ( RootName=>'conf' );
-       my $c_data = $xml -> XMLin( $xmldata );
-       my $default = $c_data->{main}->{default};
-
-       return $default;
-}
-
-#
-# List all location
-#
-sub list_locations {
-       my $xmldata = shift;
-       my $xml = new XML::Simple ( RootName=>'conf' );
-       my $c_data = $xml -> XMLin( $xmldata );
-       my $default = get_default_location ( $xmldata );
-       $default = $default . " (default)";
-       my @locations = ( $default );
-       my $data_ref = $c_data->{main}->{location};
-       my @keys = keys ( %{$data_ref} );
-       @locations = (@locations, @keys);
-
-       return @locations;
-}
-
-#
-# LDAP error handling
-#
-sub ldap_error {
-       my ($from, $mesg) = @_;
-       print "Return code: ", $mesg->code;
-       print "\tMessage: ", $mesg->error_name;
-       print " :",          $mesg->error_text;
-       print "MessageID: ", $mesg->mesg_id;
-       print "\tDN: ", $mesg->dn;
-}
-
-
-#
-# LDAP search
-#
-sub ldap_search {
-       my $url = shift;
-       my $searchString = shift;
-       my $scope = shift;
-       my $base = shift;
-       my $attrs = shift;
-       my $bind_dn = shift;
-       my $bind_dn_pwd = shift;
-       
-       if ( $base eq "NULL" ) {
-               $base = "";
-       }
-       my $ldap = Net::LDAP->new( $url ) or die "$@";
-       if ( ( ! ( $bind_dn ) ) || ( ! ( $bind_dn_pwd ) ) ) {
-               $ldap->bind;
-       } else {
-               $ldap->bind ( $bind_dn, password => $bind_dn_pwd );
-       }
-
-       my $result = $ldap->search (    base    => "$base",
-                                       scope   => "$scope",
-                                       filter  => "$searchString",
-                                       attrs   =>  $attrs
-                                       );
-       if ( $result->code ) {
-               ldap_error ( "Searching", $result );
-       }
-
-       $ldap->unbind;
-       
-       return $result;
-}
-
-#
-# Retrieve LDAP server
-#
-sub get_ldap_server {
-       my $url = shift;
-       
-       my $uri = URI->new($url);
-
-       my $scheme = $uri->scheme;
-       my $host = $uri->host;
-       my $port = $uri->port;
-       #print "$scheme - $host - $port\n";
-       my $server = $scheme . "://" . $host . ":" . $port;
-
-       return $server;
-}
-
-#
-# Retrieve LDAP base
-#
-sub get_ldap_base {
-       my $url = shift;
-       my $config_base = shift;
-       my $bind_dn = shift;
-       my $bind_dn_pwd = shift;
-       my $filter = "(objectClass=*)";
-       my $init_base = "NULL";
-       my $scope = "base";
-       my $attributes = [ 'namingcontexts' ];
-       my $entry = {};
-       my $base = "";
-
-       $config_base =~ s/\,\ +/\,/g;
-       #print $url."\n";
-       #print $config_base."\n";
-       my $result = ldap_search ( $url, $filter, $scope, $init_base, $attributes, $bind_dn, $bind_dn_pwd );
-       my @entries = $result->entries;
-       my $noe = @entries;
-       #print $noe."\n";
-       foreach $entry ( @entries ) {
-               my $tmp = $entry->get_value ( 'namingcontexts' );
-               #print $tmp."\n";
-               $tmp =~ s/\,\ +/\,/g;
-               if ( $config_base =~ m/$tmp/ ) {
-                       $base = $entry->get_value ( 'namingcontexts' );
-               }
-       }
-
-       return $base;
-}
-
-#
-# SIEVE functions
-#
-sub opensieve {
-       my $admin = shift;
-       my $pass = shift;
-       my $user = shift;
-       my $server = shift;
-       my $port = shift;
-
-       #print ( "##### Proxy => $user, Server => $server, Login => $admin, Password => $pass, Port => $port ####\n" );
-
-       my $sieve = IMAP::Sieve->new ( 'Proxy' => $user, 'Server' => $server, 'Login' => $admin, 'Password' => $pass, 'Port' => $port );
-       return $sieve;
-}
-
-sub closesieve {
-       my $sieve = shift;
-
-       if ($sieve) {$sieve->close};
-}
-
-sub listscripts {
-       my $sieve = shift;
-
-       my @scripts = $sieve->listscripts;
-       my $script_list = join("\n",@scripts)."\n";
-       #print $script_list;
-       return $script_list;
-}
-
-sub getscript {
-       my $sieve = shift;
-       my $script = shift;
-       my $scriptfile;
-       chomp $script;
-       #print "$sieve\n";
-       #print "$script\n";
-
-       $scriptfile = $sieve->getscript($script);
-       return $scriptfile;
-}
-
-sub putscript {
-       my $sieve = shift;
-       my $scriptname = shift;
-       my $script = shift;
-       #print "$sieve\n";
-       #print "$scriptname\n";
-       #print "$script\n";
-
-       my $res=$sieve->putscript($scriptname,$script);
-       if ($res) {print $sieve->{'Error'}}
-       return;
-}
-
-sub setactive {
-       my $sieve = shift;
-       my $script = shift;
-
-       my $res=$sieve->setactive($script);
-       if ($res) { print $sieve->{'Error'};}
-       return;
-}
-
-#
-# main ()
-#
-# read options
-getopts( "$opt_string", \%opt );
-
-# read GOsa config
-my $input_stream = read_config ( $gosa_config );
-
-# get location
-if ( $opt{l} ) {
-       $location = $opt{l};
-} elsif ( $opt{h} ) {
-       usage ();
-       exit (0);
-} elsif ( $opt{s} ) {
-       my $loc;
-       my $counter = 1;
-       my @locations = list_locations ( $input_stream );
-       print "\nConfigured Locations: \n";
-       print "---------------------\n";
-       foreach $loc ( @locations ) {
-               print $counter . ". " . $loc . "\n";
-               $counter++;
-       }
-       print "\n\n";
-       exit (0);
-} else {
-       $location = get_default_location ( $input_stream );
-}
-
-# parse config
-my $config = parseconfig ( $location, $input_stream );
-my $ldap_url = get_ldap_server ( $config->{url} );
-my $gosa_config_base = $config->{config_base};
-my $bind_dn = $config->{ldap_admin};
-my $bind_dn_pwd = $config->{ldap_admin_pwd};
-my $mailMethod = $config->{mailMethod};
-utf8::encode($ldap_url);
-utf8::encode($gosa_config_base);
-utf8::encode($mailMethod);
-
-# default mailMethod = kolab
-if ( $mailMethod =~ m/kolab/i ) {
-       $server_attribute = "kolabHomeServer";
-       $alternate_address_attribute = "alias";
-} elsif ( $mailMethod =~ m/cyrus/i ) {
-       $server_attribute = "gosaMailServer";
-       $alternate_address_attribute = "gosaMailAlternateAddress";
-} else {
-       exit (0);
-}
-
-# determine LDAP base
-my $ldap_base = get_ldap_base ( $ldap_url, $gosa_config_base, $simple_bind_dn, $simple_bind_dn_pwd );
-
-# retrieve user informations with activated vacation feature
-my $filter = "(&(objectClass=gosaMailAccount)(gosaMailDeliveryMode=*V*)(!(gosaMailDeliveryMode=*C*)))";
-my $list_of_attributes = [ 'uid', 'mail', $alternate_address_attribute, 'gosaVacationMessage', 'gosaVacationStart', 'gosaVacationStop', $server_attribute ];
-my $search_scope = "sub";
-my $result = ldap_search ( $ldap_url, $filter, $search_scope, $ldap_base, $list_of_attributes, $simple_bind_dn, $simple_bind_dn_pwd );
-
-my @entries = $result->entries;
-my $noe = @entries;
-#print "NOE = $noe\n";
-my $entry = {};
-foreach $entry ( @entries ) {
-       # INITIALISATIONS
-       $gosa_sieve_script_status = "FALSE";
-       my @sieve_scripts = "";
-       my $script_name = "";
-       my $sieve_script = "";
-       my $sieve_vacation = "";
-       # END INITIALISATIONS
-       my $uid_v = $entry->get_value ( 'uid' );
-       #print "$uid_v\n";
-       my $mail_v = $entry->get_value ( 'mail' );
-       my @mailalternate = $entry->get_value ( $alternate_address_attribute );
-       my $vacation = $entry->get_value ( 'gosaVacationMessage' );
-       my $start_v = $entry->get_value ( 'gosaVacationStart' );
-       my $stop_v = $entry->get_value ( 'gosaVacationStop' );
-       my $server_v = $entry->get_value ( $server_attribute );
-
-       # temp. hack to compensate old gosa server name style
-       #if ( $server_v =~ m/^imap\:\/\//i ) {
-       #       $server_v =~ s/^imap\:\/\///;
-       #}
-       if ( ! ( $uid_v ) ) {
-               $uid_v = "";
-       }
-       if ( ! ( $mail_v ) ) {
-               $mail_v = "";
-       }
-       my @mailAddress = ($mail_v);
-       my $alias = "";
-       foreach $alias ( @mailalternate ) {
-               push @mailAddress, $alias;
-       }
-       my $addresses = "";
-       foreach $alias ( @mailAddress ) {
-               $addresses .= "\"" . $alias . "\", ";
-       }
-       $addresses =~ s/\ *$//;
-       $addresses =~ s/\,$//;
-       if ( ! ( $vacation ) ) {
-               $vacation = "";
-       }
-
-       if ( ! ( $start_v ) ) {
-               $start_v = 0;
-               next;
-       }
-       #print time2str("%d.%m.%Y", $start_v)."\n";
-       my $start_date_string = time2str("%d.%m.%Y", $start_v)."\n";
-
-       if ( ! ( $stop_v ) ) {
-               $stop_v = 0;
-               next;
-       }
-       #print time2str("%d.%m.%Y", $stop_v)."\n";
-       my $stop_date_string = time2str("%d.%m.%Y", $stop_v)."\n";
-
-       chomp $start_date_string;
-       chomp $stop_date_string;
-       $vacation =~ s/$start_date_ph/$start_date_string/g;
-       $vacation =~ s/$stop_date_ph/$stop_date_string/g;
-
-       if ( ! ( $server_v ) ) {
-               $server_v = "";
-               next;
-       }
-       #print $uid_v . " | " .
-       #       $addresses . " | " .
-       #       "\n";
-
-       my ($sieve_user, $tmp) = split ( /\@/, $mail_v );
-
-       print "today = $today\nstart = $start_v\nstop = $stop_v\n";
-       my $real_stop = $stop_v + 86400;
-       if ( ( $today >= $start_v ) && ( $today < $real_stop ) ) {
-               print "activating vacation for user $uid_v\n";
-
-               my $srv_filter = "(&(goImapName=$server_v)(objectClass=goImapServer))";
-               my $srv_list_of_attributes = [ 'goImapSieveServer', 'goImapSievePort', 'goImapAdmin', 'goImapPassword' ];
-               my $srv_result = ldap_search ( $ldap_url, $srv_filter, $search_scope, $ldap_base, $srv_list_of_attributes, $bind_dn, $bind_dn_pwd );
-               my @srv_entries = $srv_result->entries;
-               my $srv_entry = {};
-               my $noe = @srv_entries;
-               if ( $noe == 0 ) {
-                       printf STDERR "Error: no $server_attribute defined! Aboarting...";
-               } elsif ( $noe > 1 ) {
-                       printf STDERR "Error: multiple $server_attribute defined! Aboarting...";
-               } else {
-                       my $goImapSieveServer = $srv_entries[0]->get_value ( 'goImapSieveServer' );
-                       my $goImapSievePort = $srv_entries[0]->get_value ( 'goImapSievePort' );
-                       my $goImapAdmin = $srv_entries[0]->get_value ( 'goImapAdmin' );
-                       my $goImapPassword = $srv_entries[0]->get_value ( 'goImapPassword' );
-                       if ( ( $goImapSieveServer ) && ( $goImapSievePort ) && ( $goImapAdmin ) && ( $goImapPassword ) ) {
-#                              if ( ! ( $sieve_user = $uid_v ) ) {
-#                                      $sieve_user = $uid_v;
-#                              }
-                               #my $sieve = opensieve ( $goImapAdmin, $goImapPassword, $sieve_user, $goImapSieveServer, $goImapSievePort);
-                               my $sieve = opensieve ( $goImapAdmin, $goImapPassword, $uid_v, $goImapSieveServer, $goImapSievePort);
-                               @sieve_scripts = listscripts ( $sieve );
-                               #print Dumper (@sieve_scripts);
-                               $script_name = "";
-                               if ( @sieve_scripts ) {
-                                       foreach $script_name ( @sieve_scripts ) {
-                                               if ( $script_name =~ m/$gosa_sieve_script_name/ ) {
-                                                       $gosa_sieve_script_status = "TRUE";
-                                               }
-                                       }
-                                       if ( $gosa_sieve_script_status eq "TRUE" ) {
-                                               print "retrieving and modifying gosa sieve script for user $uid_v\n";
-                                               # requirements
-                                               $sieve_script = getscript( $sieve, $gosa_sieve_script_name );
-                                               #print "$sieve_script\n";
-                                               if ( ! ( $sieve_script ) ) {
-                                                       print "No Sieve Script! Creating New One!\n";
-                                                       $sieve_script = $gosa_sieve_header;
-                                               }
-                                               if ( $sieve_script =~ m/require.*\[.*["|'] *vacation *["|'].*\]/ ) {
-                                                       print "require vacation ok\n";
-                                               } else {
-                                                       print "require vacation not ok\n";
-                                                       print "modifying require statement\n";
-                                                       $sieve_script =~ s/require(.*\[.*)\]/require$1\, "vacation"\]/;
-                                               }
-                                               if ( ! ( $sieve_script =~ m/$vacation_header_template/ ) ) {
-                                                       print "no match header template\n";
-                                                       $sieve_vacation = $vacation_header_template .
-                                                                               "\n" .
-                                                                               "vacation :addresses [$addresses]\n" .
-                                                                               "\"" .
-                                                                               $vacation . 
-                                                                               "\n\"\;" .
-                                                                               "\n" .
-                                                                               $vacation_footer_template .
-                                                                               "\n\n";
-                                               }
-                                               #print ( "$sieve_vacation\n" );
-                                               #print ( "$sieve_script\n" );
-                                               # including vacation message
-                                               if ( $sieve_script =~ m/$gosa_sieve_spam_header/ ) {
-                                                       #print "MATCH\n";
-                                                       $sieve_script =~ s/($gosa_sieve_spam_header[^{}]*{[^{}]*})/$1\n\n$sieve_vacation/;
-                                               } else {
-                                                       $sieve_script =~ s/require(.*\[.*\]\;)/require$1\n\n$sieve_vacation/;
-                                               }
-                                               #print ( "START SIEVE $sieve_script\nSTOP SIEVE" );
-                                               # uploading new sieve script
-                                               putscript( $sieve, $gosa_sieve_script_name, $sieve_script );
-                                               # activating new sieve script
-                                               setactive( $sieve, $gosa_sieve_script_name );
-                                       } else {
-                                               print "no gosa script available for user $uid_v, creating new one";
-                                               $sieve_script = $gosa_sieve_header . "\n\n" . $sieve_vacation;
-                                               # uploading new sieve script
-                                               putscript( $sieve, $gosa_sieve_script_name, $sieve_script );
-                                               # activating new sieve script
-                                               setactive( $sieve, $gosa_sieve_script_name );
-                                       }
-                               }
-                               closesieve ( $sieve );
-                       }
-               }
-       } elsif ( $today >= $real_stop ) {
-               print "deactivating vacation for user $uid_v\n";
-
-               my $srv_filter = "(&(goImapName=$server_v)(objectClass=goImapServer))";
-               my $srv_list_of_attributes = [ 'goImapSieveServer', 'goImapSievePort', 'goImapAdmin', 'goImapPassword' ];
-               my $srv_result = ldap_search ( $ldap_url, $srv_filter, $search_scope, $ldap_base, $srv_list_of_attributes, $bind_dn, $bind_dn_pwd );
-               my @srv_entries = $srv_result->entries;
-               my $srv_entry = {};
-               my $noe = @srv_entries;
-               if ( $noe == 0 ) {
-                       printf STDERR "Error: no $server_attribute defined! Aboarting...";
-               } elsif ( $noe > 1 ) {
-                       printf STDERR "Error: multiple $server_attribute defined! Aboarting...";
-               } else {
-                       my $goImapSieveServer = $srv_entries[0]->get_value ( 'goImapSieveServer' );
-                       my $goImapSievePort = $srv_entries[0]->get_value ( 'goImapSievePort' );
-                       my $goImapAdmin = $srv_entries[0]->get_value ( 'goImapAdmin' );
-                       my $goImapPassword = $srv_entries[0]->get_value ( 'goImapPassword' );
-                       if ( ( $goImapSieveServer ) && ( $goImapSievePort ) && ( $goImapAdmin ) && ( $goImapPassword ) ) {
-                               #my $sieve = opensieve ( $goImapAdmin, $goImapPassword, $sieve_user, $goImapSieveServer, $goImapSievePort);
-                               my $sieve = opensieve ( $goImapAdmin, $goImapPassword, $uid_v, $goImapSieveServer, $goImapSievePort);
-                               @sieve_scripts = listscripts ( $sieve );
-                               $script_name = "";
-                               if ( @sieve_scripts ) {
-                                       foreach $script_name ( @sieve_scripts ) {
-                                               if ( $script_name =~ m/$gosa_sieve_script_name/ ) {
-                                                       $gosa_sieve_script_status = "TRUE";
-                                               }
-                                       }
-                                       if ( $gosa_sieve_script_status eq "TRUE" ) {
-                                               # removing vacation part
-                                               $sieve_script = getscript( $sieve, $gosa_sieve_script_name );
-                                               if ( $sieve_script ) {
-                                                       #print "OLD SIEVE SCRIPT:\n$sieve_script\n\n";
-                                                       $sieve_script =~ s/$vacation_header_template[^#]*$vacation_footer_template//;
-                                                       #print "NEW SIEVE SCRIPT:\n$sieve_script\n\n";
-                                                       # uploading new sieve script
-                                                       putscript( $sieve, $gosa_sieve_script_name, $sieve_script );
-                                                       # activating new sieve script
-                                                       setactive( $sieve, $gosa_sieve_script_name );
-                                               }
-                                       }
-                               }
-                               closesieve ( $sieve );
-                       }
-               }
-       } else {
-               print "no vacation process necessary for user $uid_v\n";
-       }
-}
diff --git a/contrib/shells b/contrib/shells
deleted file mode 100644 (file)
index e8805ec..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-/bin/ash
-/bin/bash
-/bin/csh
-/bin/sh
-/bin/ksh
-/bin/tcsh
diff --git a/contrib/socket_server/client.php b/contrib/socket_server/client.php
deleted file mode 100755 (executable)
index a8ec842..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/php5 -q
-<?php
-
-require_once("../../include/class_socketClient.inc");
-error_reporting(E_ALL);
-
-$sock = new Socket_Client("10.89.1.155","9999",TRUE,1);
-#$sock = new Socket_Client("169.254.2.248","9999",TRUE,1);
-$sock->setEncryptionKey("ferdinand_frost");
-
-if($sock->connected()){
-       /* Prepare a hunge bunch of data to be send */
-       $data = "<xml><header>ping</header><source>192.168.1.36:10001</source><target>192.168.1.36:10000</target></xml>";
-       $sock->write($data);
-  
-  #$sock->setEncryptionKey("ferdinand_frost");
-
-       $answer = $sock->read();        
-  echo "$answer\n";
-       $sock->close(); 
-}else{
-       echo "... FAILED!\n";
-}
-
-?>
diff --git a/contrib/socket_server/server.php b/contrib/socket_server/server.php
deleted file mode 100755 (executable)
index 8bf4265..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/usr/bin/php5 -q
-<?php
-
-error_reporting(E_ALL);
-
-//IP to bind to, use 0 for all 
-$bind_ip = 0;
-
-// Port to bind  
-$bind_port = 10000;
-
-// Max clients 
-$max_clients = 3;
-
-// Rijndal encrypt key 
-$enable_encryption = TRUE;
-$encrypt_key = "ferdinand_frostferdinand_frostfe";
-
-/* Create Socket - 
- *  AF_INET means IPv4 Socket 
- *  SOCK_STREAM means Fullduplex TCP
- *  SOL_TCP - Protocol type TCP
- */
-$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
-
-/* Enable reuse of local address */
-socket_set_option($socket,SOL_SOCKET,SO_REUSEADDR,1);
-
-/* Bind to socket */
-socket_bind($socket,$bind_ip,$bind_port);
-socket_listen($socket,$max_clients);
-
-$clients = array('0' => array('socket' => $socket));
-
-echo "\nServer startet on port : $bind_port\n";
-
-
-/* Open the cipher */
-$td = mcrypt_module_open('rijndael-128', '', 'cbc', '');
-
-/* Create the IV and determine the keysize length */
-$iv = substr(md5('GONICUS GmbH'),0, mcrypt_enc_get_iv_size($td));
-$ks = mcrypt_enc_get_key_size($td);
-echo "IV-Size: ".mcrypt_enc_get_iv_size($td)."\n";
-
-/* Create key */
-$key = substr(md5('ferdinand_frost'), 0, $ks);
-echo "Key: $key\n";
-
-/* Intialize encryption */
-mcrypt_generic_init($td, $key, $iv);
-
-/* Accept connections till server is killed */
-while(TRUE) {
-
-       /* Create an array of sockets to read from */
-       $read[0] = $socket;
-       for($i=1;$i<count($clients)+1;$i++) {
-               if(isset($clients[$i] ) && $clients[$i] != NULL) {
-                       $read[$i+1] = $clients[$i]['socket'];
-               }
-       }
-
-       $ready = socket_select($read,$write=NULL,$except=NULL,0);
-
-       /* Handle incoming connections / Incoming data */
-       if(in_array($socket,$read)) {
-
-               /* Check each client slot for a new connection */
-               for($i=1;$i<$max_clients+1;$i++) {
-               
-                       /* Accept new connections */
-                       if(!isset($clients[$i])) {
-                               $clients[$i]['socket'] = socket_accept($socket);
-                               socket_getpeername($clients[$i]['socket'],$ip);
-                               $clients[$i]['ipaddy'] = $ip;
-
-                               echo("New client connected: " . $clients[$i]['ipaddy'] . " \n");
-                               break;
-                       }
-                       elseif($i == $max_clients - 1) {
-                               echo("To many Clients connected! \n");
-                       }
-                       if($ready < 1) {
-                               continue;
-                       }
-               }
-       }
-
-       /* Check if there is data to read from the client sockets */
-       for($i=1;$i<$max_clients+1;$i++) {
-
-               /* Check if socket has send data to the server */
-               if(isset($clients[$i]) && in_array($clients[$i]['socket'],$read)) {
-
-                       /* Read socket data */
-                       $data = @socket_read($clients[$i]['socket'],1024000, PHP_NORMAL_READ);
-
-                       /* Client disconnected */
-                       if ($data === FALSE) {
-                               unset($clients[$i]);
-                               echo "Client disconnected!\n";
-                               continue;
-                       }
-
-                       $data = mdecrypt_generic($td, trim($data));
-                       echo "Client (".$clients[$i]['ipaddy'].") sent: ".$data."... \n";
-
-                       echo "Sending reply... \n";
-                       socket_write($clients[$i]['socket'],mcrypt_generic($td, $data));
-
-                       @socket_close($clients[$i]);
-               }
-       }
-}
-
-?> 
diff --git a/contrib/vacation_example.txt b/contrib/vacation_example.txt
deleted file mode 100644 (file)
index 58cad15..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-DESC: Funny message
-I am currently out at a job interview and will reply to you if I fail
-to get the position. Be prepared for my mood. In urgent cases you can
-reach me on the cell phone via %mobile or write a snail mail to:
-
-%homePostalAddress
-
-Greetings,
-%givenName %sn
diff --git a/gosa-core/AUTHORS b/gosa-core/AUTHORS
new file mode 100644 (file)
index 0000000..8a46db4
--- /dev/null
@@ -0,0 +1,76 @@
+GOsa AUTHORS
+============
+
+This is the alphabetical list of all people that have
+contributed to the GOsa project, beeing code, translations,
+documentation and additional help.
+
+* Markus Amersdorfer <der.plusch@subnet.at>
+  Wiki setup, Testing, hints, proposals
+
+* Alessandro Amici <a.amici@bopen.it>
+  Italian translation
+
+* Holger Burbach <burbach@gonicus.de>
+  Kerberos PHP module
+
+* Craig Chang <craig0310@gmail.com>
+  Fixes for magic_quotes_qpc
+
+* Guillaume Delecourt <guillaume.delecourt@opensides.be>
+  Setup fixes, nagios tab plugin, xls addons ldapmanager
+  pptp connectivity option, phpscheduleit connectivity option
+
+* Dan Ellis <danellis@rushmore.com>
+  Sieve lib is taken from him
+
+* Alejandro Escanero Blanco <aescanero@chaosdimension.org>
+  Fixes, improvements, translation, Guide and some extensions
+
+* Fabian Hickert <hickert@gonicus.de>
+  Improvements for setup, various fixes and plugins
+
+* Eric Kilfoil <eric@ipass.net>
+  ldap.inc is taken from him
+
+* Niels Klomp <nk@careworks.nl>
+  Dutch translation
+  
+* Benoit Mortier <benoit.mortier@opensides.be>
+  French translation
+
+* Igor Muratov <migor@altlinux.org>
+  Various fixes and speed enhancements
+
+* Michael Pasdziernik <mp@secio.de>
+  Documentation for GOsa and safe-mode, fixes
+
+* Cajus Pollmeier <pollmeier@gonicus.de>
+  Virtually everyting which is GOsa related
+
+* Piotr Rybicki <meritus@innervision.pl>
+  Polish translation
+
+* Henning Schmiedehausen <hps@intermeta.de>
+  Various fixes, support for user defined people/group base
+
+* Alfred Schröder <schroeder@gonicus.de>
+  German translation
+
+* Thomas Schüßler <tulpe@atomar.de>
+  debuglib.inc is taken from him
+
+* Jan Wenzel <jan.wenzel@gonicus.de>
+  Implementation and research for samba munged dial support,
+  fixing of "Fiptehlers"(TM) in the german translations.
+
+* Leila El Hitori <leila.elhitori@opensides.be>
+  French online documentation
+  English online documentation
+  
+* Vincent Seynhaeve
+  Xls export plugin <vincent.seynhaeve@opensides.be>
+  
+* Wouter Verhelst <wouter@debian.org>
+  accept-to-gettext code that helps for language conversation
+
diff --git a/gosa-core/Changelog b/gosa-core/Changelog
new file mode 100644 (file)
index 0000000..cba0fc9
--- /dev/null
@@ -0,0 +1,526 @@
+GOsa2 changelog
+===============
+
+* gosa 2.6beta1
+
+* gosa 2.5.13
+  - Re-added ISC DHCP support
+  - Fixes for the mail based bugtracker
+  - Fixed autouid problem with slashes
+  - Added list sorting for FAI script lists
+  - Added copy'n paste for mimetypes
+  - Cut'n paste objects are now greyed out
+  - Added swedish locale
+  - Improved language detection
+  - Added a statistic footer to lists
+  - Added the ssh plugin
+  - Layout fixes
+
+* gosa 2.5.12
+  - Fixed problems with automatic reverse zones
+  - Fixed several IE6 related Java-Script problems
+  - Removed png.js by default. Looks ugly, but performs. Take
+    a look at the FAQ on how to re-enable it for IE.
+  - Added non-login password change dialog
+  - Various spelling fixes
+  - Added some extra robustness to the PPD reader code
+  - FAI partition ordering fixed, partition sizes fixed
+  - FAI release management updates
+  - Fixed installations that fail the schema check
+  - Updated error messages to fade out the interface
+  - Repository cleanup
+  - Added feedback link to easily report PHP errors
+  - Added more content sorting where needed
+  - Made gidNumber be the current in posix check hook
+  - Removed inconsistency in gosa/gosa+samba3 schema
+  - Fixed multiple saving of "My account" data
+  - Don't allow moving of objects from administrative units to other
+    administrative units where ACL's permit it. Objects "seemed" to
+    disapear because the tagging changes.
+  - Added gosa-desktop package to be able to start it by link
+  - Added method to highlight tabs
+  - Generel translation update for de, es, fr, it, nl, pl, ru, zh
+
+* gosa 2.5.11a
+  - Added chinese translation
+  - Fixed language detection and removed line wraps in tab headers
+  - Fixed french translation
+
+* gosa 2.5.11
+  - Add workaround for failing is_php4() when using PHP5
+    with "zend.ze1_compatibility_mode" set to "On"
+  - Backported new sieve filter editor from trunk
+  - Backported new setup from trunk
+  - Fixed double loaded pages in gecko based browsers when js
+    is activated
+  - Replaced a set of PHP <? short tag occurences
+  - Updated locales (de/fr)
+
+* gosa 2.5.10
+  - Included hook to make use of dynamic uid-bases
+  - Included vacation date range specification
+  - Fixed non-saved Samba-Domain changes in groups
+  - Freezed application parameters are not editable anymore
+  - Fixed problem with removing commata based DN's
+  - Corrected setup generated perl mkntpasswd string
+  - Fixed month listing in fax reports - february was march
+  - Enabled 9 digits for gid-/uidNumbers
+  - Fixed acl's for saving printers
+  - Fixed saving of disabled samba acl's
+  - Added support for rfc2307bis compliant groups
+
+* gosa 2.5.9
+  - Fixed ldap tls connections when schema check was being used
+  - Updated italian translation
+  - Added the possiblility to choose a RDN style for DN's when
+    a CN is already in use
+  - Fixed a problem with cut'n paste for groups and ogroups
+  - Added new mail method "golab" which has some tweaks against
+    the standard kolab mode
+  - Fixed object tagging for workstation/printer assignement
+  - Fixed undefined index in FAI package lists
+  - Fixed copy'n paste for groups and object groups
+  - Enabled non ASCII characters in vacation messages
+  - Fixed "none" permissions in IMAP shared folders to be assignable
+
+* gosa 2.5.8
+  - Fixed problem with winstations shown in user list. 
+  - Allow basic regex ().*^$ in fax blocklist numbers.
+  - Fixed date of birth and shadow expire in template adaption
+  - Updated user mail account to search for CYRUSUNIXSTYLE in all
+    relevant sections of the config file
+  - Added support for sambaLogonHours 
+  - Security fix, that allows non priviledged users to change
+    several settings - including admin passwords
+
+* gosa 2.5.7
+  - Fixed login.tpl to display error msgs in the middle of the screen
+  - Fixed some error outputs in login.php to not break the screen
+  - Added auto scroll function to FAI-Create-Branch and Department tagging
+  - Fixed problems with workstations when fai.schema was not included
+  - Made gid-/uidNumbers 32 bit aware
+  - Replaced hardcoded config path /etc/gosa with CONFIG_DIR constant
+  - Included personal title in DN
+  - Added function to remove PPD's from disc
+  - Removed old cups dependencies
+  - Fixed saving of terminals printer service attribute
+  - Fixed a ACL naming bug, that avoids that an admin with non "all" ACLs
+    can edit specified objects.
+  - Fixed simultaneous move + rename for deparments
+  - Internally updated to smarty 2.6.16
+  - Removed asterisk status view in user display. This was too slow in
+    bigger installations.
+  - Re-enabled phone queues. They got optimized for invisibility.
+
+* gosa 2.5.6
+  - Copy & paste implemented into FAI
+  - Added setup fix to support GraphicsMagick
+  - Added several fixes for all user plugins to support Copy & Paste.
+  - Fixed malformed usage of $this>var in samba class. 
+  - Fixed checkbox selection in samba class.
+  - Connectivity netatalk: Moved plugin intialization from execute() to contructor().
+  - Fixes various issues with setup.php
+  - Avoid tab lables to have line feeds
+  - Activated missing checks for IP and MAC
+  - Fixed copy'n paste errors for netatalk
+  - Various W3C fixes
+  - Fixed "My Account" mode, where buttons disappear after saving
+  - Avoid removal of shares while they are used by users
+  - Added finer grained ACL settings for mail accounts
+  - Fixed day of birth problem in M$ IE
+  - Fixed setting of Kerberos passwords
+
+* gosa 2.5.5
+  - Added remove method for shared folder in kolab mode
+  - Added checkbox to decide if the shared folder should be deleted from IMAP
+    if the mail extension is removed from group mail account
+  - Updated request method for mail folders
+  - Resolved problem with infinite loop while storing sieve scripts
+  - Added subsearch checkbox to object group "add items" filter
+  - Fixed "missing PPD" configuration error, for newly created printer
+  - Corrected problem where the object base was sometimes broken when
+    saving object groups
+  - Fixed saving of terminal attribute gotoLpdEnable to contain "yes"
+    instead of "1"
+  - Avoid reset of several attributes from workstations when not
+    inherited from object groups
+  - Show error messages from password dialog
+  - Fixed a set of W3C problems
+  - Fixed multiple savings in addressbook (Closes: #23)
+  - Fixed shadow expire when using templates (Closes: #20)
+  - Made %uid, %sn, etc. available in templates using gosaMailAlternateAddress
+
+* gosa 2.5.4
+  - Included patch to choose the addressbook base
+  - Applied fixes for logviewer done by Mario Minati
+  - Updated locales, fixed a set of missing strings
+  - Fixed problems in FAI list handling
+  - Added "uid" to personal plugins for replacement in post events
+  - Fixed saving of user logon scripts
+  - Fixed non-FAI application mode
+  - More speed fixes applied, especially for users, objectgroups and
+    generic plugin loading
+  - Bug while saving FAI partitions fixed
+  - Don't save PPD if none is not selected bug fixed
+  - Saving of non revisioned applications fixed
+
+* gosa 2.5.3
+  - Fixed problem in reloading departments when we've PHP4
+  - Fixed gotoPrinter membership problem.
+  - Fixed environment shares, only available shares will be displayed (gosaUnitTag was ignored)
+  - Fixed saving of inherited workstation settings
+  - Removed error when no FAI repositories were present
+  - Fixed posix group add dialog, filter wasn't working.
+  - Fixed get_printer_list undefined index warnings while editing a user.
+  - Fixed ogroup non-static method error
+  - Fixed user membership for gotoPrinter, if membership was edited 
+    via user environemnt, some numeric values were stored too
+  - Fixed mail account, mail server string possibly was an array
+  - Fixed typos
+  - Fixed upper/lowcase ou's for groups/people when using an
+    unclean LDAP database
+  - Fixed ACL handling to *not* show the admin user dialog
+    when configured for self modify only
+  - Fixed problem when changing passwords via "My account"
+  - Added more information to hotplug devices.
+
+* gosa 2.5.2
+  - Fixed current main base not beeing set when editing non tabbed
+    plugins
+  - Fixed filtering for divlists
+  - Fixed deletion of shares in environment tabs
+  - Updated french online help
+  - Updated german online help
+  - Fixed display of FAI partitions
+  - Removed Quota warnings for existing accounts without quota limits
+  - Worked around PHP4 session problems when creating new departments
+  - Fixed problems when moving around departments including a comma
+  - Unified bool values in gosa.conf. true/yes and false/no are valid
+    now in upper and lower case.
+  - Avoid the try of creating already existing ou's
+  - Fixed non working printer removal
+
+* gosa 2.5.1
+  - Fixed problems with NFS shares and terminals
+  - Finalized polish translations
+  - Fixed problem with compressed gosa.conf in the debian package
+
+* gosa 2.5
+  - Improved FAI support
+    * Server and workstations are treated the same way
+    * Destination selector for new devices
+    * Summary tab introduced
+  - Improved robustness while operating whith the LDAP
+  - Several Kolab related fixes
+  - Tagging of departments introduced
+  - Global check hooks allow user defined testing
+    of single plugins
+  - Major speedups with large databases
+  - Added english and french online help
+  - Unified plugin "head" selectors, (re-)added subtree
+    support
+  - Fixed PPD parsing for several commercial PPD's
+  - Tune LDAP error messages
+  - Moved from "guru mediation style" to div-popups
+  - Several css fixes
+  - Fixed series of bugs that lead to not shown groups
+
+* gosa 2.4
+  - Updated layout to work cleanly with IE6+, Firefox 1.0.4+, khtml 3.4+
+  - Added FAI (Fully Automatted Installation) support
+  - Added mail queue management
+  - Added many missing acl informations
+  - Added help browser and initial french help
+  - Fixed templating for samba and unix users
+  - Applied hundreds of smaller bugfixes
+  - Improved speed by switching to directory style dialogs and performing
+    sub searches.
+  - Per user language selector in generic tab
+  - New connectivity plugins (PHPscheduleit/PPTP/glpi)
+
+* gosa 2.4beta3
+  - Updated layout
+  - Fixed application removal
+  - Improved accessibility for disabled persons
+  - Added intranet account to list of connectivity plugins
+  - Several kolab related fixes for server objects
+  - Corrected contributed slapd.conf
+  - Fixed kolab mode where GOsa saves KB quotas, interprets quotas as kolab MB
+  - Increased robustnes for non set fields
+  - Fixed IE issues with W3C compatibilty where IE posts disabled fields
+  - Fixed problems with existing samba accounts and password changed fields
+  - Removed login problems with undefined ldap_conf variable
+  - Fixed problems where the GECOS field is not written correctly
+
+* gosa 2.4beta2
+  - Fixed error handler to be PHP 4.x compatible
+  - Fixed PHP compatibility problem in setup.php, using ini_get()
+    instead of ini_get_all()
+  - Fixed cases where ipHostAddress is required but not checked
+    by GOsa
+  - Fixed group dialog filters
+  - Fixed problems in setup which showed up with white pages if
+    PHP has been compiled without mbstring support
+  - Fixed layout if the rendered page does not cover 100% of the
+    browser window
+  - Improved phone plugin to respect IAX, CAPI and SIP phone
+    attributes
+    automatically if the revision changes
+  - Improved W3C compatibility
+  - Added checks that remove the contents of /var/spool/gosa/*
+  - Added postmodify for password change operations
+
+* gosa 2.4beta1
+  - Override automatically detected user bases if they don't exist
+  - Don't shred samba group ID's if they are not present in the
+    combobox
+  - Updated smarty to version 2.6.9
+  - Updated GOfon support to handle new features
+  - Replacement of most external programm calls
+  - Samba3 bugfixes for munged dial handling
+  - Updated LDIF export
+  - Improved setup checks to find more possible errors
+  - Fixed index ruler for long lists
+  - Completed system creation for servers, phones and misc components
+  - Added support for kolab users and kolab server settings
+  - Added server settings
+  - Added LDIF import
+  - Added CSV import
+  - Added italian translation (thanks to Alessandro Amici)
+  - Added subtree search checkbox in lists with potential higher
+    usage
+  - Added version indicator to make support more easy
+  - Added sample databases for fax, phone and system logging
+  - Added error handler for normal PHP errors
+
+* gosa 2.3
+  - Updated smarty to version 2.6.7
+  - Added dutch translations (thanks to Niels Klomp)
+  - Added webdav and phpgroupware accounts
+  - Fixed french translation
+  - Fixed error in shadowExpire attribute
+  - Unified all filters in dialogs to use the internationalized choosers
+  - Added option to do non subtree searches with filters
+  - Fixed sample configuration files to be unproblematic when used in
+    conjunction with OpenLDAP 2.2
+  - Added experimental support for editing LDAP trees that contain referrals
+  - Updated Altlinux contributions, including themes and scripts
+  - Worked around a possible problem with sizelimit in php-ldap
+  - Improved big ldap support by size limits and non sub searches
+  - Various smaller fixes
+  - Added global TLS switch for LDAP connections
+  - Fixed SELECT queries to be mysql 3.x _and_ 4.x compatible
+  - Made departments movable
+
+* gosa 2.2
+  - Removed DHCP/DNS plugins, they will be replaced by
+    the terminal/server/workstation plugins.
+  - Added case sensitivity check for login names
+  - Made bases set to users "home" department when creating new objects
+  - Moved sieve-*.txt config files to /etc/gosa
+  - Told IMAP plugin to remove mail accounts when the user is deleted
+  - Interface cleanups
+  - Added simple log file viewer
+  - Added support for asterisk
+  - Included javascript magic to improve usability (doubleclicks in
+    lists, disabling of fields, warning messages, etc.)
+  - More filtering and sizelimits for speed optimizations
+  - Mail handling is now pluggable
+  - Added possibility to bundle objects to object groups
+  - Added a reference tab to track relation ships of different objects
+  - Improved samba 3 support (terminal server support)
+  - Updated translations and added a french one
+
+* gosa 2.1.3
+  - Fixed problem with initial password setting
+  - Increase number in version.inc
+  - Add a workaround to fix problem with groups not beeing displayed
+    with openldap. Here the server reacts with empty results if searching
+    for non existing objectClass "sambaGroupMapping" in case of using samba2
+  - Fix the homeDirectory check which is a bit too harsh with templates
+
+* gosa 2.1.2
+  - Fixed problem with uppercase login names
+  - Extensive speed increasements in ldap searches
+  - Fixed gettext problem on older installations
+  - Corrected sieve login which was broken due to a library switch
+  - Made in_array act case insensitive for is_account check
+  - Fixed location of DMODE and HASH in config file
+  - Fixed general problems with password hash generation if not
+    specified
+  - Complete move to unicode which removes all active encoding/decoding
+    of contents from GOsa itself
+  - Made GOsa run smooth on PHP 5
+  - Added complete russian translation contributed by Igor Muratov
+  - Migrated phone list to (global) addressbook
+  - Filtering fixes
+
+* gosa 2.1.1
+  - Enabled mail-account-less fax accounts
+  - Fixed upper/lower case problem in mail templates
+  - Fixed typo in generic plugin error message
+  - Made template dialog work again
+  - Fixed headpage for application management which tends to do no
+    proper display of used applications
+  - Added command line interface to use GOsa without web interface
+  - Updated debian control to be aware of apache2 based installations
+  - Transferd tab variables in group dialog, so the primary mail 
+    address can be checked
+  - Fixed possible case problem with is_account
+  - Made base selector contain newly added departments in department
+    dialog
+  
+* gosa 2.1
+  Bugfix release
+  - size of homeDirectory attribute increased
+  - FAQ/README/INSTALL updated
+  - spec file updated
+
+* gosa 2.1rc2
+  Bugfix release
+  - Made user dn configurable
+  - Fixed memory usage check
+  - Fixed size of alternate mail address field
+  - Fixed sorting of group in posix tab
+  - Made GOsa keep group membership even if user has no posix
+    account
+  - Fixed typo in blocklist spelling
+  - Fixed error message when trying to filter users without a
+    valid uid
+  - Made posix account visible, even if there are no shadow
+    attributes inside this entry
+  - Included setup
+  - Translation updates
+
+* gosa 2.1rc1
+  Bugfix release
+  - Fixed annoying ACL bug in template mode
+  - Fixed possible privilege escalation problem in password
+    routine (thanks to Henning Schmiedehausen)
+  - Removed password storage from user info class (thanks to
+    Rainer Herbst)
+  - Various interface cleanups
+  - Templatization finished
+  - Reworked user headpage
+  - Made GOsa more robust in detecting errors in config
+  - Added additional error messages reported by LDAP server
+  - Added schmemacheck hook
+  - Started with setup implementation
+
+* gosa 2.1beta3
+  Bugfix release
+  - Made template mode remember the templates primary group
+  - Templatized posix plugin
+  - Added option to disable strict checking of uid/gid names
+  - Massive samba3 updates
+  - Made ou=people and ou=groups configurable
+  - Fixed user/group lists to react on filter changes
+
+* gosa 2.1beta2
+  Bugfix and feature enhancement release.
+  - Made GOsa remove object locks when changing plugins during edit
+    process.
+  - Added DHCP plugin
+  - Gerneral speed tunig, reduced the number of unessasary ldap
+    accesses
+  - Added syslog output for actions "save" and "remove"
+  - Fixed handling for multiple ACL's per base
+  - Fixed listboxes to unify output / sort output
+  - Fixed annoying bug in tab_groups.inc when removing the mailtab
+  - Bases did not get set in template mode
+  - Fixed user part
+  - Templatized faxaccount/pureftpd/samba and mail plugins
+  - Included calendar.js functionality in samba plugin
+
+* gosa 2.1beta1
+  This release has some feature enhancements and contains many
+  bugfixes and design cleanups
+  - Fixed many HTML related things. Pages are now perfectly validated
+    as html 4.01 transitional.
+  - Added dn cleaner to getDN() in order to fix problems with
+    "broken" ldap databases.
+  - Added schemata for iplanet, checked if it works.
+  - Rewrote phonelist, added vcard export.
+  - Added filters to allmost all plugins.
+  - Added DNS plugin.
+  - Generic userinterface cleanups, everything is a template now and can be
+    redesigned/stripped.
+  - Improved translations, added missing ones.
+  - Added choosable templates for mail vacation messages.
+  - Improved templating stuff to generate user defined auto uids.
+  - Made user interface more comprehensive, so its important for you
+    to start with a clean gosa.conf from contrib.
+  - Added external password change hook, so that its possible to synchronize
+    with a non samba PDC via scripts. (Some organizations tend to keep a
+    readable copy of their users password which possible now, too.)
+  - Updated FAQ
+
+* gosa 2.0.1
+  This release doesn't have feature enhancements (nearly), only
+  bugfixes reported by users are incorporated.
+  - Fixed oblivious fields when changing to subdialogs. All
+    user dialogs were affected
+  - Made facsimileTelephoneNumber beeing saved without the
+    need of a fax account
+  - Fixed printer sorting which destroyed the array index
+  - Removed redundant fields in terminal configuration
+  - Made terminal plugin save the terminal hardware information
+  - Added missing </html> tags to index.php/main.php
+  - Fixed debian debconf script not to touch uidbase/ridbase
+    values in gosa.conf
+  - Fixed "Force ID", which creates a group for the posix
+    user with forced ID.
+  - Finetuning in login window behaviour
+  - Code cleanup and templatized two more plugins
+  - As requested by some users, you can now advise GOsa not to
+    create a group for the user, but take an existing group
+    as primary one.
+  - Added 'dn cleaner' for the acl list. So syntactically
+    problematic dn's with strange commata get fixed.
+
+* gosa 2.0 final
+  - Made samba3 support work
+  - Fixed several small bugs with the templating stuff
+  - Fixed problem with shared folders, added missing attribute
+    gosaSharedFolderTarget needed in some setups
+  - Updated icons
+  - Renamed icons to have more logical names
+
+* gosa 2.0rc2
+  - Corrected mistakenly copied ui object in functions.inc
+  - Fixed errors when activating new terminals
+  - Removed krb warnings in class_user.inc
+  - Plugins user, apps, groups and departments didn't check for
+    already present entries. Now they do.
+  - Removed problem in terminal dialog where checkboxes are not
+    saved
+  - Fixed ACL handling for users primary group
+  - Replaced own template class by smarty, since only two files
+    were affected by this
+  - Changed basic layout to seperate public readable files from
+    templates
+  - Added FAQ, update TODO for next versions
+  - Made accounts movable between departments
+  - Added partial spanish translations
+  - Fixed mail group handling
+
+* gosa 2.0rc1
+  - Switched to XML based gosa.conf
+  - Cleaned all plugins, moved to children of plugin.conf
+  - Moved back to gettext for translations
+  - Added hooks for pre-/post-install scripts
+  - Cleaned LDAP class
+  - Added workarounds for MS-IE (>5.5) to render transparent
+    PNGs in a correct way
+  - Redesigned login screen / some plugins
+  - Added hooks for eGOsa, which is a java applet based
+    browsing tool
+  - Switched from user based ACLs to group based ACLs,
+    removed standalone ACL plugin in favor of new group tab.
+  - Fixed samba2 rid generation (btw. still missing is sid
+    support for samba3. But this will go into the final.)
+  - Fixed many minor bugs
+  - Introduced simple theming support
+  - Added 'dn'-renaming for accounts
+
+Changelog starts with latest Beta 1.99.97
diff --git a/gosa-core/bin/mkntpasswd b/gosa-core/bin/mkntpasswd
new file mode 100755 (executable)
index 0000000..1749958
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+if [ $# -ne 1 ]; then
+       echo "Usage: mkntpwd <password>"
+       exit 1
+fi
+
+# Render hash using perl
+perl -MCrypt::SmbHash -e "print join(q[:], ntlmgen $ARGV[0]), $/;"
+
+exit 0
diff --git a/gosa-core/contrib/altlinux/etc/cyrus.conf b/gosa-core/contrib/altlinux/etc/cyrus.conf
new file mode 100644 (file)
index 0000000..4ada843
--- /dev/null
@@ -0,0 +1,43 @@
+# standard standalone server implementation
+
+START {
+       # do not delete this entry!
+       recover cmd="ctl_cyrusdb -r"
+
+       # this is only necessary if using idled for IMAP IDLE
+#      idled           cmd="idled"
+}
+
+# UNIX sockets start with a slash and are put into /var/lib/imap/socket
+SERVICES {
+       # add or remove based on preferences
+       imap            cmd="imapd" listen="imap" prefork=5
+#      imaps           cmd="imapd -s" listen="imaps" prefork=1
+       pop3            cmd="pop3d" listen="pop3" prefork=3
+#      pop3s           cmd="pop3d -s" listen="pop3s" prefork=1
+       sieve           cmd="timsieved" listen="sieve" prefork=0
+#      smmapd          cmd="smmapd" listen="/var/lib/imap/socket/smmapd" prefork=1
+
+       # these are only necessary if receiving/exporting usenet via NNTP
+#      nntp            cmd="nntpd" listen="nntp" prefork=3
+#      nntps           cmd="nntpd -s" listen="nntps" prefork=1
+
+       # at least one LMTP is required for delivery
+#      lmtp            cmd="lmtpd" listen="lmtp" prefork=0
+       lmtpunix        cmd="lmtpd" listen="/var/spool/postfix/public/lmtp" prefork=1
+
+       # this is only necessary if using notifications
+#      notify  cmd="notifyd" listen="/var/lib/imap/socket/notify" proto="udp" prefork=1
+}
+
+EVENTS {
+       # this is required
+       checkpoint      cmd="ctl_cyrusdb -c" period=30
+
+       # this is only necessary if using duplicate delivery suppression,
+       # Sieve or NNTP
+       delprune        cmd="cyr_expire -E 3" at=0400
+
+       # this is only necessary if caching TLS sessions
+       tlsprune        cmd="tls_prune" at=0400
+}
diff --git a/gosa-core/contrib/altlinux/etc/gosa/gosa.conf b/gosa-core/contrib/altlinux/etc/gosa/gosa.conf
new file mode 100644 (file)
index 0000000..d1ceab3
--- /dev/null
@@ -0,0 +1,170 @@
+<?xml version="1.0"?>
+<conf>
+       <menu>
+               <section name="My account">
+                       <plugin acl="default" class="user" icon="personal.png"
+                               path="plugins/personal/generic" />
+                       <plugin acl="default" class="posixAccount" icon="posix.png"
+                               path="plugins/personal/posix" />
+                       <plugin acl="default" class="mailAccount" icon="email.png"
+                               path="plugins/personal/mail" />
+                       <plugin acl="default" class="sambaAccount" icon="samba.png"
+                               path="plugins/personal/samba" />
+                       <plugin acl="default" class="proxyAccount" icon="proxy.png"
+                               path="plugins/personal/proxy" />
+                       <plugin acl="default" class="pureftpdAccount" icon="ftp.png"
+                               path="plugins/personal/pureftpd" />
+                       <plugin acl="default" class="gofaxAccount" icon="fax.png"
+                               path="plugins/gofax/faxaccount" />
+               <!--
+                       <plugin acl="default" class="phoneAccount" icon="phone.png"
+                               path="plugins/gofon/phoneaccount" />
+               -->
+                       <plugin acl="default" class="password" icon="password.png"
+                               path="plugins/personal/password" />
+               </section>
+               
+               <section name="Administration">
+                       <plugin acl="user" class="userManagement" icon="user.png"
+                               path="plugins/admin/users" />
+                       <plugin acl="group" class="groupManagement" icon="group.png"
+                               path="plugins/admin/groups" />
+                       <plugin acl="ogroup" class="ogroupManagement" icon="ogroup.png"
+                               path="plugins/admin/ogroups" />
+                       <plugin acl="department" class="departmentManagement" icon="department.png"
+                               path="plugins/admin/departments" />
+                       <plugin acl="application" class="applicationManagement"
+                               icon="application.png" path="plugins/admin/applications" />
+                       <plugin acl="blocklists" class="blocklist" icon="blocklists.png"
+                               path="plugins/gofax/blocklists" />
+               <!--
+                       <plugin acl="terminal" class="systems" icon="terminal.png"
+                               path="plugins/admin/terminals" />
+               -->
+               </section>
+
+               <section name="Addons">
+                       <plugin acl="default" class="addressbook" icon="addressbook.png"
+                               path="plugins/addons/addressbook" />
+                       <plugin acl="default" class="faxreport" icon="reports.png"
+                               path="plugins/gofax/reports" />
+               <!--
+                       <plugin acl="default" class="fonreport" icon="phonereports.png"
+                               path="plugins/gofon/reports" />
+               -->
+                       <plugin acl="logs" class="logview" icon="logview.png"
+                                path="plugins/addons/logview" />
+                       <plugin acl="ldif" class="export" icon="ldif.png"
+                               path="plugins/addons/ldifexport" />
+               </section>
+       </menu>
+
+       <usertabs>
+               <tab class="user" name="Generic" />
+               <tab class="posixAccount" name="Unix" />
+               <tab class="mailAccount" name="Mail" />
+               <tab class="sambaAccount" name="Samba" />
+               <tab class="proxyAccount" name="Proxy" />
+               <tab class="pureftpdAccount" name="FTP" />
+               <tab class="gofaxAccount" name="Fax" />
+               <!--
+               <tab class="phoneAccount" name="Phone" />
+               -->
+               <tab class="reference" name="References" />
+       </usertabs>
+
+       <grouptabs>
+               <tab class="group" name="Generic" />
+               <tab class="appgroup" name="Applications" />
+               <tab class="mailgroup" name="Mail" />
+               <tab class="acl" name="ACL" />
+               <tab class="reference" name="References" />
+       </grouptabs>
+
+       <appstabs>
+               <tab class="application" name="Generic" />
+               <tab class="applicationParameters" name="Options" />
+               <tab class="reference" name="References" />
+       </appstabs>
+
+       <termtabs>
+               <tab class="termgeneric" name="Generic" />
+               <tab class="termservice" name="Devices" />
+               <tab class="termstartup" name="Startup" />
+               <tab class="terminfo" name="Monitoring" 
+                       wakecmd="/usr/bin/sudo /usr/sbin/etherwake" />
+               <tab class="reference" name="References" />
+       </termtabs>
+
+       <worktabs>
+               <tab class="workgeneric" name="Generic" />
+               <tab class="termservice" name="Devices" />
+               <tab class="termstartup" name="Startup" />
+               <tab class="terminfo" name="Monitoring" 
+                       wakecmd="/usr/bin/sudo /usr/sbin/etherwake" />
+               <tab class="reference" name="References" />
+       </worktabs>
+
+       <printtabs>
+               <tab class="printgeneric" name="Generic" />
+               <tab class="reference" name="References" />
+       </printtabs>
+
+        <phonetabs>
+                <tab class="phonegeneric" name="Generic" />
+                <tab class="reference" name="References" />
+        </phonetabs>
+
+       <deptabs>
+               <tab class="department" name="Generic" />
+               <tab class="reference" name="References" />
+       </deptabs>
+
+       <ogrouptabs>
+               <tab class="ogroup" name="Generic" />
+               <tab class="reference" name="References" />
+       </ogrouptabs>
+
+       
+       <main default="EXAMPLE.COM"
+               compile="/var/spool/gosa"
+               lang=""
+               theme="default"
+               debuglevel="0"
+               forcessl="false"
+               warnssl="false"
+               iconsize="48x48"
+               pwminlen="6"
+               forceglobals="false"
+               smbhash='mkntpwd'>
+
+               <location name="EXAMPLE.COM"
+                       uidbase="1000"
+                       governmentmode="false"
+                       sambaversion="3"
+                       server="ldap://localhost:389"
+                       admin="cn=gosa,ou=Apps,dc=example,dc=com"
+                       mailMethod="Cyrus"
+                       hash="md5"
+                       password="gosa"
+                       dnmode="uid"
+                       base="dc=example,dc=com"
+                       people="People"
+                       groups="Groups"
+                       config="ou=gosa,ou=configs,ou=systems,dc=example,dc=com" />
+
+               <language name="Russian" tag="ru_RU" />
+               <language name="German" tag="de_DE" />
+               <language name="Spanish" tag="es_ES" />
+               <language name="French" tag="fr_FR" />
+               <language name="English" tag="en_EN" />
+
+               <faxformat type="pdf" />
+               <faxformat type="ps" />
+               <faxformat type="png" />
+               <faxformat type="mtiff" />
+               <faxformat type="tiff" />
+       </main>
+</conf>
+
+
diff --git a/gosa-core/contrib/altlinux/etc/imapd.conf b/gosa-core/contrib/altlinux/etc/imapd.conf
new file mode 100644 (file)
index 0000000..5ae2d9b
--- /dev/null
@@ -0,0 +1,210 @@
+# In more detail to look in man 5 imapd.conf
+
+#@include: <none>
+
+admins: cyrus
+
+#afspts_localrealms: <none>
+#afspts_mycell: <none>
+
+#allowallsubscribe: 0
+#allowanonymouslogin: 0
+allowapop: 0
+#allownewnews: 0
+allowplaintext: 1
+#allowusermoves: 0
+#altnamespace: 0
+sasl_mech_list: plain
+
+annotation_db: skiplist
+
+autocreatequota: 10240
+#createonpost: 0
+#autocreateinboxfolders: <none>
+#autosubscribeinboxfolders: <none>
+#autosubscribesharedfolders: <none>
+
+#berkeley_cachesize: 512
+#berkeley_locks_max: 50000
+#berkeley_txns_max: 100
+
+
+configdirectory: /var/lib/imap
+#debug_command: <none>
+#defaultacl: anyone lrs
+
+#defaultdomain: taf.ru
+#defaultpartition: default
+#deleteright: c
+
+duplicate_db: berkeley-nosync
+duplicatesuppression: 0
+
+#foolstupidclients: 0
+#force_sasl_client_mech: <none>
+#fulldirhash: 0
+
+hashimapspool: 1
+#hostname_mechs: <none>
+#hostname_password: <none>
+
+idlesocket: /var/lib/imap/socket/idle
+#ignorereference: 0
+#imapidlepoll: 60
+imapidresponse: 0
+#imapmagicplus: 0
+#implicit_owner_rights: lca
+
+#ldap_authz: <none>
+#ldap_base: <none>
+#ldap_bind_dn: <none>
+#ldap_deref: never
+#ldap_filter: <none>
+#ldap_group_base: <empty string>
+#ldap_group_filter: (cn=%u)
+#ldap_group_scope: sub
+#ldap_id: <none>
+#ldap_mech: <none>
+#ldap_member_attribute: <none>
+#ldap_member_base: <empty string>
+#ldap_member_filter: (member=%D)
+#ldap_member_method: attribute
+#ldap_member_scope: sub
+#ldap_password: <none>
+#ldap_realm: <none>
+#ldap_referrals: 0
+#ldap_restart: 1
+#ldap_sasl: 1
+#ldap_sasl_authc: <none>
+#ldap_sasl_authz: <none>
+#ldap_sasl_mech: <none>
+#ldap_sasl_password: <none>
+#ldap_sasl_realm: <none>
+#ldap_scope: sub
+#ldap_servers: ldap://localhost/
+#ldap_size_limit: 1
+#ldap_start_tls: 0
+#ldap_time_limit: 5
+#ldap_timeout: 5
+#ldap_tls_cacert_dir: <none>
+#ldap_tls_cacert_file: <none>
+#ldap_tls_cert: <none>
+#ldap_tls_check_peer: 0
+#ldap_tls_ciphers: <none>
+#ldap_tls_key: <none>
+#ldap_uri: <none>
+#ldap_version: 3
+
+
+
+lmtp_downcase_rcpt: 1
+lmtp_over_quota_perm_failure: yes 
+#lmtpsocket: {configdirectory}/socket/lmtp
+lmtpsocket: /var/spool/postfix/public/lmtp
+
+#loginrealms: <empty string>
+#loginuseacl: 0
+#logtimestamps: 0
+
+#mailnotifier: <none>
+#maxmessagesize: 0
+
+mboxlist_db: skiplist
+
+#mupdate_connections_max: 128
+#mupdate_authname: <none>
+#mupdate_password: <none>
+#mupdate_port: 3905
+#mupdate_realm: <none>
+#mupdate_retry_delay: 20
+#mupdate_server: <none>
+#mupdate_workers_start: 5
+#mupdate_workers_minspare: 2
+#mupdate_workers_maxspare: 10
+#mupdate_workers_max: 50
+#mupdate_username: <empty string>
+
+#netscapeurl: http://asg.web.cmu.edu/cyrus/imapd/netscape-admin.html
+
+#newsmaster: news
+#newspeer: <none>
+#newspostuser: <none>
+#newsprefix: <none>
+#notifysocket: {configdirectory}/socket/notify
+
+partition-default: /var/spool/imap
+#partition-name: <none>
+#plaintextloginpause: 0
+
+#popexpiretime: -1
+#popminpoll: 0
+poptimeout: 5
+#postmaster: postmaster
+#postuser: <empty string>
+#proxy_authname: proxy
+#proxy_password: <none>
+#proxy_realm: <none>
+#proxyd_allow_status_referral: 0
+#proxyservers: <none>
+
+#ptloader_sock: <none>
+
+#ptscache_db: berkeley
+#ptscache_timeout: 10800
+#ptskrb5_convert524: 1
+
+#quota_db: quotalegacy
+#quotawarn: 90
+#quotawarnkb: 0
+
+# If you want to have 8-bit symbols in 'Subject' the
+# reject8bit should matter 0
+reject8bit: 0
+
+#rfc2046_strict: 0
+#rfc3028_strict: 1
+
+#sasl_auto_transition: 0
+#sasl_maximum_layer: 256
+#sasl_minimum_layer: 0
+#sasl_option: 0
+sasl_pwcheck_method: saslauthd
+
+seenstate_db: skiplist
+
+sendmail: /usr/sbin/sendmail
+servername: example.com
+
+#sharedprefix: Shared Folders
+#sieve_maxscriptsize: 32
+#sieve_maxscripts: 5
+sievedir: /var/lib/imap/sieve
+#sievenotifier: <none>
+#sieveusehomedir: 0
+
+#singleinstancestore: 1
+#skiplist_unsafe: 0
+#soft_noauth: 1
+#srvtab: <empty string>
+
+subscription_db: flat
+
+#syslog_prefix: <none>
+
+#temp_path: /tmp
+#timeout: 30
+#tls_ca_file: <none>
+#tls_ca_path: <none>
+#tlscache_db: berkeley-nosync
+#tls_cert_file: /var/lib/ssl/certs/cyrus-imapd.pem
+#tls_cipher_list: DEFAULT
+#tls_key_file: /var/lib/ssl/certs/cyrus-imapd.pem
+#tls_require_cert: 0
+#tls_session_timeout: 1440
+
+#umask: 077
+username_tolower: 1
+#userprefix: Other Users
+#unix_group_enable: 1
+#unixhierarchysep: 0
+#virtdomains: on
diff --git a/gosa-core/contrib/altlinux/etc/ldap.conf b/gosa-core/contrib/altlinux/etc/ldap.conf
new file mode 100644 (file)
index 0000000..c245047
--- /dev/null
@@ -0,0 +1,227 @@
+# @(#)$Id: ldap.conf,v 1.1 2004/09/16 06:46:19 migor-guest Exp $
+#
+# This is the configuration file for the LDAP nameservice
+# switch library and the LDAP PAM module.
+#
+# PADL Software
+# http://www.padl.com
+#
+
+# Your LDAP server. Must be resolvable without using LDAP.
+# Multiple hosts may be specified, each separated by a 
+# space. How long nss_ldap takes to failover depends on
+# whether your LDAP client library supports configurable
+# network or connect timeouts (see bind_timelimit).
+#host 127.0.0.1
+
+# The distinguished name of the search base.
+base dc=example,dc=com
+
+# Another way to specify your LDAP server is to provide an
+# uri with the server name. This allows to use
+# Unix Domain Sockets to connect to a local LDAP Server.
+uri ldap://127.0.0.1/
+#uri ldaps://127.0.0.1/   
+#uri ldapi://%2fvar%2frun%2fldapi_sock/
+# Note: %2f encodes the '/' used as directory separator
+
+# The LDAP version to use (defaults to 3
+# if supported by client library)
+ldap_version 3
+
+# The distinguished name to bind to the server with.
+# Optional: default is to bind anonymously.
+#binddn cn=proxyuser,dc=example,dc=com
+
+# The credentials to bind with. 
+# Optional: default is no credential.
+#bindpw secret
+
+# The distinguished name to bind to the server with
+# if the effective user ID is root. Password is
+# stored in /etc/ldap.secret (mode 600)
+#rootbinddn cn=manager,dc=example,dc=com
+
+# The port.
+# Optional: default is 389.
+#port 389
+
+# The search scope.
+#scope sub
+#scope one
+#scope base
+
+# Search timelimit
+#timelimit 30
+
+# Bind/connect timelimit
+#bind_timelimit 30
+
+# Reconnect policy: hard (default) will retry connecting to
+# the software with exponential backoff, soft will fail
+# immediately.
+#bind_policy hard
+
+# Idle timelimit; client will close connections
+# (nss_ldap only) if the server has not been contacted
+# for the number of seconds specified below.
+#idle_timelimit 3600
+
+# Filter to AND with uid=%s
+#pam_filter objectclass=account
+
+# The user ID attribute (defaults to uid)
+#pam_login_attribute uid
+
+# Search the root DSE for the password policy (works
+# with Netscape Directory Server)
+#pam_lookup_policy yes
+
+# Group to enforce membership of
+#pam_groupdn cn=PAM,ou=Groups,dc=example,dc=com
+
+# Group member attribute
+#pam_member_attribute uniquemember
+
+# Template login attribute, default template user
+# (can be overriden by value of former attribute
+# in user's entry)
+#pam_login_attribute userPrincipalName
+#pam_template_login_attribute uid
+#pam_template_login nobody
+
+# HEADS UP: the pam_crypt, pam_nds_passwd,
+# and pam_ad_passwd options are no
+# longer supported.
+
+# Do not hash the password at all; presume
+# the directory server will do it, if
+# necessary. This is the default.
+#pam_password clear
+
+# Hash password locally; required for University of
+# Michigan LDAP server, and works with Netscape
+# Directory Server if you're using the UNIX-Crypt
+# hash mechanism and not using the NT Synchronization
+# service. 
+#pam_password crypt
+
+# Remove old password first, then update in
+# cleartext. Necessary for use with Novell
+# Directory Services (NDS)
+#pam_password nds
+
+# Update Active Directory password, by
+# creating Unicode password and updating
+# unicodePwd attribute.
+#pam_password ad
+
+# Use the OpenLDAP password change
+# extended operation to update the password.
+#pam_password exop
+
+# RFC2307bis naming contexts
+# Syntax:
+# nss_base_XXX         base?scope?filter
+# where scope is {base,one,sub}
+# and filter is a filter to be &'d with the
+# default filter.
+# You can omit the suffix eg:
+# nss_base_passwd      ou=People,
+# to append the default base DN but this
+# may incur a small performance impact.
+#nss_base_passwd       ou=People,dc=example,dc=com?one
+#nss_base_shadow       ou=People,dc=example,dc=com?one
+#nss_base_group                ou=Groups,dc=example,dc=com?one
+#nss_base_hosts                ou=Hosts,dc=example,dc=com?one
+#nss_base_services     ou=Services,dc=example,dc=com?one
+#nss_base_networks     ou=Networks,dc=example,dc=com?one
+#nss_base_protocols    ou=Protocols,dc=example,dc=com?one
+#nss_base_rpc          ou=Rpc,dc=example,dc=com?one
+#nss_base_ethers       ou=Ethers,dc=example,dc=com?one
+#nss_base_netmasks     ou=Networks,dc=example,dc=com?ne
+#nss_base_bootparams   ou=Ethers,dc=example,dc=com?one
+#nss_base_aliases      ou=Aliases,dc=example,dc=com?one
+#nss_base_netgroup     ou=Netgroup,dc=example,dc=com?one
+
+# attribute/objectclass mapping
+# Syntax:
+#nss_map_attribute     rfc2307attribute        mapped_attribute
+#nss_map_objectclass   rfc2307objectclass      mapped_objectclass
+
+# configure --enable-nds is no longer supported.
+# For NDS now do:
+#nss_map_attribute uniqueMember member
+
+# configure --enable-mssfu-schema is no longer supported.
+# For MSSFU now do:
+#nss_map_objectclass posixAccount User
+#nss_map_attribute uid msSFUName
+#nss_map_attribute uniqueMember posixMember
+#nss_map_attribute userPassword msSFUPassword
+#nss_map_attribute homeDirectory msSFUHomeDirectory
+#nss_map_objectclass posixGroup Group
+#nss_map_attribute cn msSFUName
+#pam_login_attribute msSFUName
+#pam_filter objectclass=User
+#pam_password ad
+
+# Alternatively, if you wish to equivalence W2K and POSIX
+# groups, change the uniqueMember mapping line to:
+#nss_map_attribute uniqueMember member
+
+# configure --enable-authpassword is no longer supported
+# For authPassword support, now do:
+#nss_map_attribute userPassword authPassword
+#pam_password nds
+
+# For IBM AIX SecureWay support, do:
+#nss_map_objectclass posixAccount aixAccount
+#nss_base_passwd ou=aixaccount,?one
+#nss_map_attribute uid userName
+#nss_map_attribute gidNumber gid
+#nss_map_attribute uidNumber uid
+#nss_map_attribute userPassword passwordChar
+#nss_map_objectclass posixGroup aixAccessGroup
+#nss_base_group ou=aixgroup,?one
+#nss_map_attribute cn groupName
+#nss_map_attribute uniqueMember member
+#pam_login_attribute userName
+#pam_filter objectclass=aixAccount
+#pam_password clear
+
+# Netscape SDK LDAPS
+#ssl on
+
+# Netscape SDK SSL options
+#sslpath /etc/ssl/certs/cert7.db
+
+# OpenLDAP SSL mechanism
+# start_tls mechanism uses the normal LDAP port, LDAPS typically 636
+#ssl start_tls
+#ssl on
+
+# OpenLDAP SSL options
+# Require and verify server certificate (yes/no)
+# Default is "no"
+#tls_checkpeer yes
+
+# CA certificates for server certificate verification
+# At least one of these are required if tls_checkpeer is "yes"
+#tls_cacertfile /etc/ssl/ca.cert
+#tls_cacertdir /etc/ssl/certs
+
+# SSL cipher suite
+# See man ciphers for syntax
+#tls_ciphers TLSv1
+
+# Client certificate and key
+# Use these, if your server requires client authentication.
+#tls_cert
+#tls_key
+
+# Disable SASL security layers. This is needed for AD.
+#sasl_secprops maxssf=0
+
+# Override the default Kerberos ticket cache location.
+#krb5_ccname FILE:/etc/.ldapcache
diff --git a/gosa-core/contrib/altlinux/etc/nsswitch.conf b/gosa-core/contrib/altlinux/etc/nsswitch.conf
new file mode 100644 (file)
index 0000000..5f0d1eb
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Please refer to nsswitch.conf(5) for more information on this file.
+#
+# This is the Name Service Switch configuration file.  This file should
+# be sorted with the most-used databases at the beginning.
+#
+# Specifying '[NOTFOUND=return]' means that the search for an entry
+# should stop if the search with the previous service turned up nothing.
+# Note that if the search failed due to some other reason (like no NIS
+# server responding) then the search continues with the next service.
+#
+# Legal name services are:
+#
+#      files                   Use local files
+#      tcb                     Use local tcb shadow files, see tcb(5)
+#      db                      Use local database files under /var/db
+#      nis or yp               Use NIS (NIS version 2), also called YP
+#      nisplus or nis+         Use NIS+ (NIS version 3)
+#      dns                     Use DNS (Domain Name Service)
+#      compat                  Use NIS in compatibility mode
+#      hesiod                  Use Hesiod for user lookups
+#      [NOTFOUND=return]       Stop searching if not found so far
+#
+
+passwd:     files ldap 
+shadow:     tcb ldap
+group:      files ldap
+
+hosts:      files nisplus nis dns
+
+# To use db, put the "db" in front of "files" for things you want to be
+# looked up first in the db files.
+#
+#passwd:    db files nisplus nis
+#shadow:    db tcb files nisplus nis
+#group:     db files nisplus nis
+#
+#hosts:     db files nisplus nis dns
+
+ethers:     files
+netmasks:   files
+networks:   files
+protocols:  files
+rpc:        files
+services:   files
+
+# Example - obey only what nisplus tells us...
+#services:  nisplus [NOTFOUND=return] files
+#networks:  nisplus [NOTFOUND=return] files
+#protocols: nisplus [NOTFOUND=return] files
+#rpc:       nisplus [NOTFOUND=return] files
+#ethers:    nisplus [NOTFOUND=return] files
+#netmasks:  nisplus [NOTFOUND=return] files
+
+bootparams: nisplus [NOTFOUND=return] files
+
+netgroup:   nisplus
+
+publickey:  nisplus
+
+automount:  files nisplus
+aliases:    files nisplus
diff --git a/gosa-core/contrib/altlinux/etc/openldap/ldap.conf b/gosa-core/contrib/altlinux/etc/openldap/ldap.conf
new file mode 100644 (file)
index 0000000..eac6d22
--- /dev/null
@@ -0,0 +1,17 @@
+# $OpenLDAP: pkg/ldap/libraries/libldap/ldap.conf,v 1.9 2000/09/04 19:57:01 kurt Exp $
+#
+# LDAP Defaults
+#
+
+# See ldap.conf(5) for details
+# This file should be world readable but not world writable.
+
+BASE   dc=example,dc=com
+URI    ldap://localhost
+
+#URI    ldap://ldap.example.com ldap://ldap-master.example.com:666
+
+#SIZELIMIT      12
+#TIMELIMIT      15
+#DEREF          never
+
diff --git a/gosa-core/contrib/altlinux/etc/openldap/slapd.conf b/gosa-core/contrib/altlinux/etc/openldap/slapd.conf
new file mode 100644 (file)
index 0000000..37ee301
--- /dev/null
@@ -0,0 +1,311 @@
+# $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.23.2.8 2003/05/24 23:19:14 kurt Exp $
+#
+# See slapd.conf(5) for details on configuration options.
+# This file should NOT be world readable.
+#
+# [ GLOBAL SETTINGS ]
+# Default schemas
+include                /etc/openldap/schema/core.schema
+include                /etc/openldap/schema/cosine.schema
+include                /etc/openldap/schema/inetorgperson.schema
+include                /etc/openldap/schema/openldap.schema
+include                /etc/openldap/schema/nis.schema
+#include               /etc/openldap/schema/misc.schema
+#include               /etc/openldap/schema/rfc822-MailMember.schema
+#include               /etc/openldap/schema/kerberosobject.schema
+#include               /etc/openldap/schema/corba.schema
+#include               /etc/openldap/schema/java.schema
+# Addon schemas
+#include               /etc/openldap/schema/autofs.schema
+#include               /etc/openldap/schema/courier.schema
+#include               /etc/openldap/schema/dnszone.schema
+#include               /etc/openldap/schema/qmail.schema
+#include               /etc/openldap/schema/qmailControl.schema
+#include               /etc/openldap/schema/samba2.schema
+include                /etc/openldap/schema/samba3.schema
+# Experementel schemas
+#include               /etc/openldap/schema/cron.schema
+#include               /etc/openldap/schema/trust.schema
+#include               /etc/openldap/schema/turbo.schema
+# Netscape roaming
+#include               /etc/openldap/schema/mull.schema
+#include               /etc/openldap/schema/netscape-profile.schema
+# Local schema
+
+# GOSA2 schemas
+#include               /etc/openldap/schema/local.schema
+include                /etc/openldap/schema/gohard.schema
+include                /etc/openldap/schema/goto.schema
+include                /etc/openldap/schema/gofax.schema
+include                /etc/openldap/schema/goserver.schema
+include                /etc/openldap/schema/gosa+samba3.schema
+#include               /etc/openldap/schema/gosa.schema
+
+# Specify  a  set  of features (separated by white space) to allow.
+allow bind_v2
+
+# Do not enable referrals until AFTER you have a working directory
+# service AND an understanding of referrals.
+#referral ldap://root.openldap.org
+
+# Specify a desired level of concurrency. Provided to the underlying thread
+# system as a hint. The default is not to provide any hint.
+concurency 20
+
+# Specify  the maximum number of pending requests for an anonymous session.  If
+# requests are submitted faster than the  server  can process them, they will
+# be queued up to this limit. If the limit is exceeded, the session is closed.
+#conn_max_pending 100
+
+# Specify  the  maximum  number  of  pending   requests   for   an
+# authenticated session.
+#conn_max_pending 1000 
+
+# Specify  a default search base to use when client submits a non-base search
+# request with an empty base DN.
+defaultsearchbase "dc=example,dc=com"
+
+# A SIGHUP signal will only  cause  a  'gentle'  shutdown-attempt: Slapd  will
+# stop  listening  for  new connections, but will not close the connections to
+# the  current  clients.
+gentlehup on
+
+# Specify the number of seconds to wait before forcibly closing an idle client
+# connection. A idletimeout of 0 disables this feature.
+#idletimeout 0
+
+# Specify time and size limits based on who initiated an operation.
+#sizelimit 500
+#timelimit 60
+#limits anonymous time.soft=60 time.hard=120
+#limits anonymous size.soft=1000 size.hard=1100 size.unchecked=1000
+#limits users time.soft=60 time.hard=120
+#limits users size=1000
+#limits dn.base="ou=People,dc=example,dc=com" size=100
+
+# Specify the level at which debugging statements and operation statistics
+# should be syslogged (currently logged to the syslogd(8) LOG_LOCAL4 facility).
+# Log levels are additive, and available levels are:
+#    -1  full
+#     0  none
+#     1  trace function calls
+#     2  debug packet handling
+#     4  heavy trace debugging
+#     8  connection management
+#    16  print out packets sent and received
+#    32  search filter processing
+#    64  configuration file processing
+#   128  access control list processing
+#   256  stats log connections/operations/results
+#   512  stats log entries sent
+#  1024  print communication with shell backends
+#  2048  entry parsing
+#loglevel 256
+
+# This option sets the hash to be used in generation of user passwords, stored
+# in userPassword, during processing of LDAP Password Modify Extended
+# Operations (RFC 3062). The <hash> must be one of {SSHA}, {SHA}, {SMD5},
+# {MD5}, {CRYPT}, and {CLEARTEXT}. The default is {SSHA}.
+#password-hash {SSHA}
+
+# The ( absolute ) name of a file that will hold the server's process ID
+# if started without the debugging command line option.
+pidfile                        /var/run/slapd.pid
+argsfile               /var/run/slapd.args
+replica-pidfile                /var/run/slurpd.pid
+replica-argsfile       /var/run/slurpd.args
+
+# Specify a set of conditions (separated by white space) to require (default
+# none). The directive may be specified globally and/or per-database. bind
+# requires bind operation prior to directory operations. LDAPv3 requires
+# session to be using LDAP version 3. authc requires authentication prior to
+# directory operations. SASL requires SASL authentication prior to directory
+# operations. strong requires strong authentication prior to directory
+# operations. The strong keyword allows protected "simple" authentication as
+# well as SASL authentication. none may be used to require no conditions
+# (useful for clearly globally set conditions within a particular database).
+#require none
+
+# Specify the name of an LDIF(5) file containing user defined attributes for
+# the root DSE. These attributes are returned in addition to the attributes
+# normally produced by slapd.
+#rootDSE /etc/openldap/rootdse.ldif
+
+# Specify a set of factors (separated by white space) to require. An integer
+# value is associated with each factor and is roughly equivalent of the
+# encryption key length to require. A value of 112 is equivalent to 3DES, 128
+# to Blowfish, etc..
+#      Require integrity protection (prevent hijacking)
+#      Require 112-bit (3DES or better) encryption for updates
+#      Require 63-bit encryption for simple bind
+#security ssf=1 update_ssf=112 simple_bind=64
+
+# Specify the maximum size of the primary thread pool. The default is 16.
+#threads 16
+
+
+#
+# [ TLS OPTIONS ]
+#
+# Permits configuring what ciphers will be accepted and the preference order.
+# <cipher-suite-spec> should be a cipher specification for OpenSSL.
+#TLSCipherSuite HIGH:MEDIUM:+SSLv2
+
+# Specifies the path of a directory that contains Certificate Authority
+# certificates in separate individual files. Usually only one of this or the
+# TLSCACertificateFile is used.
+#TLSCACertificateFile /etc/openldap/ssl/slapd.pem
+#TLSCACertificatePath /etc/openldap/ssl
+
+# Specifies the file that contains the slapd server certificate.
+#TLSCertificateFile /etc/openldap/ssl/slapd.pem
+
+# Specifies the file that contains the slapd server private key that matches
+# the certificate stored in the TLSCertificateFile file. Currently, the private
+# key must not be protected with a password, so it is of critical importance
+# that it is protected carefully.
+#TLSCertificateKeyFile /etc/openldap/ssl/slapd.pem
+
+# Specifies what checks to perform on client certificates in an incoming TLS
+# session, if any.
+#TLSVerifyClient never
+
+
+#
+# [ ACCESS CONTROL ]
+#
+# See slapd.access(5) for details
+#access to attrs=userPassword
+#      by self write
+#      by anonymous auth
+#      by * none
+
+
+#
+# [ BACKEND OPTIONS ]
+#
+# Load dynamic backend modules:
+modulepath     /usr/lib/openldap
+#moduleload    back_dnssrv.la
+#moduleload    back_ldap.la
+moduleload     back_bdb.la
+#moduleload    back_ldbm.la
+#moduleload    back_meta.la
+#moduleload    back_monitor.la
+#moduleload    back_null.la
+#moduleload    back_passwd.la
+#moduleload    back_shell.la
+#moduleload    back_perl.la
+#moduleload    back_sql.la
+
+# Options in this section only apply to the configuration file section for the
+# specified backend. They are supported by every type of backend.
+#backend ldbm
+#cachesize 1000
+#dbcachesize 100000
+#dbsync 10 12 5
+
+
+#
+# [ DATABASE OPTIONS ]
+#
+# Mark the beginning of a new database instance definition.
+#database ldbm
+
+# Specify the DN suffix of queries that will be passed to this backend
+# database. Multiple suffix lines can be given and at least one is required for
+# each database definition. If the suffix of one database is "inside" that of
+# another, the database with the inner suffix must come first in the
+# configuration file.
+#suffix "dc=example,dc=com"
+
+# Specify the distinguished name that is not subject to access control or
+# administrative limit restrictions for operations on this database. An empty
+# root DN (the default) specifies no root access is to be granted. It is
+# recommended that the rootdn only be specified when needed (such as when
+# initially populating a database).
+#rootdn "cn=admin,dc=example,dc=com"
+
+# Specify a password (or hash of the password) for the rootdn. This option
+# accepts all RFC 2307 userPassword formats known to the server (see
+# password-hash desription) as well as cleartext.
+#rootpw secret
+
+# Controls whether slapd will automatically maintain the modifiersName,
+# modifyTimestamp, creatorsName, and createTimestamp attributes for entries.
+#lastmod on
+
+# Specifies the maximum number of aliases to dereference when trying to resolve
+# an entry, used to avoid inifinite alias loops.
+#maxderefdepth 1
+
+# This option puts the database into "read-only" mode. Any attempts to modify
+# the database will return an "unwilling to perform" error.
+#readonly on
+
+# Specify a replication site for this database. Refer to the "OpenLDAP
+# Administrator's Guide" for detailed information on setting up a replicated
+# slapd directory service.
+#replica uri=ldaps://ldap2.example.com/
+
+# Specify the name of the replication log file to log changes to.
+#replogfile /var/lib/ldap/replica/example.com.replog
+
+# Specify that the current backend database is a subordinate of another backend
+# database. A subordinate database may have only one suffix. This option may be
+# used to glue multiple databases into a single namingContext.
+#subordinate
+
+# This option is only applicable in a slave slapd. It specifies the DN allowed
+# to make changes to the replica
+#updatedn "cn=slave,dc=example,dc=com"
+
+# Specify the referral to pass back when slapd(8) is asked to modify a
+# replicated local database. If specified multiple times, each url is provided.
+#updateref "uri=ldap://ldap2.example.com"
+
+# Specify the directory where the LDBM files containing this database and
+# associated indexes live.
+#directory /var/lib/ldap/bases/example.com
+
+# Specify the indexes to maintain for the given attribute (or list of
+# attributes). Some attributes only support a subset of indexes.Specify the
+# indexes to maintain for the given attribute (or list of attributes). Some
+# attributes only support a subset of indexes.
+#index objectClass eq
+#index uid pres,eq,sub
+#index cn pres,eq,sub,subany
+
+#access to *
+#      by * read
+
+
+#
+# Next database instance
+#
+database bdb
+suffix "dc=example,dc=com"
+#rootdn "cn=admin,dc=example,dc=com"
+#rootpw secret
+directory /var/lib/ldap/bases/example.com
+
+index objectClass eq
+index uid pres,eq
+index cn pres,eq,sub,subany
+index mail pres,eq
+index gosaMailDeliveryMode pres,eq,sub
+
+access to userPassword
+       by dn=".*,ou=Admins,dc=example,dc=com" write
+       by dn="cn=gosa,ou=Apps,dc=example,dc=com" write
+       by dn="cn=smbpasswd,ou=Apps,dc=example,dc=com" write
+       by self write
+       by anonymous auth
+       by * none
+
+access to *
+       by dn=".*,ou=Admins,dc=example,dc=com" write
+       by dn="cn=gosa,ou=Apps,dc=example,dc=com" write
+       by dn="cn=smbpasswd,ou=Apps,dc=example,dc=com" write
+       by * read
+
diff --git a/gosa-core/contrib/altlinux/etc/postfix/main.cf b/gosa-core/contrib/altlinux/etc/postfix/main.cf
new file mode 100644 (file)
index 0000000..225bea7
--- /dev/null
@@ -0,0 +1,596 @@
+# Global Postfix configuration file. This file lists only a subset
+# of all 300+ parameters. See the samples/xxx.cf files for a full list.
+# 
+# The general format is lines with parameter = value pairs. Lines
+# that begin with whitespace continue the previous line. A value can
+# contain references to other $names or ${name}s.
+#
+# NOTE - CHANGE NO MORE THAN 2-3 PARAMETERS AT A TIME, AND TEST IF
+# POSTFIX STILL WORKS AFTER EVERY CHANGE.
+
+# SOFT BOUNCE
+#
+# The soft_bounce parameter provides a limited safety net for
+# testing.  When soft_bounce is enabled, mail will remain queued that
+# would otherwise bounce. This parameter disables locally-generated
+# bounces, and prevents the SMTP server from rejecting mail permanently
+# (by changing 5xx replies into 4xx replies). However, soft_bounce
+# is no cure for address rewriting mistakes or mail routing mistakes.
+#
+#soft_bounce = no
+
+# INTERNET HOST AND DOMAIN NAMES
+# 
+# The myhostname parameter specifies the internet hostname of this
+# mail system. The default is to use the fully-qualified domain name
+# from gethostname(). $myhostname is used as a default value for many
+# other configuration parameters.
+#
+#myhostname = host.domain.tld
+#myhostname = virtual.domain.tld
+
+# The mydomain parameter specifies the local internet domain name.
+# The default is to use $myhostname minus the first component.
+# $mydomain is used as a default value for many other configuration
+# parameters.
+#
+#mydomain = domain.tld
+
+# SENDING MAIL
+# 
+# The myorigin parameter specifies the domain that locally-posted
+# mail appears to come from. The default is to append $myhostname,
+# which is fine for small sites.  If you run a domain with multiple
+# machines, you should (1) change this to $mydomain and (2) set up
+# a domain-wide alias database that aliases each user to
+# user@that.users.mailhost.
+#
+# For the sake of consistency between sender and recipient addresses,
+# myorigin also specifies the default domain name that is appended
+# to recipient addresses that have no @domain part.
+#
+#myorigin = $myhostname
+#myorigin = $mydomain
+
+# RECEIVING MAIL
+
+# The inet_interfaces parameter specifies the network interface
+# addresses that this mail system receives mail on.  By default,
+# the software claims all active interfaces on the machine. The
+# parameter also controls delivery of mail to user@[ip.address].
+#
+# See also the proxy_interfaces parameter, for network addresses that
+# are forwarded to us via a proxy or network address translator.
+#
+# Note: you need to stop/start Postfix when this parameter changes.
+#
+#inet_interfaces = all
+#inet_interfaces = $myhostname
+#inet_interfaces = $myhostname, localhost
+
+# The proxy_interfaces parameter specifies the network interface
+# addresses that this mail system receives mail on by way of a
+# proxy or network address translation unit. This setting extends
+# the address list specified with the inet_interfaces parameter.
+#
+# You must specify your proxy/NAT addresses when your system is a
+# backup MX host for other domains, otherwise mail delivery loops
+# will happen when the primary MX host is down.
+#
+#proxy_interfaces =
+#proxy_interfaces = 1.2.3.4
+
+# The mydestination parameter specifies the list of domains that this
+# machine considers itself the final destination for.
+#
+# These domains are routed to the delivery agent specified with the
+# local_transport parameter setting. By default, that is the UNIX
+# compatible delivery agent that lookups all recipients in /etc/passwd
+# and /etc/aliases or their equivalent.
+#
+# The default is $myhostname + localhost.$mydomain.  On a mail domain
+# gateway, you should also include $mydomain.
+#
+# Do not specify the names of virtual domains - those domains are
+# specified elsewhere (see samples/virtual.cf).
+#
+# Do not specify the names of domains that this machine is backup MX
+# host for. Specify those names via the relay_domains settings for
+# the SMTP server, or use permit_mx_backup if you are lazy (see
+# samples/smtpd.cf).
+#
+# The local machine is always the final destination for mail addressed
+# to user@[the.net.work.address] of an interface that the mail system
+# receives mail on (see the inet_interfaces parameter).
+#
+# Specify a list of host or domain names, /file/name or type:table
+# patterns, separated by commas and/or whitespace. A /file/name
+# pattern is replaced by its contents; a type:table is matched when
+# a name matches a lookup key (the right-hand side is ignored).
+# Continue long lines by starting the next line with whitespace.
+#
+# DO NOT LIST RELAY DESTINATIONS IN MYDESTINATION.
+# SPECIFY RELAY DESTINATIONS IN RELAY_DOMAINS.
+#
+# See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
+#
+#mydestination = $myhostname, localhost.$mydomain
+#mydestination = $myhostname, localhost.$mydomain $mydomain
+#mydestination = $myhostname, localhost.$mydomain, $mydomain,
+#      mail.$mydomain, www.$mydomain, ftp.$mydomain
+mydestination = localhost, $myhostname, localhost.$mydomain, $config_directory/mydestination
+
+# REJECTING MAIL FOR UNKNOWN LOCAL USERS
+#
+# The local_recipient_maps parameter specifies optional lookup tables
+# with all names or addresses of users that are local with respect
+# to $mydestination and $inet_interfaces.
+#
+# If this parameter is defined, then the SMTP server will reject
+# mail for unknown local users. This parameter is defined by default.
+#
+# To turn off local recipient checking in the SMTP server, specify
+# local_recipient_maps = (i.e. empty).
+#
+# The default setting assumes that you use the default Postfix local
+# delivery agent for local delivery. You need to update the
+# local_recipient_maps setting if:
+#
+# - You define $mydestination domain recipients in files other than
+#   /etc/passwd, /etc/postfix/aliases, or the $virtual_alias_maps files.
+#   For example, you define $mydestination domain recipients in    
+#   the $virtual_mailbox_maps files.
+#
+# - You redefine the local delivery agent in master.cf.
+#
+# - You redefine the "local_transport" setting in main.cf.
+#
+# - You use the "luser_relay", "mailbox_transport", or "fallback_transport"
+#   feature of the Postfix local delivery agent (see samples/local.cf).
+#
+# Details are described in the LOCAL_RECIPIENT_README file.
+#
+# Beware: if the Postfix SMTP server runs chrooted, you probably have
+# to access the passwd file via the proxymap service, in order to
+# overcome chroot restrictions. The alternative, having a copy of
+# the system passwd file in the chroot jail is just not practical.
+#
+# The right-hand side of the lookup tables is conveniently ignored.
+# In the left-hand side, specify a bare username, an @domain.tld
+# wild-card, or specify a user@domain.tld address.
+# 
+#local_recipient_maps = unix:passwd.byname $alias_maps
+#local_recipient_maps = proxy:unix:passwd.byname $alias_maps
+#local_recipient_maps =
+
+# The unknown_local_recipient_reject_code specifies the SMTP server
+# response code when a recipient domain matches $mydestination or
+# $inet_interfaces, while $local_recipient_maps is non-empty and the
+# recipient address or address local-part is not found.
+#
+# The default setting is 550 (reject mail) but it is safer to start
+# with 450 (try again later) until you are certain that your
+# local_recipient_maps settings are OK.
+#
+unknown_local_recipient_reject_code = 550
+
+# TRUST AND RELAY CONTROL
+
+# The mynetworks parameter specifies the list of "trusted" SMTP
+# clients that have more privileges than "strangers".
+#
+# In particular, "trusted" SMTP clients are allowed to relay mail
+# through Postfix.  See the smtpd_recipient_restrictions parameter
+# in file samples/smtpd.cf.
+#
+# You can specify the list of "trusted" network addresses by hand
+# or you can let Postfix do it for you (which is the default).
+#
+# By default (mynetworks_style = host), Postfix "trusts" SMTP
+# clients of the local machine only.
+# 
+# Specify "mynetworks_style = class" when Postfix should "trust" SMTP
+# clients in the same IP class A/B/C networks as the local machine.
+# Don't do this with a dialup site - it would cause Postfix to "trust"
+# your entire provider's network.  Instead, specify an explicit
+# mynetworks list by hand, as described below.
+#  
+# Specify "mynetworks_style = subnet" when Postfix should "trust" SMTP
+# clients in the same IP subnetworks as the local machine.
+# 
+#mynetworks_style = class
+#mynetworks_style = subnet
+#mynetworks_style = host
+
+# Alternatively, you can specify the mynetworks list by hand, in
+# which case Postfix ignores the mynetworks_style setting.
+#
+# Specify an explicit list of network/netmask patterns, where the
+# mask specifies the number of bits in the network part of a host
+# address.
+#
+# You can also specify the absolute pathname of a pattern file instead
+# of listing the patterns here. Specify type:table for table-based lookups
+# (the value on the table right-hand side is not used).
+#
+#mynetworks = 168.100.189.0/28, 127.0.0.0/8
+#mynetworks = $config_directory/mynetworks
+#mynetworks = hash:/etc/postfix/network_table
+
+# The relay_domains parameter restricts what destinations this system will
+# relay mail to.  See the smtpd_recipient_restrictions restriction in the
+# file samples/smtpd.cf for detailed information.
+#
+# By default, Postfix relays mail
+# - from "trusted" clients (IP address matches $mynetworks) to any destination,
+# - from "untrusted" clients to destinations that match $relay_domains or
+#   subdomains thereof, except addresses with sender-specified routing.
+# The default relay_domains value is $mydestination.
+# 
+# In addition to the above, the Postfix SMTP server by default accepts mail
+# that Postfix is final destination for:
+# - destinations that match $inet_interfaces,
+# - destinations that match $mydestination
+# - destinations that match $virtual_alias_domains,
+# - destinations that match $virtual_mailbox_domains.
+# These destinations do not need to be listed in $relay_domains.
+# 
+# Specify a list of hosts or domains, /file/name patterns or type:name
+# lookup tables, separated by commas and/or whitespace.  Continue
+# long lines by starting the next line with whitespace. A file name
+# is replaced by its contents; a type:name table is matched when a
+# (parent) domain appears as lookup key.
+#
+# NOTE: Postfix will not automatically forward mail for domains that
+# list this system as their primary or backup MX host. See the
+# permit_mx_backup restriction in the file samples/smtpd.cf.
+#
+#relay_domains = $mydestination
+
+# INTERNET OR INTRANET
+
+# The relayhost parameter specifies the default host to send mail to
+# when no entry is matched in the optional transport(5) table. When
+# no relayhost is given, mail is routed directly to the destination.
+#
+# On an intranet, specify the organizational domain name. If your
+# internal DNS uses no MX records, specify the name of the intranet
+# gateway host instead.
+#
+# In the case of SMTP, specify a domain, host, host:port, [host]:port,
+# [address] or [address]:port; the form [host] turns off MX lookups.
+#
+# If you're connected via UUCP, see also the default_transport parameter.
+#
+#relayhost = $mydomain
+#relayhost = gateway.my.domain
+#relayhost = uucphost
+#relayhost = [an.ip.add.ress]
+
+# REJECTING UNKNOWN RELAY USERS
+#
+# The relay_recipient_maps parameter specifies optional lookup tables
+# with all addresses in the domains that match $relay_domains.
+#
+# If this parameter is defined, then the SMTP server will reject
+# mail for unknown relay users. This feature is off by default.
+#
+# The right-hand side of the lookup tables is conveniently ignored.
+# In the left-hand side, specify an @domain.tld wild-card, or specify
+# a user@domain.tld address.
+# 
+#relay_recipient_maps = hash:/etc/postfix/relay_recipients
+
+# INPUT RATE CONTROL
+#
+# The in_flow_delay configuration parameter implements mail input
+# flow control. This feature is turned on by default, although it
+# still needs further development (it's disabled on SCO UNIX due
+# to an SCO bug).
+# 
+# A Postfix process will pause for $in_flow_delay seconds before
+# accepting a new message, when the message arrival rate exceeds the
+# message delivery rate. With the default 100 SMTP server process
+# limit, this limits the mail inflow to 100 messages a second more
+# than the number of messages delivered per second.
+# 
+# Specify 0 to disable the feature. Valid delays are 0..10.
+# 
+#in_flow_delay = 1s
+
+# ADDRESS REWRITING
+#
+# Insert text from samples/rewrite.cf if you need to do address
+# masquerading.
+#
+# Insert text from samples/canonical.cf if you need to do address
+# rewriting, or if you need username->Firstname.Lastname mapping.
+
+# ADDRESS REDIRECTION (VIRTUAL DOMAIN)
+#
+# Insert text from samples/virtual.cf if you need virtual domain support.
+
+# "USER HAS MOVED" BOUNCE MESSAGES
+#
+# Insert text from samples/relocated.cf if you need "user has moved"
+# style bounce messages. Alternatively, you can bounce recipients
+# with an SMTP server access table. See samples/smtpd.cf.
+
+# TRANSPORT MAP
+#
+# Insert text from samples/transport.cf if you need explicit routing.
+
+# ALIAS DATABASE
+#
+# The alias_maps parameter specifies the list of alias databases used
+# by the local delivery agent. The default list is system dependent.
+#
+# On systems with NIS, the default is to search the local alias
+# database, then the NIS alias database. See aliases(5) for syntax
+# details.
+# 
+# If you change the alias database, run "postalias /etc/postfix/aliases" (or
+# wherever your system stores the mail alias file), or simply run
+# "newaliases" to build the necessary DBM or DB file.
+#
+# It will take a minute or so before changes become visible.  Use
+# "postfix reload" to eliminate the delay.
+#
+#alias_maps = dbm:/etc/postfix/aliases
+alias_maps = hash:/etc/postfix/aliases
+#, hash:/var/lib/mailman/etc/aliases
+#alias_maps = hash:/etc/postfix/aliases, nis:mail.aliases
+#alias_maps = netinfo:/aliases
+
+# The alias_database parameter specifies the alias database(s) that
+# are built with "newaliases" or "sendmail -bi".  This is a separate
+# configuration parameter, because alias_maps (see above) may specify
+# tables that are not necessarily all under control by Postfix.
+#
+#alias_database = dbm:/etc/postfix/aliases
+alias_database = hash:/etc/postfix/aliases
+#alias_database = hash:/etc/postfix/aliases, hash:/opt/majordomo/aliases
+#virtual_maps = hash:/var/lib/mailman/etc/virtual-mailman
+
+# ADDRESS EXTENSIONS (e.g., user+foo)
+#
+# The recipient_delimiter parameter specifies the separator between
+# user names and address extensions (user+foo). See canonical(5),
+# local(8), relocated(5) and virtual(5) for the effects this has on
+# aliases, canonical, virtual, relocated and .forward file lookups.
+# Basically, the software tries user+foo and .forward+foo before
+# trying user and .forward.
+#
+#recipient_delimiter = +
+
+# DELIVERY TO MAILBOX
+#
+# The home_mailbox parameter specifies the optional pathname of a
+# mailbox file relative to a user's home directory. The default
+# mailbox file is /var/spool/mail/user or /var/mail/user.  Specify
+# "Maildir/" for qmail-style delivery (the / is required).
+#
+#home_mailbox = Mailbox
+#home_mailbox = Maildir/
+
+# The mail_spool_directory parameter specifies the directory where
+# UNIX-style mailboxes are kept. The default setting depends on the
+# system type.
+#
+#mail_spool_directory = /var/mail
+#mail_spool_directory = /var/spool/mail
+
+# The mailbox_command parameter specifies the optional external
+# command to use instead of mailbox delivery. The command is run as
+# the recipient with proper HOME, SHELL and LOGNAME environment settings.
+# Exception:  delivery for root is done as $default_user.
+#
+# Other environment variables of interest: USER (recipient username),
+# EXTENSION (address extension), DOMAIN (domain part of address),
+# and LOCAL (the address localpart).
+#
+# Unlike other Postfix configuration parameters, the mailbox_command
+# parameter is not subjected to $parameter substitutions. This is to
+# make it easier to specify shell syntax (see example below).
+#
+# Avoid shell meta characters because they will force Postfix to run
+# an expensive shell process. Procmail alone is expensive enough.
+#
+# IF YOU USE THIS TO DELIVER MAIL SYSTEM-WIDE, YOU MUST SET UP AN
+# ALIAS THAT FORWARDS MAIL FOR ROOT TO A REAL USER.
+#
+#mailbox_command = /usr/bin/procmail -a "$EXTENSION"
+mailbox_command = /usr/bin/procmail -a $DOMAIN -d $LOGNAME
+
+# The mailbox_transport specifies the optional transport in master.cf
+# to use after processing aliases and .forward files. This parameter
+# has precedence over the mailbox_command, fallback_transport and
+# luser_relay parameters.
+#
+# Specify a string of the form transport:nexthop, where transport is
+# the name of a mail delivery transport defined in master.cf.  The
+# :nexthop part is optional. For more details see the sample transport
+# configuration file.
+#
+# NOTE: if you use this feature for accounts not in the UNIX password
+# file, then you must update the "local_recipient_maps" setting in
+# the main.cf file, otherwise the SMTP server will reject mail for    
+# non-UNIX accounts with "User unknown in local recipient table".
+#
+mailbox_transport = lmtp:unix:/public/lmtp
+#mailbox_transport = cyrus
+
+# The fallback_transport specifies the optional transport in master.cf
+# to use for recipients that are not found in the UNIX passwd database.
+# This parameter has precedence over the luser_relay parameter.
+#
+# Specify a string of the form transport:nexthop, where transport is
+# the name of a mail delivery transport defined in master.cf.  The
+# :nexthop part is optional. For more details see the sample transport
+# configuration file.
+#
+# NOTE: if you use this feature for accounts not in the UNIX password
+# file, then you must update the "local_recipient_maps" setting in
+# the main.cf file, otherwise the SMTP server will reject mail for    
+# non-UNIX accounts with "User unknown in local recipient table".
+#
+#fallback_transport = lmtp:unix:/private/lmtp
+fallback_transport = cyrus
+#fallback_transport =
+
+# The luser_relay parameter specifies an optional destination address
+# for unknown recipients.  By default, mail for unknown@$mydestination
+# and unknown@[$inet_interfaces] is returned as undeliverable.
+#
+# The following expansions are done on luser_relay: $user (recipient
+# username), $shell (recipient shell), $home (recipient home directory),
+# $recipient (full recipient address), $extension (recipient address
+# extension), $domain (recipient domain), $local (entire recipient
+# localpart), $recipient_delimiter. Specify ${name?value} or
+# ${name:value} to expand value only when $name does (does not) exist.
+#
+# luser_relay works only for the default Postfix local delivery agent.
+#
+# NOTE: if you use this feature for accounts not in the UNIX password
+# file, then you must specify "local_recipient_maps =" (i.e. empty) in
+# the main.cf file, otherwise the SMTP server will reject mail for    
+# non-UNIX accounts with "User unknown in local recipient table".
+#
+#luser_relay = $user@other.host
+#luser_relay = $local@other.host
+#luser_relay = admin+$local
+
+# JUNK MAIL CONTROLS
+# 
+# The controls listed here are only a very small subset. See the file
+# samples/smtpd.cf for an elaborate list of anti-UCE controls.
+
+# The header_checks parameter specifies an optional table with patterns
+# that each logical message header is matched against, including
+# headers that span multiple physical lines.
+#
+# By default, these patterns also apply to MIME headers and to the
+# headers of attached messages. With older Postfix versions, MIME and
+# attached message headers were treated as body text.
+#
+# For details, see the samples/filter.cf file.
+#
+#header_checks = regexp:/etc/postfix/header_checks
+
+# FAST ETRN SERVICE
+#
+# Postfix maintains per-destination logfiles with information about
+# deferred mail, so that mail can be flushed quickly with the SMTP
+# "ETRN domain.tld" command, or by executing "sendmail -qRdomain.tld".
+# 
+# By default, Postfix maintains deferred mail logfile information
+# only for destinations that Postfix is willing to relay to (as
+# specified in the relay_domains parameter). For other destinations,
+# Postfix attempts to deliver ALL queued mail after receiving the
+# SMTP "ETRN domain.tld" command, or after execution of "sendmail
+# -qRdomain.tld". This can be slow when a lot of mail is queued.
+# 
+# The fast_flush_domains parameter controls what destinations are
+# eligible for this "fast ETRN/sendmail -qR" service.
+# 
+#fast_flush_domains = $relay_domains
+#fast_flush_domains =
+
+# SHOW SOFTWARE VERSION OR NOT
+#
+# The smtpd_banner parameter specifies the text that follows the 220
+# code in the SMTP server's greeting banner. Some people like to see
+# the mail version advertised. By default, Postfix shows no version.
+#
+# You MUST specify $myhostname at the start of the text. That is an
+# RFC requirement. Postfix itself does not care.
+#
+#smtpd_banner = $myhostname ESMTP $mail_name
+#smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
+
+# The smtpd_etrn_restrictions parameter restricts what clients are
+# allowed to issue the ETRN command.
+#
+# The Postfix ETRN command accepts only destinations that are eligible
+# for the Postfix "fast flush" service. See the samples/flush.cf file
+# for details.
+#
+# The default is to allow ETRN from any host.  The following restrictions
+# are available:
+#
+#   reject_unknown_client: reject the request if the client hostname is unknown.
+#   permit_mynetworks: permit if the client address matches $mynetworks.
+#   check_client_access maptype:mapname
+#      look up client name, parent domains, client address,
+#      or networks obtained by stripping octets.
+#      see access(5) for possible lookup results.
+#   reject_rbl_client domain.tld: reject if the reverse client network
+#      address is listed in an A record under domain.tld.
+#   reject_rhsbl_client domain.tld: reject if the client hostname is listed
+#      in an A record under domain.tld.
+#   reject: reject the request. Place this at the end of a restriction.
+#   permit: permit the request. Place this at the end of a restriction.
+#   warn_if_reject: next restriction logs a warning instead of rejecting.
+#
+# You may also list any helo or client restrictions here (see below).
+#
+smtpd_etrn_restrictions = permit_mynetworks, reject
+
+# The smtpd_helo_required parameter optionally turns on the requirement
+# that SMTP clients must introduce themselves at the beginning of an
+# SMTP session.
+#
+smtpd_helo_required = yes
+
+# PARALLEL DELIVERY TO THE SAME DESTINATION
+#
+# How many parallel deliveries to the same user or domain? With local
+# delivery, it does not make sense to do massively parallel delivery
+# to the same user, because mailbox updates must happen sequentially,
+# and expensive pipelines in .forward files can cause disasters when
+# too many are run at the same time. With SMTP deliveries, 10
+# simultaneous connections to the same domain could be sufficient to
+# raise eyebrows.
+# 
+# Each message delivery transport has its XXX_destination_concurrency_limit
+# parameter.  The default is $default_destination_concurrency_limit for
+# most delivery transports. For the local delivery agent the default is 2.
+
+#local_destination_concurrency_limit = 2
+#default_destination_concurrency_limit = 20
+
+# INSTALL-TIME CONFIGURATION INFORMATION
+readme_directory = /etc/postfix/README_FILES
+sample_directory = /etc/postfix/samples
+sendmail_path = /usr/sbin/sendmail
+setgid_group = postdrop
+command_directory = /usr/sbin
+manpage_directory = /usr/share/man
+daemon_directory = /usr/lib/postfix
+newaliases_path = /usr/bin/newaliases
+mailq_path = /usr/bin/mailq
+queue_directory = /var/spool/postfix
+mail_owner = postfix
+
+# SASL authenticated SMTPD
+#smtpd_sasl_auth_enable = yes
+#broken_sasl_auth_clients = yes
+#smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, check_relay_domains
+#smtpd_etrn_restrictions = permit_mynetworks, reject
+
+# Virtual users
+virtual_maps = hash:/etc/postfix/virtual
+virtual_alias_maps = ldap:vlocal, ldap:vforward
+
+# Delivery for Local, Local/Forward and Alias
+vlocal_server_host = localhost
+vlocal_search_base = dc=example,dc=com
+vlocal_query_filter = (&(objectClass=gosaMailAccount)(gosaMailDeliveryMode=[*L*])(|(mail=%s)(gosaMailAlternateAddress=%s)))
+vlocal_result_attribute = uid,gosaMailForwardingAddress,memberUid
+
+# Delivery when Forward only
+vforward_server_host = localhost
+vforward_search_base = dc=example,dc=com
+vforward_query_filter = (&(objectClass=gosaMailAccount)(!(gosaMailDeliveryMode=[*L*]))(|(mail=%s)(gosaMailAlternateAddress=%s)))
+vforward_result_attribute = gosaMailForwardingAddress
+
diff --git a/gosa-core/contrib/altlinux/etc/samba/smb.conf b/gosa-core/contrib/altlinux/etc/samba/smb.conf
new file mode 100644 (file)
index 0000000..6910adb
--- /dev/null
@@ -0,0 +1,73 @@
+#======================= Global Settings =====================================
+[global]
+       ldap server = localhost
+       ldap port = 389
+       ldap suffix = dc=example,dc=com
+       ldap admin dn = cn=smbpasswd,ou=Apps,dc=example,dc=com
+       
+       ldap user suffix = ou=People
+       ldap group suffix = ou=Groups
+       ldap machine suffix = ou=Computers
+       ldap passwd sync = Yes
+
+       workgroup = EXAMPLE
+       netbios name = PDC
+       server string =  Samba server on %h (v. %v)
+       #realm = PDC.EXAMPLE.TLD
+       announce version = 4.8
+       time server = Yes
+
+       log file = /var/log/samba/log.%m
+       max log size = 50
+
+       security = user
+       hosts allow = 192.168.1. 127.
+       encrypt passwords = yes
+       null passwords = No
+       min passwd length = 6
+       smb passwd file = /etc/samba/smbpasswd
+       socket options = TCP_NODELAY
+       os level = 254
+       nt acl support = No
+       passdb backend = ldapsam:ldap://localhost
+
+       domain master = yes 
+       preferred master = yes
+       domain logons = yes
+       dns proxy = no 
+
+       #dos charset = CP866
+       #unix charset = KOI8-R
+       #display charset = KOI8-R
+       use sendfile = yes
+       preserve case = Yes
+       short preserve case = Yes
+       case sensitive = Yes
+       hide dot files = Yes
+
+#============================ Share Definitions ==============================
+[homes]
+   comment = Home Directory for '%u'
+   browseable = no
+   writable = yes
+
+# Un-comment the following and create the netlogon directory for Domain Logons
+[netlogon]
+   comment = Network Logon Service
+   path = /var/lib/samba/netlogon
+   guest ok = yes
+   browsable = no
+   writable = no
+
+#Uncomment the following 2 lines if you would like your login scripts to
+#be created dynamically by ntlogon (check that you have it in the correct
+#location (the default of the ntlogon rpm available in contribs)
+;root preexec = /usr/bin/ntlogon -u %U -g %G -o %a -d /var/lib/samba/netlogon
+;root postexec = rm -f /var/lib/samba/netlogon/%U.bat
+
+# Un-comment the following to provide a specific roving profile share
+# the default is to use the user's home directory
+;[Profiles]
+;    path = /var/lib/samba/profiles
+;    browseable = no
+;    guest ok = yes
diff --git a/gosa-core/contrib/altlinux/etc/sasl2/imapd.conf b/gosa-core/contrib/altlinux/etc/sasl2/imapd.conf
new file mode 100644 (file)
index 0000000..993c2b0
--- /dev/null
@@ -0,0 +1,2 @@
+pwcheck_method: saslauthd
+mech_list: login plain
diff --git a/gosa-core/contrib/altlinux/etc/sasl2/saslauthd.conf b/gosa-core/contrib/altlinux/etc/sasl2/saslauthd.conf
new file mode 100644 (file)
index 0000000..f713903
--- /dev/null
@@ -0,0 +1,74 @@
+ldap_servers: ldap://localhost/
+ldap_bind_dn: cn=saslauthd,ou=Apps,dc=example,dc=com
+ldap_bind_pw: saslauthd
+ldap_version: 3
+# <2|3>
+#      Specify the LDAP protocol version to use.
+
+ldap_timeout: 5
+#      Specify a number of seconds a search can take before timing out.
+
+ldap_time_limit: 5
+#      Specify a number of seconds for a search request to complete.
+
+#ldap_deref: <none> <search|find|always|never>
+#      Specify how aliases dereferencing is handled during a search.
+
+#ldap_referrals: <no>
+#      Specify whether or not the client should follow referrals.
+
+#ldap_restart: <yes>
+#      Specify whether or not LDAP I/O operations are automatically restarted
+#      if they abort prematurely.
+
+#ldap_cache_ttl: <0>
+#      Non zero enables client side caching.  Cached results will expire after
+#      specified number seconds, e.g. 30.  Use this option with care.
+#      OpenLDAP folks consider this feature experimental.
+
+#ldap_cache_mem: <0>
+#      If client side caching is enabled, the value specifies the cache size
+#      in bytes,  e.g. 32768.
+       
+#ldap_scope: <sub> <sub|one|base>
+#      Search scope.
+
+ldap_search_base: dc=iph,dc=ras,dc=ru
+#      Specify a starting point for the search.  e.g. dc=foo,dc=com
+
+#ldap_auth_method: <bind> <bind|custom>
+#      Specify an authentication method.  The default 'bind' method uses the
+#      LDAP simple bind facility to verify the password.  The custom method
+#      uses userPassword attribute to verify the password.  Currently, {CRYPT}
+#      hash is supported.
+
+ldap_filter: (|(uid=%u)(cn=%u))
+#      Specify a filter.  Use the %u and %r tokens for the username and realm
+#      substitution.  The %u token has to be used at minimum for the filter to
+#      be useful.  If ldap_auth_method is 'bind', the filter will search for
+#      the DN (distinguished name) attribute.  Otherwise, the search will look
+#      for the userPassword attribute.
+
+#ldap_debug: <0>
+#      Specify a debugging level in the OpenLDAP libraries.  See
+#      ldap_set_option(3) for more (LDAP_OPT_DEBUG_LEVEL).
+#
+#ldap_tls_check_peer: <no> <yes|no>
+#      Require and verify server certificate.  If this option is yes,
+#      you must specify ldap_tls_cacert_file or ldap_tls_cacert_dir.
+
+#ldap_tls_cacert_file: <none>
+#      File containing CA (Certificate Authority) certificate(s).
+
+#ldap_tls_cacert_dir: <none>
+#      Path to directory with CA (Certificate Authority) certificates.
+
+#ldap_tls_ciphers: <DEFAULT>
+#      List of SSL/TLS ciphers to allow.  The format of the string is
+#      described in ciphers(1).
+
+#ldap_tls_cert: <none>
+#      File containing the client certificate.
+
+#ldap_tls_key: <none>
+#      File containing the private client key.
diff --git a/gosa-core/contrib/altlinux/etc/services b/gosa-core/contrib/altlinux/etc/services
new file mode 100644 (file)
index 0000000..9251a48
--- /dev/null
@@ -0,0 +1,557 @@
+# /etc/services:
+# $Id: services,v 1.1 2004/12/08 07:22:10 migor-guest Exp $
+#
+# Network services, Internet style
+#
+# Note that it is presently the policy of IANA to assign a single well-known
+# port number for both TCP and UDP; hence, most entries here have two entries
+# even if the protocol doesn't support UDP operations.
+# Updated from RFC 1700, ``Assigned Numbers'' (October 1994).  Not all ports
+# are included, only the more common ones.
+#
+# The latest IANA port assignments can be gotten from
+#      http://www.iana.org/assignments/port-numbers
+# The Well Known Ports are those from 0 through 1023.
+# The Registered Ports are those from 1024 through 49151
+# The Dynamic and/or Private Ports are those from 49152 through 65535
+#
+# Each line describes one service, and is of the form:
+# 
+# service-name  port/protocol  [aliases ...]   [# comment]
+
+tcpmux         1/tcp                           # TCP port service multiplexer
+tcpmux         1/udp                           # TCP port service multiplexer
+rje            5/tcp                           # Remote Job Entry
+rje            5/udp                           # Remote Job Entry
+echo           7/tcp
+echo           7/udp
+discard                9/tcp           sink null
+discard                9/udp           sink null
+systat         11/tcp          users           # Active Users
+systat         11/udp          users           # Active Users
+daytime                13/tcp
+daytime                13/udp
+qotd           17/tcp          quote           # Quote of the Day
+qotd           17/udp          quote           # Quote of the Day
+msp            18/tcp                          # Message Send Protocol
+msp            18/udp                          # Message Send Protocol
+chargen                19/tcp          ttytst source   # Character Generator
+chargen                19/udp          ttytst source   # Character Generator
+ftp-data       20/tcp                          # File Transfer [Default Data]
+ftp-data       20/udp                          # File Transfer [Default Data]
+# 21 is registered to ftp, but also used by fsp
+ftp            21/tcp                          # File Transfer [Control]
+ftp            21/udp          fsp fspd        # File Transfer [Control]
+ssh            22/tcp                          # SSH Remote Login Protocol
+ssh            22/udp                          # SSH Remote Login Protocol
+telnet         23/tcp
+telnet         23/udp
+# 24 - private mail system
+smtp           25/tcp          mail            # Simple Mail Transfer Protocol
+smtp           25/udp          mail            # Simple Mail Transfer Protocol
+time           37/tcp          timserver
+time           37/udp          timserver
+rlp            39/tcp          resource        # Resource Location Protocol
+rlp            39/udp          resource        # Resource Location Protocol
+nameserver     42/tcp          name            # Host Name Server
+nameserver     42/udp          name            # Host Name Server
+nicname                43/tcp          whois
+nicname                43/udp          whois
+tacacs         49/tcp                          # Login Host Protocol (TACACS)
+tacacs         49/udp                          # Login Host Protocol (TACACS)
+re-mail-ck     50/tcp                          # Remote Mail Checking Protocol
+re-mail-ck     50/udp                          # Remote Mail Checking Protocol
+domain         53/tcp                          # Domain Name Server
+domain         53/udp                          # Domain Name Server
+whois++                63/tcp
+whois++                63/udp
+bootps         67/tcp                          # BOOTP server
+bootps         67/udp
+bootpc         68/tcp                          # BOOTP client
+bootpc         68/udp
+tftp           69/tcp                          # Trivial File Transfer
+tftp           69/udp                          # Trivial File Transfer
+gopher         70/tcp                          # Internet Gopher
+gopher         70/udp
+netrjs-1       71/tcp                          # Remote Job Service
+netrjs-1       71/udp                          # Remote Job Service
+netrjs-2       72/tcp                          # Remote Job Service
+netrjs-2       72/udp                          # Remote Job Service
+netrjs-3       73/tcp                          # Remote Job Service
+netrjs-3       73/udp                          # Remote Job Service
+netrjs-4       74/tcp                          # Remote Job Service
+netrjs-4       74/udp                          # Remote Job Service
+finger         79/tcp
+finger         79/udp
+http           80/tcp          www www-http    # World Wide Web HTTP
+http           80/udp          www www-http    # HyperText Transfer Protocol
+kerberos       88/tcp          kerberos5 krb5  # Kerberos v5
+kerberos       88/udp          kerberos5 krb5  # Kerberos v5
+supdup         95/tcp
+supdup         95/udp
+hostname       101/tcp         hostnames       # usually from sri-nic
+hostname       101/udp         hostnames       # usually from sri-nic
+iso-tsap       102/tcp         tsap            # part of ISODE.
+csnet-ns       105/tcp         cso             # also used by CSO name server
+csnet-ns       105/udp         cso
+# unfortunately the poppassd (Eudora) uses a port which has already
+# been assigned to a different service. We list the poppassd as an
+# alias here. This should work for programs asking for this service.
+# (due to a bug in inetd the 3com-tsmux line is disabled)
+#3com-tsmux    106/tcp         poppassd
+#3com-tsmux    106/udp         poppassd
+rtelnet                107/tcp                         # Remote Telnet
+rtelnet                107/udp
+pop2           109/tcp         pop-2   postoffice      # POP version 2
+pop2           109/udp         pop-2
+pop3           110/tcp         pop-3           # POP version 3
+pop3           110/udp         pop-3
+sunrpc         111/tcp         portmapper      # RPC 4.0 portmapper TCP
+sunrpc         111/udp         portmapper      # RPC 4.0 portmapper UDP
+auth           113/tcp         authentication tap ident
+auth           113/udp         authentication tap ident
+sftp           115/tcp
+sftp           115/udp
+uucp-path      117/tcp
+uucp-path      117/udp
+nntp           119/tcp         readnews untp   # USENET News Transfer Protocol
+nntp           119/udp         readnews untp   # USENET News Transfer Protocol
+ntp            123/tcp
+ntp            123/udp                         # Network Time Protocol
+pwdgen         129/tcp                         # Password Generator Protocol
+pwdgen         129/udp                         # Password Generator Protocol
+netbios-ns     137/tcp                         # NETBIOS Name Service
+netbios-ns     137/udp
+netbios-dgm    138/tcp                         # NETBIOS Datagram Service
+netbios-dgm    138/udp
+netbios-ssn    139/tcp                         # NETBIOS session service
+netbios-ssn    139/udp
+imap           143/tcp         imap2           # Interim Mail Access Proto v2
+imap           143/udp         imap2
+snmp           161/tcp                         # Simple Net Mgmt Proto
+snmp           161/udp                         # Simple Net Mgmt Proto
+snmptrap       162/udp         snmp-trap       # Traps for SNMP
+cmip-man       163/tcp                         # ISO mgmt over IP (CMOT)
+cmip-man       163/udp
+cmip-agent     164/tcp
+cmip-agent     164/udp
+mailq          174/tcp                         # MAILQ
+mailq          174/udp                         # MAILQ
+xdmcp          177/tcp                         # X Display Mgr. Control Proto
+xdmcp          177/udp
+nextstep       178/tcp         NeXTStep NextStep       # NeXTStep window
+nextstep       178/udp         NeXTStep NextStep       # server
+bgp            179/tcp                         # Border Gateway Proto.
+bgp            179/udp
+prospero       191/tcp                         # Cliff Neuman's Prospero
+prospero       191/udp
+irc            194/tcp                         # Internet Relay Chat
+irc            194/udp
+smux           199/tcp                         # SNMP Unix Multiplexer
+smux           199/udp
+at-rtmp                201/tcp                         # AppleTalk routing
+at-rtmp                201/udp
+at-nbp         202/tcp                         # AppleTalk name binding
+at-nbp         202/udp
+at-echo                204/tcp                         # AppleTalk echo
+at-echo                204/udp
+at-zis         206/tcp                         # AppleTalk zone information
+at-zis         206/udp
+qmtp           209/tcp                         # Quick Mail Transfer Protocol
+qmtp           209/udp                         # Quick Mail Transfer Protocol
+z39.50         210/tcp         z3950 wais      # NISO Z39.50 database 
+z39.50         210/udp         z3950 wais
+ipx            213/tcp                         # IPX
+ipx            213/udp
+imap3          220/tcp                         # Interactive Mail Access
+imap3          220/udp                         # Protocol v3
+link           245/tcp         ttylink
+link           245/ucp         ttylink
+fatserv                347/tcp                         # Fatmen Server
+fatserv                347/udp                         # Fatmen Server
+rsvp_tunnel    363/tcp
+rsvp_tunnel    363/udp
+rpc2portmap    369/tcp
+rpc2portmap    369/udp                         # Coda portmapper
+codaauth2      370/tcp
+codaauth2      370/udp                         # Coda authentication server
+ulistproc      372/tcp         ulistserv       # UNIX Listserv
+ulistproc      372/udp         ulistserv
+ldap           389/tcp
+ldap           389/udp
+svrloc          427/tcp                                # Server Location Protocl
+svrloc          427/udp                                # Server Location Protocl
+mobileip-agent 434/tcp
+mobileip-agent 434/udp
+mobilip-mn     435/tcp
+mobilip-mn     435/udp
+https          443/tcp                         # MCom
+https          443/udp                         # MCom
+snpp           444/tcp                         # Simple Network Paging Protocol
+snpp           444/udp                         # Simple Network Paging Protocol
+microsoft-ds   445/tcp
+microsoft-ds   445/udp
+kpasswd                464/tcp         kpwd            # Kerberos "passwd"
+kpasswd                464/udp         kpwd            # Kerberos "passwd"
+photuris       468/tcp
+photuris       468/udp
+saft           487/tcp                         # Simple Asynchronous File Transfer
+saft           487/udp                         # Simple Asynchronous File Transfer
+gss-http       488/tcp
+gss-http       488/udp
+pim-rp-disc    496/tcp
+pim-rp-disc    496/udp
+isakmp         500/tcp
+isakmp         500/udp
+gdomap         538/tcp                         # GNUstep distributed objects
+gdomap         538/udp                         # GNUstep distributed objects
+iiop           535/tcp
+iiop           535/udp
+dhcpv6-client  546/tcp
+dhcpv6-client  546/udp
+dhcpv6-server  547/tcp
+dhcpv6-server  547/udp
+rtsp           554/tcp                         # Real Time Stream Control Protocol
+rtsp           554/udp                         # Real Time Stream Control Protocol
+nntps          563/tcp                         # NNTP over SSL
+nntps          563/udp                         # NNTP over SSL
+whoami         565/tcp
+whoami         565/udp
+submission     587/tcp         msa             # mail message submission
+submission     587/udp         msa             # mail message submission
+npmp-local     610/tcp         dqs313_qmaster  # npmp-local / DQS
+npmp-local     610/udp         dqs313_qmaster  # npmp-local / DQS
+npmp-gui       611/tcp         dqs313_execd    # npmp-gui / DQS
+npmp-gui       611/udp         dqs313_execd    # npmp-gui / DQS
+hmmp-ind       612/tcp         dqs313_intercell # HMMP Indication / DQS
+hmmp-ind       612/udp         dqs313_intercell # HMMP Indication / DQS
+ipp            631/tcp                         # Internet Printing Protocol
+ipp            631/ucp                         # Internet Printing Protocol
+ldaps          636/tcp                         # LDAP over SSL
+ldaps          636/udp                         # LDAP over SSL
+acap           674/tcp
+acap           674/udp
+ha-cluster     694/tcp                         # Heartbeat HA-cluster
+ha-cluster     694/udp                         # Heartbeat HA-cluster
+kerberos-adm   749/tcp                         # Kerberos `kadmin' (v5)
+kerberos-iv    750/udp         kerberos4 kerberos-sec kdc
+kerberos-iv    750/tcp         kerberos4 kerberos-sec kdc
+webster                765/tcp                         # Network dictionary
+webster                765/udp
+phonebook      767/tcp                         # Network phonebook
+phonebook      767/udp
+rsync          873/tcp                         # rsync
+rsync          873/udp                         # rsync
+telnets                992/tcp
+telnets                992/udp
+imaps          993/tcp                         # IMAP over SSL
+imaps          993/udp                         # IMAP over SSL
+ircs           994/tcp
+ircs           994/udp
+pop3s          995/tcp                         # POP-3 over SSL
+pop3s          995/udp                         # POP-3 over SSL
+
+#
+# UNIX specific services
+#
+exec           512/tcp
+biff           512/udp         comsat
+login          513/tcp
+who            513/udp         whod
+shell          514/tcp         cmd             # no passwords used
+syslog         514/udp
+printer                515/tcp         spooler         # line printer spooler
+printer                515/udp         spooler         # line printer spooler
+talk           517/udp
+ntalk          518/udp
+utime          519/tcp         unixtime
+utime          519/udp         unixtime
+efs            520/tcp
+router         520/udp         route routed    # RIP
+ripng          521/tcp
+ripng          521/udp
+timed          525/tcp         timeserver
+timed          525/udp         timeserver
+tempo          526/tcp         newdate
+courier                530/tcp         rpc
+conference     531/tcp         chat
+netnews                532/tcp
+netwall                533/udp                         # -for emergency broadcasts
+uucp           540/tcp         uucpd           # uucp daemon
+klogin         543/tcp                         # Kerberized `rlogin' (v5)
+kshell         544/tcp         krcmd           # Kerberized `rsh' (v5)
+afpovertcp     548/tcp                         # AFP over TCP
+afpovertcp     548/udp                         # AFP over TCP
+remotefs       556/tcp         rfs_server rfs  # Brunhoff remote filesystem
+
+#
+# From ``PORT NUMBERS'':
+#
+#>REGISTERED PORT NUMBERS
+#>
+#>The Registered Ports are listed by the IANA and on most systems can be
+#>used by ordinary user processes or programs executed by ordinary
+#>users.
+#>
+#>Ports are used in the TCP [RFC793] to name the ends of logical
+#>connections which carry long term conversations.  For the purpose of
+#>providing services to unknown callers, a service contact port is
+#>defined.  This list specifies the port used by the server process as
+#>its contact port.
+#>
+#>The IANA registers uses of these ports as a convienence to the
+#>community.
+#
+socks          1080/tcp                        # socks proxy server
+socks          1080/udp                        # socks proxy server
+h323hostcallsc 1300/tcp                        # H323 Host Call Secure
+h323hostcallsc 1300/udp                        # H323 Host Call Secure
+ms-sql-s       1433/tcp                        # Microsoft-SQL-Server 
+ms-sql-s       1433/udp                        # Microsoft-SQL-Server 
+ms-sql-m       1434/tcp                        # Microsoft-SQL-Monitor
+ms-sql-m       1434/udp                        # Microsoft-SQL-Monitor          
+ica            1494/tcp                        # Citrix ICA Client
+ica            1494/udp                        # Citrix ICA Client
+wins           1512/tcp                        # Microsoft's Windows Internet Name Service
+wins           1512/udp                        # Microsoft's Windows Internet Name Service
+ingreslock     1524/tcp
+ingreslock     1524/udp
+prospero-np    1525/tcp                        # Prospero non-privileged
+prospero-np    1525/udp
+datametrics    1645/tcp        old-radius      # datametrics / old radius entry
+datametrics    1645/udp        old-radius      # datametrics / old radius entry
+sa-msg-port    1646/tcp        old-radacct     # sa-msg-port / old radacct entry
+sa-msg-port    1646/udp        old-radacct     # sa-msg-port / old radacct entry
+kermit         1649/tcp
+kermit         1649/udp
+l2tp           1701/tcp        l2f
+l2tp           1701/udp        l2f
+h323gatedisc   1718/tcp
+h323gatedisc   1718/udp
+h323gatestat   1719/tcp
+h323gatestat   1719/udp
+h323hostcall   1720/tcp
+h323hostcall   1720/udp
+tftp-mcast     1758/tcp
+tftp-mcast     1758/udp
+hello          1789/tcp
+hello          1789/udp
+radius         1812/tcp                        # Radius
+radius         1812/udp                        # Radius
+radius-acct    1813/tcp        radacct         # Radius Accounting
+radius-acct    1813/udp        radacct         # Radius Accounting
+mtp            1911/tcp                        #
+mtp            1911/udp                        #
+hsrp           1985/tcp                        # Cisco Hot Standby Router Protocol
+hsrp           1985/udp                        # Cisco Hot Standby Router Protocol
+licensedaemon  1986/tcp
+licensedaemon  1986/udp
+gdp-port       1997/tcp                        # Cisco Gateway Discovery Protocol
+gdp-port       1997/udp                        # Cisco Gateway Discovery Protocol
+nfs            2049/tcp        nfsd
+nfs            2049/udp        nfsd
+zephyr-srv     2102/tcp                        # Zephyr server
+zephyr-srv     2102/udp                        # Zephyr server
+zephyr-clt     2103/tcp                        # Zephyr serv-hm connection
+zephyr-clt     2103/udp                        # Zephyr serv-hm connection
+zephyr-hm      2104/tcp                        # Zephyr hostmanager
+zephyr-hm      2104/udp                        # Zephyr hostmanager
+cvspserver     2401/tcp                        # CVS client/server operations
+cvspserver     2401/udp                        # CVS client/server operations
+venus          2430/tcp                        # codacon port
+venus          2430/udp                        # Venus callback/wbc interface
+venus-se       2431/tcp                        # tcp side effects
+venus-se       2431/udp                        # udp sftp side effect
+codasrv                2432/tcp                        # not used
+codasrv                2432/udp                        # server port
+codasrv-se     2433/tcp                        # tcp side effects
+codasrv-se     2433/udp                        # udp sftp side effectQ
+
+# Ports numbered 2600 through 2606 are used by the zebra package.  The primary
+# names are the registered names, and the zebra names are listed as aliases.
+hpstgmgr       2600/tcp        zebrasrv        # HPSTGMGR
+hpstgmgr       2600/udp                        # HPSTGMGR
+discp-client   2601/tcp        zebra           # discp client
+discp-client   2601/udp                        # discp client
+discp-server   2602/tcp        ripd            # discp server
+discp-server   2602/udp                        # discp server
+servicemeter   2603/tcp        ripngd          # Service Meter
+servicemeter   2603/udp                        # Service Meter
+nsc-ccs                2604/tcp        ospfd           # NSC CCS
+nsc-ccs                2604/udp                        # NSC CCS
+nsc-posa       2605/tcp        bgpd            # NSC POSA
+nsc-posa       2605/udp                        # NSC POSA
+netmon         2606/tcp        ospf6d          # Dell Netmon
+netmon         2606/udp                        # Dell Netmon
+
+corbaloc       2809/tcp                        # CORBA naming service locator
+icpv2          3130/tcp                        # Internet Cache Protocol V2 (Squid)
+icpv2          3130/udp                        # Internet Cache Protocol V2 (Squid)
+mysql          3306/tcp                        # MySQL
+mysql          3306/udp                        # MySQL
+trnsprntproxy   3346/tcp                       # Trnsprnt Proxy
+trnsprntproxy   3346/udp                       # Trnsprnt Proxy
+rwhois         4321/tcp                        # Remote Who Is
+rwhois         4321/udp                        # Remote Who Is
+krb524         4444/tcp                        # Kerberos 5 to 4 ticket xlator
+krb524         4444/udp                        # Kerberos 5 to 4 ticket xlator
+rfe            5002/tcp                        # Radio Free Ethernet
+rfe            5002/udp                        # Actually uses UDP only
+jabber-client  5222/tcp                        # Jabber Client Connection
+jabber-client  5222/udp                        # Jabber Client Connection
+jabber-server  5269/tcp                        # Jabber Server Connection
+jabber-server  5269/udp                        # Jabber Server Connection
+cfengine       5308/tcp                        # CFengine
+cfengine       5308/udp                        # CFengine
+cvsup           5999/tcp       CVSup           # CVSup file transfer/John Polstra/FreeBSD
+cvsup           5999/udp       CVSup           # CVSup file transfer/John Polstra/FreeBSD
+x11            6000/tcp        X               # the X Window System
+afs3-fileserver 7000/tcp                       # file server itself
+afs3-fileserver 7000/udp                       # file server itself
+afs3-callback   7001/tcp                       # callbacks to cache managers
+afs3-callback   7001/udp                       # callbacks to cache managers
+afs3-prserver   7002/tcp                       # users & groups database
+afs3-prserver   7002/udp                       # users & groups database
+afs3-vlserver   7003/tcp                       # volume location database
+afs3-vlserver   7003/udp                       # volume location database
+afs3-kaserver   7004/tcp                       # AFS/Kerberos authentication service
+afs3-kaserver   7004/udp                       # AFS/Kerberos authentication service
+afs3-volser     7005/tcp                       # volume managment server
+afs3-volser     7005/udp                       # volume managment server
+afs3-errors     7006/tcp                       # error interpretation service
+afs3-errors     7006/udp                       # error interpretation service
+afs3-bos        7007/tcp                       # basic overseer process
+afs3-bos        7007/udp                       # basic overseer process
+afs3-update     7008/tcp                       # server-to-server updater
+afs3-update     7008/udp                       # server-to-server updater
+afs3-rmtsys     7009/tcp                       # remote cache manager service
+afs3-rmtsys     7009/udp                       # remote cache manager service
+sd             9876/tcp                        # Session Director
+sd             9876/udp                        # Session Director
+amanda         10080/tcp                       # amanda backup services
+amanda         10080/udp                       # amanda backup services
+pgpkeyserver   11371/tcp                       # PGP/GPG public keyserver
+pgpkeyserver   11371/udp                       # PGP/GPG public keyserver
+h323callsigalt 11720/tcp                       # H323 Call Signal Alternate
+h323callsigalt 11720/udp                       # H323 Call Signal Alternate
+
+# This port is registered as wnn6, but also used under the name "wnn4" by the
+# FreeWnn package.
+wnn6           22273/tcp       wnn4
+wnn6           22273/ucp       wnn4
+
+quake          26000/tcp
+quake          26000/udp
+wnn6-ds                26208/tcp
+wnn6-ds                26208/udp
+traceroute     33434/tcp
+traceroute     33434/udp
+
+#
+# Datagram Delivery Protocol services
+#
+rtmp           1/ddp                           # Routing Table Maintenance Protocol
+nbp            2/ddp                           # Name Binding Protocol
+echo           4/ddp                           # AppleTalk Echo Protocol
+zip            6/ddp                           # Zone Information Protocol
+
+#
+# Kerberos (Project Athena/MIT) services
+# Note that these are for Kerberos v4, and are unofficial.  Sites running
+# v4 should uncomment these and comment out the v5 entries above.
+#
+kerberos_master        751/udp                         # Kerberos authentication
+kerberos_master        751/tcp                         # Kerberos authentication
+passwd_server  752/udp                         # Kerberos passwd server
+krbupdate      760/tcp         kreg            # Kerberos registration
+kpop           1109/tcp                        # Pop with Kerberos
+knetd          2053/tcp                        # Kerberos de-multiplexor
+
+#
+# Kerberos 5 services, also not registered with IANA
+#
+krb5_prop      754/tcp                         # Kerberos slave propagation
+eklogin                2105/tcp                        # Kerberos encrypted rlogin
+
+#
+# Unregistered but necessary (for NetBSD) services
+#
+supfilesrv     871/tcp                         # SUP server
+supfiledbg     1127/tcp                        # SUP debugging
+
+#
+# Unregistered but useful/necessary other services
+#
+netstat                15/tcp                          # (was once asssigned, no more)
+linuxconf      98/tcp                          # Linuxconf HTML access
+poppassd       106/tcp                         # Eudora
+poppassd       106/udp                         # Eudora
+smtps          465/tcp                         # SMTP over SSL (TLS)
+gii            616/tcp                         # gated interactive interface
+omirr          808/tcp         omirrd          # online mirror
+omirr          808/udp         omirrd          # online mirror
+swat           901/tcp                         # Samba Web Administration Tool
+rndc           953/tcp                         # rndc control sockets (BIND 9)
+rndc           953/udp                         # rndc control sockets (BIND 9)
+skkserv                1178/tcp                        # SKK Japanese input method
+rmtcfg         1236/tcp                        # Gracilis Packeten remote config server
+xtel           1313/tcp                        # french minitel
+lotusnote      1352/tcp        lotusnotes      # Lotus notes
+lotusnote      1352/udp        lotusnotes      # Lotus notes
+support                1529/tcp        prmsd gnatsd    # GNATS, cygnus bug tracker
+cfinger                2003/tcp                        # GNU Finger
+ninstall       2150/tcp                        # ninstall service
+ninstall       2150/udp                        # ninstall service
+afbackup       2988/tcp                        # Afbackup system
+afbackup       2988/udp                        # Afbackup system
+squid          3128/tcp                        # squid web proxy
+prsvp          3455/tcp                        # RSVP Port
+prsvp          3455/udp                        # RSVP Port
+postgres       5432/tcp                        # POSTGRES
+postgres       5432/udp                        # POSTGRES
+fax            4557/tcp                        # FAX transmission service        (old)
+hylafax                4559/tcp                        # HylaFAX client-server protocol  (new)
+sgi-dgl                5232/tcp                        # SGI Distributed Graphics
+sgi-dgl                5232/udp
+noclog         5354/tcp                        # noclogd with TCP (nocol)
+noclog         5354/udp                        # noclogd with UDP (nocol)
+hostmon                5355/tcp                        # hostmon uses TCP (nocol)
+hostmon                5355/udp                        # hostmon uses TCP (nocol)
+canna          5680/tcp
+x11-ssh-offset 6010/tcp                        # SSH X11 forwarding offset
+ircd           6667/tcp                        # Internet Relay Chat
+ircd           6667/udp                        # Internet Relay Chat
+xfs            7100/tcp                        # X font server
+tircproxy      7666/tcp                        # Tircproxy
+http-alt       8008/tcp
+http-alt       8008/udp
+webcache       8080/tcp                        # WWW caching service
+webcache       8080/udp                        # WWW caching service
+tproxy         8081/tcp                        # Transparent Proxy
+tproxy         8081/udp                        # Transparent Proxy
+jetdirect      9100/tcp        laserjet hplj   #
+mandelspawn    9359/udp        mandelbrot      # network mandelbrot
+kamanda                10081/tcp                       # amanda backup services (Kerberos)
+kamanda                10081/udp                       # amanda backup services (Kerberos)
+amandaidx      10082/tcp                       # amanda backup services
+amidxtape      10083/tcp                       # amanda backup services
+ladcca         14541/tcp                       # LADCCA client/server protocol
+isdnlog                20011/tcp                       # isdn logging system
+isdnlog                20011/udp                       # isdn logging system
+vboxd          20012/tcp                       # voice box system
+vboxd          20012/udp                       # voice box system
+wnn4_Kr                22305/tcp                       # used by the kWnn package
+wnn4_Cn                22289/tcp                       # used by the cWnn package
+wnn4_Tw                22321/tcp                       # used by the tWnn package
+binkp          24554/tcp                       # Binkley
+binkp          24554/udp                       # Binkley
+asp            27374/tcp                       # Address Search Protocol
+asp            27374/udp                       # Address Search Protocol
+tfido          60177/tcp                       # Ifmail
+tfido          60177/udp                       # Ifmail
+fido           60179/tcp                       # Ifmail
+fido           60179/udp                       # Ifmail
+
+# Cyrus SIEVE service
+sieve          2000/tcp
+sieve          2000/udp
diff --git a/gosa-core/contrib/altlinux/etc/squid/squid.conf b/gosa-core/contrib/altlinux/etc/squid/squid.conf
new file mode 100644 (file)
index 0000000..5d2459b
--- /dev/null
@@ -0,0 +1,3303 @@
+
+#      WELCOME TO SQUID 2
+#      ------------------
+#
+#      This is the default Squid configuration file. You may wish
+#      to look at the Squid home page (http://www.squid-cache.org/)
+#      for the FAQ and other documentation.
+#
+#      The default Squid config file shows what the defaults for
+#      various options happen to be.  If you don't need to change the
+#      default, you shouldn't uncomment the line.  Doing so may cause
+#      run-time problems.  In some cases "none" refers to no default
+#      setting at all, while in other cases it refers to a valid
+#      option - the comments for that keyword indicate if this is the
+#      case.
+#
+
+
+# NETWORK OPTIONS
+# -----------------------------------------------------------------------------
+
+#  TAG: http_port
+#      Usage:  port
+#              hostname:port
+#              1.2.3.4:port
+#
+#      The socket addresses where Squid will listen for HTTP client
+#      requests.  You may specify multiple socket addresses.
+#      There are three forms: port alone, hostname with port, and
+#      IP address with port.  If you specify a hostname or IP
+#      address, then Squid binds the socket to that specific
+#      address.  This replaces the old 'tcp_incoming_address'
+#      option.  Most likely, you do not need to bind to a specific
+#      address, so you can use the port number alone.
+#
+#      The default port number is 3128.
+#
+#      If you are running Squid in accelerator mode, then you
+#      probably want to listen on port 80 also, or instead.
+#
+#      The -a command line option will override the *first* port
+#      number listed here.   That option will NOT override an IP
+#      address, however.
+#
+#      You may specify multiple socket addresses on multiple lines.
+#
+#      If you run Squid on a dual-homed machine with an internal
+#      and an external interface then we recommend you to specify the
+#      internal address:port in http_port. This way Squid will only be
+#      visible on the internal address.
+#
+#Default:
+# http_port 3128
+
+#  TAG: https_port
+#        Usage:  [ip:]port cert=certificate.pem [key=key.pem] [options...]
+#
+#        The socket address where Squid will listen for HTTPS client
+#        requests.
+#
+#        This is really only useful for situations where you are running
+#        squid in accelerator mode and you want to do the SSL work at the
+#        accelerator level.
+#
+#      You may specify multiple socket addresses on multiple lines,
+#      each with their own SSL certificate and/or options.
+#                            
+#      Options:
+#
+#         cert=        Path to SSL certificate (PEM format)
+#              
+#         key=         Path to SSL private key file (PEM format)
+#                      if not specified, the certificate file is
+#                      assumed to be a combined certificate and
+#                      key file
+#
+#         version=     The version of SSL/TLS supported
+#                          1   automatic (default)
+#                          2   SSLv2 only
+#                          3   SSLv3 only
+#                          4   TLSv1 only
+#
+#         cipher=      Colon separated list of supported ciphers
+#
+#         options=     Varions SSL engine options. The most important
+#                      being:
+#                          NO_SSLv2  Disallow the use of SSLv2
+#                          NO_SSLv3  Disallow the use of SSLv3
+#                          NO_TLSv1  Disallow the use of TLSv1
+#                      See src/ssl_support.c or OpenSSL documentation
+#                      for a more complete list.
+#
+#Default:
+# none
+
+#  TAG: ssl_unclean_shutdown
+#      Some browsers (especially MSIE) bugs out on SSL shutdown
+#      messages.
+#
+#Default:
+# ssl_unclean_shutdown off
+
+#  TAG: icp_port
+#      The port number where Squid sends and receives ICP queries to
+#      and from neighbor caches.  Default is 3130.  To disable use
+#      "0".  May be overridden with -u on the command line.
+#
+#Default:
+# icp_port 3130
+
+#  TAG: htcp_port
+# Note: This option is only available if Squid is rebuilt with the
+#       --enable-htcp option
+#
+#      The port number where Squid sends and receives HTCP queries to
+#      and from neighbor caches.  Default is 4827.  To disable use
+#      "0".
+#
+#Default:
+# htcp_port 4827
+
+#  TAG: mcast_groups
+#      This tag specifies a list of multicast groups which your server
+#      should join to receive multicasted ICP queries.
+#
+#      NOTE!  Be very careful what you put here!  Be sure you
+#      understand the difference between an ICP _query_ and an ICP
+#      _reply_.  This option is to be set only if you want to RECEIVE
+#      multicast queries.  Do NOT set this option to SEND multicast
+#      ICP (use cache_peer for that).  ICP replies are always sent via
+#      unicast, so this option does not affect whether or not you will
+#      receive replies from multicast group members.
+#
+#      You must be very careful to NOT use a multicast address which
+#      is already in use by another group of caches.
+#
+#      If you are unsure about multicast, please read the Multicast
+#      chapter in the Squid FAQ (http://www.squid-cache.org/FAQ/).
+#
+#      Usage: mcast_groups 239.128.16.128 224.0.1.20
+#
+#      By default, Squid doesn't listen on any multicast groups.
+#
+#Default:
+# none
+
+#  TAG: udp_incoming_address
+#  TAG: udp_outgoing_address
+#      udp_incoming_address    is used for the ICP socket receiving packets
+#                              from other caches.
+#      udp_outgoing_address    is used for ICP packets sent out to other
+#                              caches.
+#
+#      The default behavior is to not bind to any specific address.
+#
+#      A udp_incoming_address value of 0.0.0.0 indicates that Squid should
+#      listen for UDP messages on all available interfaces.
+#
+#      If udp_outgoing_address is set to 255.255.255.255 (the default)
+#      then it will use the same socket as udp_incoming_address. Only
+#      change this if you want to have ICP queries sent using another
+#      address than where this Squid listens for ICP queries from other
+#      caches.
+#
+#      NOTE, udp_incoming_address and udp_outgoing_address can not
+#      have the same value since they both use port 3130.
+#
+#Default:
+# udp_incoming_address 0.0.0.0
+# udp_outgoing_address 255.255.255.255
+
+
+# OPTIONS WHICH AFFECT THE NEIGHBOR SELECTION ALGORITHM
+# -----------------------------------------------------------------------------
+
+#  TAG: cache_peer
+#      To specify other caches in a hierarchy, use the format:
+#
+#              cache_peer hostname type http_port icp_port
+#
+#      For example,
+#
+#      #                                        proxy  icp
+#      #          hostname             type     port   port  options
+#      #          -------------------- -------- ----- -----  -----------
+#      cache_peer parent.foo.net       parent    3128  3130  [proxy-only]
+#      cache_peer sib1.foo.net         sibling   3128  3130  [proxy-only]
+#      cache_peer sib2.foo.net         sibling   3128  3130  [proxy-only]
+#
+#            type:  either 'parent', 'sibling', or 'multicast'.
+#
+#      proxy_port:  The port number where the cache listens for proxy
+#                   requests.
+#
+#        icp_port:  Used for querying neighbor caches about
+#                   objects.  To have a non-ICP neighbor
+#                   specify '7' for the ICP port and make sure the
+#                   neighbor machine has the UDP echo port
+#                   enabled in its /etc/inetd.conf file.
+#
+#          options: proxy-only
+#                   weight=n
+#                   ttl=n
+#                   no-query
+#                   default
+#                   round-robin
+#                   multicast-responder
+#                   closest-only
+#                   no-digest
+#                   no-netdb-exchange
+#                   no-delay
+#                   login=user:password | PASS | *:password
+#                   connect-timeout=nn
+#                   digest-url=url
+#                   allow-miss
+#                   max-conn
+#                   htcp
+#                   carp-load-factor
+#
+#                   use 'proxy-only' to specify that objects fetched
+#                   from this cache should not be saved locally.
+#
+#                   use 'weight=n' to specify a weighted parent.
+#                   The weight must be an integer.  The default weight
+#                   is 1, larger weights are favored more.
+#
+#                   use 'ttl=n' to specify a IP multicast TTL to use
+#                   when sending an ICP queries to this address.
+#                   Only useful when sending to a multicast group.
+#                   Because we don't accept ICP replies from random
+#                   hosts, you must configure other group members as
+#                   peers with the 'multicast-responder' option below.
+#
+#                   use 'no-query' to NOT send ICP queries to this
+#                   neighbor.
+#
+#                   use 'default' if this is a parent cache which can
+#                   be used as a "last-resort." You should probably
+#                   only use 'default' in situations where you cannot
+#                   use ICP with your parent cache(s).
+#
+#                   use 'round-robin' to define a set of parents which
+#                   should be used in a round-robin fashion in the
+#                   absence of any ICP queries.
+#
+#                   'multicast-responder' indicates that the named peer
+#                   is a member of a multicast group.  ICP queries will
+#                   not be sent directly to the peer, but ICP replies
+#                   will be accepted from it.
+#
+#                   'closest-only' indicates that, for ICP_OP_MISS
+#                   replies, we'll only forward CLOSEST_PARENT_MISSes
+#                   and never FIRST_PARENT_MISSes.
+#
+#                   use 'no-digest' to NOT request cache digests from
+#                   this neighbor.
+#
+#                   'no-netdb-exchange' disables requesting ICMP
+#                   RTT database (NetDB) from the neighbor.
+#
+#                   use 'no-delay' to prevent access to this neighbor
+#                   from influencing the delay pools.
+#
+#                   use 'login=user:password' if this is a personal/workgroup
+#                   proxy and your parent requires proxy authentication.
+#                   Note: The string can include URL escapes (i.e. %20 for
+#                   spaces). This also means that % must be written as %%.
+#
+#                   use 'login=PASS' if users must authenticate against
+#                   the upstream proxy. This will pass the users credentials
+#                   as they are to the peer proxy. This only works for the
+#                   Basic HTTP authentication sheme. Note: To combine this
+#                   with proxy_auth both proxies must share the same user
+#                   database as HTTP only allows for one proxy login.
+#                   Also be warned that this will expose your users proxy
+#                   password to the peer. USE WITH CAUTION
+#
+#                   use 'login=*:password' to pass the username to the
+#                   upstream cache, but with a fixed password. This is meant
+#                   to be used when the peer is in another administrative
+#                   domain, but it is still needed to identify each user.
+#                   The star can optionally be followed by some extra
+#                   information which is added to the username. This can
+#                   be used to identify this proxy to the peer, similar to
+#                   the login=username:password option above.
+#
+#                   use 'connect-timeout=nn' to specify a peer
+#                   specific connect timeout (also see the
+#                   peer_connect_timeout directive)
+#
+#                   use 'digest-url=url' to tell Squid to fetch the cache
+#                   digest (if digests are enabled) for this host from
+#                   the specified URL rather than the Squid default
+#                   location.
+#
+#                   use 'allow-miss' to disable Squid's use of only-if-cached
+#                   when forwarding requests to siblings. This is primarily
+#                   useful when icp_hit_stale is used by the sibling. To
+#                   extensive use of this option may result in forwarding
+#                   loops, and you should avoid having two-way peerings
+#                   with this option. (for example to deny peer usage on
+#                   requests from peer by denying cache_peer_access if the
+#                   source is a peer)
+#
+#                   use 'max-conn' to limit the amount of connections Squid
+#                   may open to this peer.
+#
+#                   use 'htcp' to send HTCP, instead of ICP, queries
+#                   to the neighbor.  You probably also want to
+#                   set the "icp port" to 4827 instead of 3130.
+#
+#                   use 'carp-load-factor=f' to define a parent
+#                   cache as one participating in a CARP array.
+#                   The 'f' values for all CARP parents must add
+#                   up to 1.0.
+#               
+#
+#      NOTE: non-ICP/HTCP neighbors must be specified as 'parent'.
+#
+#Default:
+# none
+
+#  TAG: cache_peer_domain
+#      Use to limit the domains for which a neighbor cache will be
+#      queried.  Usage:
+#
+#      cache_peer_domain cache-host domain [domain ...]
+#      cache_peer_domain cache-host !domain
+#
+#      For example, specifying
+#
+#              cache_peer_domain parent.foo.net        .edu
+#
+#      has the effect such that UDP query packets are sent to
+#      'bigserver' only when the requested object exists on a
+#      server in the .edu domain.  Prefixing the domainname
+#      with '!' means that the cache will be queried for objects
+#      NOT in that domain.
+#
+#      NOTE:   * Any number of domains may be given for a cache-host,
+#                either on the same or separate lines.
+#              * When multiple domains are given for a particular
+#                cache-host, the first matched domain is applied.
+#              * Cache hosts with no domain restrictions are queried
+#                for all requests.
+#              * There are no defaults.
+#              * There is also a 'cache_peer_access' tag in the ACL
+#                section.
+#
+#Default:
+# none
+
+#  TAG: neighbor_type_domain
+#      usage: neighbor_type_domain neighbor parent|sibling domain domain ...
+#
+#      Modifying the neighbor type for specific domains is now
+#      possible.  You can treat some domains differently than the the
+#      default neighbor type specified on the 'cache_peer' line.
+#      Normally it should only be necessary to list domains which
+#      should be treated differently because the default neighbor type
+#      applies for hostnames which do not match domains listed here.
+#
+#EXAMPLE:
+#      cache_peer  parent cache.foo.org 3128 3130
+#      neighbor_type_domain cache.foo.org sibling .com .net
+#      neighbor_type_domain cache.foo.org sibling .au .de
+#
+#Default:
+# none
+
+#  TAG: icp_query_timeout      (msec)
+#      Normally Squid will automatically determine an optimal ICP
+#      query timeout value based on the round-trip-time of recent ICP
+#      queries.  If you want to override the value determined by
+#      Squid, set this 'icp_query_timeout' to a non-zero value.  This
+#      value is specified in MILLISECONDS, so, to use a 2-second
+#      timeout (the old default), you would write:
+#
+#              icp_query_timeout 2000
+#
+#Default:
+# icp_query_timeout 0
+
+#  TAG: maximum_icp_query_timeout      (msec)
+#      Normally the ICP query timeout is determined dynamically.  But
+#      sometimes it can lead to very large values (say 5 seconds).
+#      Use this option to put an upper limit on the dynamic timeout
+#      value.  Do NOT use this option to always use a fixed (instead
+#      of a dynamic) timeout value. To set a fixed timeout see the
+#      'icp_query_timeout' directive.
+#
+#Default:
+# maximum_icp_query_timeout 2000
+
+#  TAG: mcast_icp_query_timeout        (msec)
+#      For Multicast peers, Squid regularly sends out ICP "probes" to
+#      count how many other peers are listening on the given multicast
+#      address.  This value specifies how long Squid should wait to
+#      count all the replies.  The default is 2000 msec, or 2
+#      seconds.
+#
+#Default:
+# mcast_icp_query_timeout 2000
+
+#  TAG: dead_peer_timeout      (seconds)
+#      This controls how long Squid waits to declare a peer cache
+#      as "dead."  If there are no ICP replies received in this
+#      amount of time, Squid will declare the peer dead and not
+#      expect to receive any further ICP replies.  However, it
+#      continues to send ICP queries, and will mark the peer as
+#      alive upon receipt of the first subsequent ICP reply.
+#
+#      This timeout also affects when Squid expects to receive ICP
+#      replies from peers.  If more than 'dead_peer' seconds have
+#      passed since the last ICP reply was received, Squid will not
+#      expect to receive an ICP reply on the next query.  Thus, if
+#      your time between requests is greater than this timeout, you
+#      will see a lot of requests sent DIRECT to origin servers
+#      instead of to your parents.
+#
+#Default:
+# dead_peer_timeout 10 seconds
+
+#  TAG: hierarchy_stoplist
+#      A list of words which, if found in a URL, cause the object to
+#      be handled directly by this cache.  In other words, use this
+#      to not query neighbor caches for certain objects.  You may
+#      list this option multiple times.
+#We recommend you to use at least the following line.
+hierarchy_stoplist cgi-bin ?
+
+#  TAG: no_cache
+#      A list of ACL elements which, if matched, cause the request to
+#      not be satisfied from the cache and the reply to not be cached.
+#      In other words, use this to force certain objects to never be cached.
+#
+#      You must use the word 'DENY' to indicate the ACL names which should
+#      NOT be cached.
+#
+#We recommend you to use the following two lines.
+acl QUERY urlpath_regex cgi-bin \?
+no_cache deny QUERY
+
+
+# OPTIONS WHICH AFFECT THE CACHE SIZE
+# -----------------------------------------------------------------------------
+
+#  TAG: cache_mem      (bytes)
+#      NOTE: THIS PARAMETER DOES NOT SPECIFY THE MAXIMUM PROCESS SIZE.
+#      IT ONLY PLACES A LIMIT ON HOW MUCH ADDITIONAL MEMORY SQUID WILL
+#      USE AS A MEMORY CACHE OF OBJECTS. SQUID USES MEMORY FOR OTHER
+#      THINGS AS WELL. SEE THE SQUID FAQ SECTION 8 FOR DETAILS.
+#
+#      'cache_mem' specifies the ideal amount of memory to be used
+#      for:
+#              * In-Transit objects
+#              * Hot Objects
+#              * Negative-Cached objects
+#
+#      Data for these objects are stored in 4 KB blocks.  This
+#      parameter specifies the ideal upper limit on the total size of
+#      4 KB blocks allocated.  In-Transit objects take the highest
+#      priority.
+#
+#      In-transit objects have priority over the others.  When
+#      additional space is needed for incoming data, negative-cached
+#      and hot objects will be released.  In other words, the
+#      negative-cached and hot objects will fill up any unused space
+#      not needed for in-transit objects.
+#
+#      If circumstances require, this limit will be exceeded.
+#      Specifically, if your incoming request rate requires more than
+#      'cache_mem' of memory to hold in-transit objects, Squid will
+#      exceed this limit to satisfy the new requests.  When the load
+#      decreases, blocks will be freed until the high-water mark is
+#      reached.  Thereafter, blocks will be used to store hot
+#      objects.
+#
+#Default:
+# cache_mem 8 MB
+
+#  TAG: cache_swap_low (percent, 0-100)
+#  TAG: cache_swap_high        (percent, 0-100)
+#
+#      The low- and high-water marks for cache object replacement.
+#      Replacement begins when the swap (disk) usage is above the
+#      low-water mark and attempts to maintain utilization near the
+#      low-water mark.  As swap utilization gets close to high-water
+#      mark object eviction becomes more aggressive.  If utilization is
+#      close to the low-water mark less replacement is done each time.
+#      
+#      Defaults are 90% and 95%. If you have a large cache, 5% could be
+#      hundreds of MB. If this is the case you may wish to set these
+#      numbers closer together.
+#
+#Default:
+# cache_swap_low 90
+# cache_swap_high 95
+
+#  TAG: maximum_object_size    (bytes)
+#      Objects larger than this size will NOT be saved on disk.  The
+#      value is specified in kilobytes, and the default is 4MB.  If
+#      you wish to get a high BYTES hit ratio, you should probably
+#      increase this (one 32 MB object hit counts for 3200 10KB
+#      hits).  If you wish to increase speed more than your want to
+#      save bandwidth you should leave this low.
+#
+#      NOTE: if using the LFUDA replacement policy you should increase
+#      this value to maximize the byte hit rate improvement of LFUDA!
+#      See replacement_policy below for a discussion of this policy.
+#
+#Default:
+# maximum_object_size 4096 KB
+
+#  TAG: minimum_object_size    (bytes)
+#      Objects smaller than this size will NOT be saved on disk.  The
+#      value is specified in kilobytes, and the default is 0 KB, which
+#      means there is no minimum.
+#
+#Default:
+# minimum_object_size 0 KB
+
+#  TAG: maximum_object_size_in_memory  (bytes)
+#        Objects greater than this size will not be attempted to kept in
+#        the memory cache. This should be set high enough to keep objects
+#        accessed frequently in memory to improve performance whilst low
+#        enough to keep larger objects from hoarding cache_mem .
+#
+#Default:
+# maximum_object_size_in_memory 8 KB
+
+#  TAG: ipcache_size   (number of entries)
+#  TAG: ipcache_low    (percent)
+#  TAG: ipcache_high   (percent)
+#      The size, low-, and high-water marks for the IP cache.
+#
+#Default:
+# ipcache_size 1024
+# ipcache_low 90
+# ipcache_high 95
+
+#  TAG: fqdncache_size (number of entries)
+#      Maximum number of FQDN cache entries.
+#
+#Default:
+# fqdncache_size 1024
+
+#  TAG: cache_replacement_policy
+#      The cache replacement policy parameter determines which
+#      objects are evicted (replaced) when disk space is needed.
+#
+#          lru       : Squid's original list based LRU policy
+#          heap GDSF : Greedy-Dual Size Frequency
+#          heap LFUDA: Least Frequently Used with Dynamic Aging
+#          heap LRU  : LRU policy implemented using a heap
+#
+#      Applies to any cache_dir lines listed below this.
+#
+#      The LRU policies keeps recently referenced objects.
+#
+#      The heap GDSF policy optimizes object hit rate by keeping smaller
+#      popular objects in cache so it has a better chance of getting a
+#      hit.  It achieves a lower byte hit rate than LFUDA though since
+#      it evicts larger (possibly popular) objects.
+#
+#      The heap LFUDA policy keeps popular objects in cache regardless of
+#      their size and thus optimizes byte hit rate at the expense of
+#      hit rate since one large, popular object will prevent many
+#      smaller, slightly less popular objects from being cached.
+#
+#      Both policies utilize a dynamic aging mechanism that prevents
+#      cache pollution that can otherwise occur with frequency-based
+#      replacement policies.
+#
+#      NOTE: if using the LFUDA replacement policy you should increase
+#      the value of maximum_object_size above its default of 4096 KB to
+#      to maximize the potential byte hit rate improvement of LFUDA.
+#
+#      For more information about the GDSF and LFUDA cache replacement
+#      policies see http://www.hpl.hp.com/techreports/1999/HPL-1999-69.html
+#      and http://fog.hpl.external.hp.com/techreports/98/HPL-98-173.html.
+#
+#Default:
+# cache_replacement_policy lru
+
+#  TAG: memory_replacement_policy
+#      The memory replacement policy parameter determines which
+#      objects are purged from memory when memory space is needed.
+#
+#      See cache_replacement_policy for details.
+#
+#Default:
+# memory_replacement_policy lru
+
+
+# LOGFILE PATHNAMES AND CACHE DIRECTORIES
+# -----------------------------------------------------------------------------
+
+#  TAG: cache_dir
+#      Usage:
+#      
+#      cache_dir Type Directory-Name Fs-specific-data [options]
+#
+#      You can specify multiple cache_dir lines to spread the
+#      cache among different disk partitions.
+#
+#      Type specifies the kind of storage system to use. Only "ufs"
+#      is built by default. To eanble any of the other storage systems
+#      see the --enable-storeio configure option.
+#
+#      'Directory' is a top-level directory where cache swap
+#      files will be stored.  If you want to use an entire disk
+#      for caching, then this can be the mount-point directory.
+#      The directory must exist and be writable by the Squid
+#      process.  Squid will NOT create this directory for you.
+#
+#      The ufs store type:
+#
+#      "ufs" is the old well-known Squid storage format that has always
+#      been there.
+#
+#      cache_dir ufs Directory-Name Mbytes L1 L2 [options]
+#
+#      'Mbytes' is the amount of disk space (MB) to use under this
+#      directory.  The default is 100 MB.  Change this to suit your
+#      configuration.  Do NOT put the size of your disk drive here.
+#      Instead, if you want Squid to use the entire disk drive,
+#      subtract 20% and use that value.
+#
+#      'Level-1' is the number of first-level subdirectories which
+#      will be created under the 'Directory'.  The default is 16.
+#
+#      'Level-2' is the number of second-level subdirectories which
+#      will be created under each first-level directory.  The default
+#      is 256.
+#
+#      The aufs store type:
+#
+#      "aufs" uses the same storage format as "ufs", utilizing
+#      POSIX-threads to avoid blocking the main Squid process on
+#      disk-I/O. This was formerly known in Squid as async-io.
+#
+#      cache_dir aufs Directory-Name Mbytes L1 L2 [options]
+#
+#      see argument descriptions under ufs above
+#
+#      The diskd store type:
+#
+#      "diskd" uses the same storage format as "ufs", utilizing a
+#      separate process to avoid blocking the main Squid process on
+#      disk-I/O.
+#
+#      cache_dir diskd Directory-Name Mbytes L1 L2 [options] [Q1=n] [Q2=n]
+#
+#      see argument descriptions under ufs above
+#
+#      Q1 specifies the number of unacknowledged I/O requests when Squid
+#      stops opening new files. If this many messages are in the queues,
+#      Squid won't open new files. Default is 64
+#
+#      Q2 specifies the number of unacknowledged messages when Squid
+#      starts blocking.  If this many messages are in the queues,
+#      Squid blocks until it recevies some replies. Default is 72
+#
+#      The coss store type:
+#
+#      block-size=n defines the "block size" for COSS cache_dir's.
+#      Squid uses file numbers as block numbers.  Since file numbers
+#      are limited to 24 bits, the block size determines the maximum
+#      size of the COSS partition.  The default is 512 bytes, which
+#      leads to a maximum cache_dir size of 512<<24, or 8 GB.  Note
+#      that you should not change the coss block size after Squid
+#      has written some objects to the cache_dir.
+#
+#      Common options:
+#
+#      read-only, this cache_dir is read only.
+#
+#      max-size=n, refers to the max object size this storedir supports.
+#      It is used to initially choose the storedir to dump the object.
+#      Note: To make optimal use of the max-size limits you should order
+#      the cache_dir lines with the smallest max-size value first and the
+#      ones with no max-size specification last.
+#
+#      Note that for coss, max-size must be less than COSS_MEMBUF_SZ
+#      (hard coded at 1 MB).
+#
+#Default:
+# cache_dir ufs /var/spool/squid 100 16 256
+
+#  TAG: cache_access_log
+#      Logs the client request activity.  Contains an entry for
+#      every HTTP and ICP queries received. To disable, enter "none".
+#
+#Default:
+# cache_access_log /var/log/squid/access.log
+
+#  TAG: cache_log
+#      Cache logging file. This is where general information about
+#      your cache's behavior goes. You can increase the amount of data
+#      logged to this file with the "debug_options" tag below.
+#
+#Default:
+# cache_log /var/log/squid/cache.log
+
+#  TAG: cache_store_log
+#      Logs the activities of the storage manager.  Shows which
+#      objects are ejected from the cache, and which objects are
+#      saved and for how long.  To disable, enter "none". There are
+#      not really utilities to analyze this data, so you can safely
+#      disable it.
+#
+#Default:
+# cache_store_log /var/log/squid/store.log
+
+#  TAG: cache_swap_log
+#      Location for the cache "swap.log."  This log file holds the
+#      metadata of objects saved on disk.  It is used to rebuild the
+#      cache during startup.  Normally this file resides in each
+#      'cache_dir' directory, but you may specify an alternate
+#      pathname here.  Note you must give a full filename, not just
+#      a directory. Since this is the index for the whole object
+#      list you CANNOT periodically rotate it!
+#
+#      If %s can be used in the file name then it will be replaced with a
+#      a representation of the cache_dir name where each / is replaced
+#      with '.'. This is needed to allow adding/removing cache_dir
+#      lines when cache_swap_log is being used.
+#      
+#      If have more than one 'cache_dir', and %s is not used in the name
+#      then these swap logs will have names such as:
+#
+#              cache_swap_log.00
+#              cache_swap_log.01
+#              cache_swap_log.02
+#
+#      The numbered extension (which is added automatically)
+#      corresponds to the order of the 'cache_dir' lines in this
+#      configuration file.  If you change the order of the 'cache_dir'
+#      lines in this file, then these log files will NOT correspond to
+#      the correct 'cache_dir' entry (unless you manually rename
+#      them).  We recommend that you do NOT use this option.  It is
+#      better to keep these log files in each 'cache_dir' directory.
+#
+#Default:
+# none
+
+#  TAG: emulate_httpd_log      on|off
+#      The Cache can emulate the log file format which many 'httpd'
+#      programs use.  To disable/enable this emulation, set
+#      emulate_httpd_log to 'off' or 'on'.  The default
+#      is to use the native log format since it includes useful
+#      information that Squid-specific log analyzers use.
+#
+#Default:
+# emulate_httpd_log off
+
+#  TAG: log_ip_on_direct       on|off
+#      Log the destination IP address in the hierarchy log tag when going
+#      direct. Earlier Squid versions logged the hostname here. If you
+#      prefer the old way set this to off.
+#
+#Default:
+# log_ip_on_direct on
+
+#  TAG: mime_table
+#      Pathname to Squid's MIME table. You shouldn't need to change
+#      this, but the default file contains examples and formatting
+#      information if you do.
+#
+#Default:
+# mime_table /etc/squid/mime.conf
+
+#  TAG: log_mime_hdrs  on|off
+#      The Cache can record both the request and the response MIME
+#      headers for each HTTP transaction.  The headers are encoded
+#      safely and will appear as two bracketed fields at the end of
+#      the access log (for either the native or httpd-emulated log
+#      formats).  To enable this logging set log_mime_hdrs to 'on'.
+#
+#Default:
+# log_mime_hdrs off
+
+#  TAG: useragent_log
+#      Squid will write the User-Agent field from HTTP requests
+#      to the filename specified here.  By default useragent_log
+#      is disabled.
+#
+#Default:
+# none
+
+#  TAG: referer_log
+# Note: This option is only available if Squid is rebuilt with the
+#       --enable-referer-log option
+#
+#      Squid will write the Referer field from HTTP requests to the
+#      filename specified here.  By default referer_log is disabled.
+#
+#Default:
+# none
+
+#  TAG: pid_filename
+#      A filename to write the process-id to.  To disable, enter "none".
+#
+#Default:
+# pid_filename /var/run/squid.pid
+
+#  TAG: debug_options
+#      Logging options are set as section,level where each source file
+#      is assigned a unique section.  Lower levels result in less
+#      output,  Full debugging (level 9) can result in a very large
+#      log file, so be careful.  The magic word "ALL" sets debugging
+#      levels for all sections.  We recommend normally running with
+#      "ALL,1".
+#
+#Default:
+# debug_options ALL,1
+
+#  TAG: log_fqdn       on|off
+#      Turn this on if you wish to log fully qualified domain names
+#      in the access.log. To do this Squid does a DNS lookup of all
+#      IP's connecting to it. This can (in some situations) increase
+#      latency, which makes your cache seem slower for interactive
+#      browsing.
+#
+#Default:
+# log_fqdn off
+
+#  TAG: client_netmask
+#      A netmask for client addresses in logfiles and cachemgr output.
+#      Change this to protect the privacy of your cache clients.
+#      A netmask of 255.255.255.0 will log all IP's in that range with
+#      the last digit set to '0'.
+#
+#Default:
+# client_netmask 255.255.255.255
+
+
+# OPTIONS FOR EXTERNAL SUPPORT PROGRAMS
+# -----------------------------------------------------------------------------
+
+#  TAG: ftp_user
+#      If you want the anonymous login password to be more informative
+#      (and enable the use of picky ftp servers), set this to something
+#      reasonable for your domain, like wwwuser@somewhere.net
+#
+#      The reason why this is domainless by default is that the
+#      request can be made on the behalf of a user in any domain,
+#      depending on how the cache is used.
+#      Some ftp server also validate that the email address is valid
+#      (for example perl.com).
+#
+#Default:
+# ftp_user Squid@
+
+#  TAG: ftp_list_width
+#      Sets the width of ftp listings. This should be set to fit in
+#      the width of a standard browser. Setting this too small
+#      can cut off long filenames when browsing ftp sites.
+#
+#Default:
+# ftp_list_width 32
+
+#  TAG: ftp_passive
+#      If your firewall does not allow Squid to use passive
+#      connections, then turn off this option.
+#
+#Default:
+# ftp_passive on
+
+#  TAG: ftp_sanitycheck
+#      For security and data integrity reasons Squid by default performs
+#      sanity checks of the addresses of FTP data connections ensure the
+#      data connection is to the requested server. If you need to allow
+#      FTP connections to servers using another IP address for the data
+#      connection then turn this off.
+#
+#Default:
+# ftp_sanitycheck on
+
+#  TAG: ftp_telnet_protocol
+#      The FTP protocol is officially defined to use the telnet protocol
+#      as transport channel for the control connection. However, many
+#      implemenations are broken and does not respect this aspect of
+#      the FTP protocol.
+#
+#      If you have trouble accessing files with ASCII code 255 in the
+#      path or similar problems involving this ASCII code then you can
+#      try setting this directive to off. If that helps report to the
+#      operator of the FTP server in question that their FTP server
+#      is broken and does not follow the FTP standard.
+#
+#Default:
+# ftp_telnet_protocol on
+
+#  TAG: cache_dns_program
+# Note: This option is only available if Squid is rebuilt with the
+#       --disable-internal-dns option
+#
+#      Specify the location of the executable for dnslookup process.
+#
+#Default:
+# cache_dns_program /usr/lib/squid/dnsserver
+
+#  TAG: dns_children
+# Note: This option is only available if Squid is rebuilt with the
+#       --disable-internal-dns option
+#
+#      The number of processes spawn to service DNS name lookups.
+#      For heavily loaded caches on large servers, you should
+#      probably increase this value to at least 10.  The maximum
+#      is 32.  The default is 5.
+#
+#      You must have at least one dnsserver process.
+#
+#Default:
+# dns_children 5
+
+#  TAG: dns_retransmit_interval
+#      Initial retransmit interval for DNS queries. The interval is
+#      doubled each time all configured DNS servers have been tried.
+#
+#
+#Default:
+# dns_retransmit_interval 5 seconds
+
+#  TAG: dns_timeout
+#      DNS Query timeout. If no response is received to a DNS query
+#      within this time then all DNS servers for the queried domain
+#      is assumed to be unavailable.
+#
+#Default:
+# dns_timeout 2 minutes
+
+#  TAG: dns_defnames   on|off
+# Note: This option is only available if Squid is rebuilt with the
+#       --disable-internal-dns option
+#
+#      Normally the 'dnsserver' disables the RES_DEFNAMES resolver
+#      option (see res_init(3)).  This prevents caches in a hierarchy
+#      from interpreting single-component hostnames locally.  To allow
+#      dnsserver to handle single-component names, enable this
+#      option.
+#
+#Default:
+# dns_defnames off
+
+#  TAG: dns_nameservers
+#      Use this if you want to specify a list of DNS name servers
+#      (IP addresses) to use instead of those given in your
+#      /etc/resolv.conf file.
+#      On Windows platforms, if no value is specified here or in
+#      the /etc/resolv.conf file, the list of DNS name servers are
+#      taken from the Windows registry, both static and dynamic DHCP
+#      configurations are supported.
+#
+#      Example: dns_nameservers 10.0.0.1 192.172.0.4
+#
+#Default:
+# none
+
+#  TAG: hosts_file
+#      Location of the host-local IP name-address associations
+#      database.  Most Operating Systems have such a file: under
+#      Un*X it's by default in /etc/hosts MS-Windows NT/2000 places
+#      that in %SystemRoot%(by default
+#      c:\winnt)\system32\drivers\etc\hosts, while Windows 9x/ME
+#      places that in %windir%(usually c:\windows)\hosts
+#
+#      The file contains newline-separated definitions, in the
+#      form ip_address_in_dotted_form name [name ...] names are
+#      whitespace-separated.  lines beginnng with an hash (#)
+#      character are comments.
+#
+#      The file is checked at startup and upon configuration.  If
+#      set to 'none', it won't be checked.  If append_domain is
+#      used, that domain will be added to domain-local (i.e. not
+#      containing any dot character) host definitions.
+#
+#Default:
+# hosts_file /etc/hosts
+
+#  TAG: diskd_program
+#      Specify the location of the diskd executable.
+#      Note that this is only useful if you have compiled in
+#      diskd as one of the store io modules.
+#
+#Default:
+# diskd_program /usr/lib/squid/diskd
+
+#  TAG: unlinkd_program
+#      Specify the location of the executable for file deletion process.
+#
+#Default:
+# unlinkd_program /usr/lib/squid/unlinkd
+
+#  TAG: pinger_program
+#      Specify the location of the executable for the pinger process.
+#
+#Default:
+# pinger_program /usr/lib/squid/pinger
+
+#  TAG: redirect_program
+#      Specify the location of the executable for the URL redirector.
+#      Since they can perform almost any function there isn't one included.
+#      See the FAQ (section 15) for information on how to write one.
+#      By default, a redirector is not used.
+#
+#Default:
+# none
+
+#  TAG: redirect_children
+#      The number of redirector processes to spawn. If you start
+#      too few Squid will have to wait for them to process a backlog of
+#      URLs, slowing it down. If you start too many they will use RAM
+#      and other system resources.
+#
+#Default:
+# redirect_children 5
+
+#  TAG: redirect_rewrites_host_header
+#      By default Squid rewrites any Host: header in redirected
+#      requests.  If you are running an accelerator then this may
+#      not be a wanted effect of a redirector.
+#
+#Default:
+# redirect_rewrites_host_header on
+
+#  TAG: redirector_access
+#      If defined, this access list specifies which requests are
+#      sent to the redirector processes.  By default all requests
+#      are sent.
+#
+#Default:
+# none
+
+#  TAG: auth_param
+#      This is used to define parameters for the various authentication
+#      schemes supported by Squid.
+#
+#      format: auth_param scheme parameter [setting]
+#      
+#      The order that authentication schemes are presented to the client is
+#      dependant on the order the scheme first appears in config file. IE
+#      has a bug (it's not rfc 2617 compliant) in that it will use the basic
+#      scheme if basic is the first entry presented, even if more secure
+#      schemes are presented. For now use the order in the recommended
+#      settings section below. If other browsers have difficulties (don't
+#      recognise the schemes offered even if you are using basic) then either
+#      put basic first, or disable the other schemes (by commenting out their
+#      program entry).
+#
+#      Once an authentication scheme is fully configured, it can only be
+#      shutdown by shutting squid down and restarting. Changes can be made on
+#      the fly and activated with a reconfigure. I.E. You can change to a
+#      different helper, but not unconfigure the helper completely.
+#
+#      Please note that while this directive defines how Squid processes
+#      authentication it does not automatically activate authentication.
+#      To use authenticaiton you must in addition make use of acls based
+#      on login name in http_access (proxy_auth, proxy_auth_regex or
+#      external with %LOGIN used in the format tag). The browser will be
+#      challenged for authentication on the first such acl encountered
+#      in http_access processing and will also be rechallenged for new
+#      login credentials if the request is being denied by a proxy_auth
+#      type acl.
+#
+#      === Parameters for the basic scheme follow. ===
+#      
+#      "program" cmdline
+#      Specify the command for the external authenticator.  Such a program
+#      reads a line containing "username password" and replies "OK" or
+#      "ERR" in an endless loop.
+#
+#      By default, the basic authentication sheme is not used unless a
+#      program is specified.
+#
+#      If you want to use the traditional proxy authentication, jump over to
+#      the helpers/basic_auth/NCSA directory and type:
+#              % make
+#              % make install
+#
+#      Then, set this line to something like
+#
+#      auth_param basic program /usr/libexec/ncsa_auth /usr/etc/passwd
+#      
+#      "children" numberofchildren
+#      The number of authenticator processes to spawn.
+#      If you start too few Squid will have to wait for them to process a
+#      backlog of usercode/password verifications, slowing it down. When
+#      password verifications are done via a (slow) network you are likely to
+#      need lots of authenticator processes.
+#      auth_param basic children 5
+#
+#      "realm" realmstring
+#      Specifies the realm name which is to be reported to the client for
+#      the basic proxy authentication scheme (part of the text the user
+#      will see when prompted their username and password).
+#      auth_param basic realm Squid proxy-caching web server
+#
+#      "credentialsttl" timetolive
+#      Specifies how long squid assumes an externally validated
+#      username:password pair is valid for - in other words how often the
+#      helper program is called for that user. Set this low to force
+#      revalidation with short lived passwords.  Note that setting this high
+#      does not impact your susceptability to replay attacks unless you are
+#      using an one-time password system (such as SecureID). If you are using
+#      such a system, you will be vulnerable to replay attacks unless you
+#      also use the max_user_ip ACL in an http_access rule.
+#      auth_param basic credentialsttl 2 hours
+#
+#      === Parameters for the digest scheme follow ===
+#
+#      "program" cmdline
+#      Specify the command for the external authenticator.  Such a program
+#      reads a line containing "username":"realm" and replies with the
+#      appropriate H(A1) value base64 encoded.  See rfc 2616 for the
+#      definition of H(A1).
+#
+#      By default, the digest authentication scheme is not used unless a
+#      program is specified.
+#
+#      If you want to use a digest authenticator, jump over to the
+#      helpers/digest_auth/ directory and choose the authenticator to use.
+#      It it's directory type
+#              % make
+#              % make install
+#
+#      Then, set this line to something like
+#
+#      auth_param digest program /usr/libexec/digest_auth_pw /usr/etc/digpass
+#
+#
+#      "children" numberofchildren
+#      The number of authenticator processes to spawn (no default). If you
+#      start too few Squid will have to wait for them to process a backlog of
+#      H(A1) calculations, slowing it down.  When the H(A1) calculations are
+#      done via a (slow) network you are likely to need lots of authenticator
+#      processes.
+#      auth_param digest children 5
+#
+#      "realm" realmstring
+#      Specifies the realm name which is to be reported to the client for the
+#      digest proxy authentication scheme (part of the text the user will see
+#      when prompted their username and password).
+#      auth_param digest realm Squid proxy-caching web server
+#
+#      "nonce_garbage_interval" timeinterval
+#      Specifies the interval that nonces that have been issued to clients are
+#      checked for validity.
+#      auth_param digest nonce_garbage_interval 5 minutes
+#
+#      "nonce_max_duration" timeinterval
+#      Specifies the maximum length of time a given nonce will be valid for.
+#      auth_param digest nonce_max_duration 30 minutes
+#
+#      "nonce_max_count" number
+#      Specifies the maximum number of times a given nonce can be used.
+#      auth_param digest nonce_max_count 50
+#
+#      "nonce_strictness" on|off
+#      Determines if squid requires strict increment-by-1 behaviour for nonce
+#      counts, or just incrementing (off - for use when useragents generate
+#      nonce counts that occasionally miss 1 (ie, 1,2,4,6)).
+#      auth_param digest nonce_strictness off
+#
+#      "check_nonce_count" on|off
+#      This directive if set to off can disable the nonce count check
+#      completely to work around buggy digest qop implementations in certain
+#      mainstream browser versions. Default on to check the nonce count to
+#      protect from authentication replay attacks.
+#      auth_param digest check_nonce_count on
+#
+#      "post_workaround" on|off
+#      This is a workaround to certain buggy browsers who sends an incorrect
+#      request digest in POST requests when reusing the same nonce as aquired
+#              earlier in response to a GET request.
+#      auth_param digest post_workaround off
+#
+#      === NTLM scheme options follow ===
+#
+#      "program" cmdline
+#      Specify the command for the external ntlm authenticator. Such a
+#      program participates in the NTLMSSP exchanges between Squid and the
+#      client and reads commands according to the Squid ntlmssp helper
+#      protocol. See helpers/ntlm_auth/ for details. Recommended ntlm
+#      authenticator is ntlm_auth from Samba-3.X, but a number of other
+#      ntlm authenticators is available.
+#
+#      By default, the ntlm authentication scheme is not used unless a
+#      program is specified.
+#
+#      auth_param ntlm program /path/to/samba/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp
+#
+#      "children" numberofchildren
+#      The number of authenticator processes to spawn (no default). If you
+#      start too few Squid will have to wait for them to process a backlog
+#      of credential verifications, slowing it down. When crendential
+#      verifications are done via a (slow) network you are likely to need
+#      lots of authenticator processes.
+#      auth_param ntlm children 5
+#
+#      "max_challenge_reuses" number
+#      The maximum number of times a challenge given by a ntlm authentication
+#      helper can be reused. Increasing this number increases your exposure
+#      to replay attacks on your network. 0 (the default) means use the
+#      challenge is used only once. See also the max_ntlm_challenge_lifetime
+#      directive if enabling challenge reuses.
+#      auth_param ntlm max_challenge_reuses 0
+#
+#      "max_challenge_lifetime" timespan
+#      The maximum time period that a ntlm challenge is reused over. The
+#      actual period will be the minimum of this time AND the number of
+#      reused challenges.
+#      auth_param ntlm max_challenge_lifetime 2 minutes
+#
+#      "use_ntlm_negotiate" on|off
+#      Enables support for NTLM NEGOTIATE packet exchanges with the helper.
+#      The configured ntlm authenticator must be able to handle NTLM
+#      NEGOTIATE packet. See the authenticator programs documentation if
+#      unsure. ntlm_auth from Samba-3.0.2 or later supports the use of this
+#      option.
+#      The NEGOTIATE packet is required to support NTLMv2 and a
+#      number of other negotiable NTLMSSP options, and also makes it
+#      more likely the negotiation is successful. Enabling this parameter
+#      will also solve problems encountered when NT domain policies
+#      restrict users to access only certain workstations. When this is off,
+#      all users must be allowed to log on the proxy servers too, or they'll
+#      get "invalid workstation" errors - and access denied - when trying to
+#      use Squid's services.
+#      Use of ntlm NEGOTIATE is incompatible with challenge reuse, so
+#      enabling this parameter will OVERRIDE the max_challenge_reuses and
+#      max_challenge_lifetime parameters and set them to 0.
+#      auth_param ntlm use_ntlm_negotiate off
+#
+#Recommended minimum configuration:
+#auth_param digest program <uncomment and complete this line>
+#auth_param digest children 5
+#auth_param digest realm Squid proxy-caching web server
+#auth_param digest nonce_garbage_interval 5 minutes
+#auth_param digest nonce_max_duration 30 minutes
+#auth_param digest nonce_max_count 50
+#auth_param ntlm program /usr/lib/squid/ntlm_auth IPH\\PDC
+#auth_param ntlm children 5
+#auth_param ntlm max_challenge_reuses 0
+#auth_param ntlm max_challenge_lifetime 2 minutes
+#auth_param ntlm use_ntlm_negotiate off
+auth_param basic program /usr/lib/squid/squid_ldap_auth -b ou=People,dc=example,dc=com -f (&(uid=%s)(objectClass=gosaProxyAccount))
+auth_param basic children 5
+auth_param basic realm Squid proxy-caching web server
+auth_param basic credentialsttl 2 hours
+
+#  TAG: authenticate_cache_garbage_interval
+#      The time period between garbage collection across the username cache.
+#      This is a tradeoff between memory utilisation (long intervals - say
+#      2 days) and CPU (short intervals - say 1 minute). Only change if you
+#      have good reason to.
+#
+#Default:
+# authenticate_cache_garbage_interval 1 hour
+
+#  TAG: authenticate_ttl
+#      The time a user & their credentials stay in the logged in user cache
+#      since their last request. When the garbage interval passes, all user
+#      credentials that have passed their TTL are removed from memory.
+#
+#Default:
+# authenticate_ttl 1 hour
+
+#  TAG: authenticate_ip_ttl
+#      If you use proxy authentication and the 'max_user_ip' ACL, this
+#      directive controls how long Squid remembers the IP addresses
+#      associated with each user.  Use a small value (e.g., 60 seconds) if
+#      your users might change addresses quickly, as is the case with
+#      dialups. You might be safe using a larger value (e.g., 2 hours) in a
+#      corporate LAN environment with relatively static address assignments.
+#
+#Default:
+# authenticate_ip_ttl 0 seconds
+
+#  TAG: external_acl_type
+#      This option defines external acl classes using a helper program to
+#      look up the status
+#      
+#        external_acl_type name [options] FORMAT.. /path/to/helper [helper arguments..]
+#      
+#      Options:
+#
+#        ttl=n         TTL in seconds for cached results (defaults to 3600
+#                      for 1 hour)
+#        negative_ttl=n
+#                      TTL for cached negative lookups (default same
+#                      as ttl)
+#        children=n    Concurrency level / number of processes spawn
+#                      to service external acl lookups of this type.
+#                      Note: see compatibility note below
+#        cache=n       result cache size, 0 is unbounded (default)
+#      
+#      FORMAT specifications
+#
+#        %LOGIN        Authenticated user login name
+#        %IDENT        Ident user name
+#        %SRC          Client IP
+#        %DST          Requested host
+#        %PROTO        Requested protocol
+#        %PORT         Requested port
+#        %METHOD       Request method
+#        %{Header}     HTTP request header
+#        %{Hdr:member} HTTP request header list member
+#        %{Hdr:;member}
+#                      HTTP request header list member using ; as
+#                      list separator. ; can be any non-alphanumeric
+#                      character.
+#
+#      In addition, any string specified in the referencing acl will
+#      also be included in the helper request line, after the specified
+#      formats (see the "acl external" directive)
+#
+#      The helper receives lines per the above format specification,
+#      and returns lines starting with OK or ERR indicating the validity
+#      of the request and optionally followed by additional keywords with
+#      more details.
+#
+#      General result syntax:
+#      
+#        OK/ERR keyword=value ...
+#
+#      Defined keywords:
+#
+#        user=         The users name (login)
+#        error=        Error description (only defined for ERR results)
+#
+#      Keyword values need to be enclosed in quotes if they may contain
+#      whitespace, or the whitespace escaped using \. Any quotes or \
+#      characters within the keyword value must be \ escaped.
+#
+#      Compatibility Note: The children= option was named concurrency= in
+#      Squid-2.5.STABLE3 and earlier and such syntax is still accepted to
+#      keep compatibility within the Squid-2.5 release. However, the meaning
+#      of concurrency= option has changed in Squid-3 and the old syntax of
+#      the directive is therefore depreated from Squid-2.5.STABLE4 and later.
+#      If you want to be able to easily downgrade to earlier Squid-2.5
+#      releases then you may want to continue using the old name, if not
+#      please use the new name.
+#
+#Default:
+# none
+
+
+# OPTIONS FOR TUNING THE CACHE
+# -----------------------------------------------------------------------------
+
+#  TAG: wais_relay_host
+#  TAG: wais_relay_port
+#      Relay WAIS request to host (1st arg) at port (2 arg).
+#
+#Default:
+# wais_relay_port 0
+
+#  TAG: request_header_max_size        (KB)
+#      This specifies the maximum size for HTTP headers in a request.
+#      Request headers are usually relatively small (about 512 bytes).
+#      Placing a limit on the request header size will catch certain
+#      bugs (for example with persistent connections) and possibly
+#      buffer-overflow or denial-of-service attacks.
+#
+#Default:
+# request_header_max_size 10 KB
+
+#  TAG: request_body_max_size  (KB)
+#      This specifies the maximum size for an HTTP request body.
+#      In other words, the maximum size of a PUT/POST request.
+#      A user who attempts to send a request with a body larger
+#      than this limit receives an "Invalid Request" error message.
+#      If you set this parameter to a zero (the default), there will
+#      be no limit imposed.
+#
+#Default:
+# request_body_max_size 0 KB
+
+#  TAG: refresh_pattern
+#      usage: refresh_pattern [-i] regex min percent max [options]
+#
+#      By default, regular expressions are CASE-SENSITIVE.  To make
+#      them case-insensitive, use the -i option.
+#
+#      'Min' is the time (in minutes) an object without an explicit
+#      expiry time should be considered fresh. The recommended
+#      value is 0, any higher values may cause dynamic applications
+#      to be erroneously cached unless the application designer
+#      has taken the appropriate actions.
+#
+#      'Percent' is a percentage of the objects age (time since last
+#      modification age) an object without explicit expiry time
+#      will be considered fresh.
+#
+#      'Max' is an upper limit on how long objects without an explicit
+#      expiry time will be considered fresh.
+#
+#      options: override-expire
+#               override-lastmod
+#               reload-into-ims
+#               ignore-reload
+#
+#              override-expire enforces min age even if the server
+#              sent a Expires: header. Doing this VIOLATES the HTTP
+#              standard.  Enabling this feature could make you liable
+#              for problems which it causes.
+#
+#              override-lastmod enforces min age even on objects
+#              that was modified recently.
+#
+#              reload-into-ims changes client no-cache or ``reload''
+#              to If-Modified-Since requests. Doing this VIOLATES the
+#              HTTP standard. Enabling this feature could make you
+#              liable for problems which it causes.
+#
+#              ignore-reload ignores a client no-cache or ``reload''
+#              header. Doing this VIOLATES the HTTP standard. Enabling
+#              this feature could make you liable for problems which
+#              it causes.
+#              
+#      Basically a cached object is:
+#
+#              FRESH if expires < now, else STALE
+#              STALE if age > max
+#              FRESH if lm-factor < percent, else STALE
+#              FRESH if age < min
+#              else STALE
+#
+#      The refresh_pattern lines are checked in the order listed here.
+#      The first entry which matches is used.  If none of the entries
+#      match, then the default will be used.
+#
+#      Note, you must uncomment all the default lines if you want
+#      to change one. The default setting is only active if none is
+#      used.
+#
+#Suggested default:
+refresh_pattern ^ftp:          1440    20%     10080
+refresh_pattern ^gopher:       1440    0%      1440
+refresh_pattern .              0       20%     4320
+
+#  TAG: quick_abort_min        (KB)
+#  TAG: quick_abort_max        (KB)
+#  TAG: quick_abort_pct        (percent)
+#      The cache by default continues downloading aborted requests
+#      which are almost completed (less than 16 KB remaining). This
+#      may be undesirable on slow (e.g. SLIP) links and/or very busy
+#      caches.  Impatient users may tie up file descriptors and
+#      bandwidth by repeatedly requesting and immediately aborting
+#      downloads.
+#
+#      When the user aborts a request, Squid will check the
+#      quick_abort values to the amount of data transfered until
+#      then.
+#
+#      If the transfer has less than 'quick_abort_min' KB remaining,
+#      it will finish the retrieval.
+#
+#      If the transfer has more than 'quick_abort_max' KB remaining,
+#      it will abort the retrieval.
+#
+#      If more than 'quick_abort_pct' of the transfer has completed,
+#      it will finish the retrieval.
+#
+#      If you do not want any retrieval to continue after the client
+#      has aborted, set both 'quick_abort_min' and 'quick_abort_max'
+#      to '0 KB'.
+#
+#      If you want retrievals to always continue if they are being
+#      cached then set 'quick_abort_min' to '-1 KB'.
+#
+#Default:
+# quick_abort_min 16 KB
+# quick_abort_max 16 KB
+# quick_abort_pct 95
+
+#  TAG: negative_ttl   time-units
+#      Time-to-Live (TTL) for failed requests.  Certain types of
+#      failures (such as "connection refused" and "404 Not Found") are
+#      negatively-cached for a configurable amount of time.  The
+#      default is 5 minutes.  Note that this is different from
+#      negative caching of DNS lookups.
+#
+#Default:
+# negative_ttl 5 minutes
+
+#  TAG: positive_dns_ttl       time-units
+#      Upper limit on how long Squid will cache positive DNS responses.
+#      Default is 6 hours (360 minutes). This directive must be set
+#      larger than negative_dns_ttl.
+#
+#Default:
+# positive_dns_ttl 6 hours
+
+#  TAG: negative_dns_ttl       time-units
+#      Time-to-Live (TTL) for negative caching of failed DNS lookups.
+#      This also makes sets the lower cache limit on positive lookups.
+#      Minimum value is 1 second, and it is not recommendable to go
+#      much below 10 seconds.
+#
+#Default:
+# negative_dns_ttl 1 minute
+
+#  TAG: range_offset_limit     (bytes)
+#      Sets a upper limit on how far into the the file a Range request
+#      may be to cause Squid to prefetch the whole file. If beyond this
+#      limit then Squid forwards the Range request as it is and the result
+#      is NOT cached.
+#
+#      This is to stop a far ahead range request (lets say start at 17MB)
+#      from making Squid fetch the whole object up to that point before
+#      sending anything to the client.
+#
+#      A value of -1 causes Squid to always fetch the object from the
+#      beginning so that it may cache the result. (2.0 style)
+#
+#      A value of 0 causes Squid to never fetch more than the
+#      client requested. (default)
+#
+#Default:
+# range_offset_limit 0 KB
+
+
+# TIMEOUTS
+# -----------------------------------------------------------------------------
+
+#  TAG: forward_timeout        time-units
+#      This parameter specifies how long Squid should at most attempt in
+#      finding a forwarding path for the request before giving up.
+#
+#Default:
+# forward_timeout 4 minutes
+
+#  TAG: connect_timeout        time-units
+#      This parameter specifies how long to wait for the TCP connect to
+#      the requested server or peer to complete before Squid should
+#      attempt to find another path where to forward the request.
+#
+#Default:
+# connect_timeout 1 minute
+
+#  TAG: peer_connect_timeout   time-units
+#      This parameter specifies how long to wait for a pending TCP
+#      connection to a peer cache.  The default is 30 seconds.   You
+#      may also set different timeout values for individual neighbors
+#      with the 'connect-timeout' option on a 'cache_peer' line.
+#
+#Default:
+# peer_connect_timeout 30 seconds
+
+#  TAG: read_timeout   time-units
+#      The read_timeout is applied on server-side connections.  After
+#      each successful read(), the timeout will be extended by this
+#      amount.  If no data is read again after this amount of time,
+#      the request is aborted and logged with ERR_READ_TIMEOUT.  The
+#      default is 15 minutes.
+#
+#Default:
+# read_timeout 15 minutes
+
+#  TAG: request_timeout
+#      How long to wait for an HTTP request after initial
+#      connection establishment.
+#
+#Default:
+# request_timeout 5 minutes
+
+#  TAG: persistent_request_timeout
+#      How long to wait for the next HTTP request on a persistent
+#      connection after the previous request completes.
+#
+#Default:
+# persistent_request_timeout 1 minute
+
+#  TAG: client_lifetime        time-units
+#      The maximum amount of time that a client (browser) is allowed to
+#      remain connected to the cache process.  This protects the Cache
+#      from having a lot of sockets (and hence file descriptors) tied up
+#      in a CLOSE_WAIT state from remote clients that go away without
+#      properly shutting down (either because of a network failure or
+#      because of a poor client implementation).  The default is one
+#      day, 1440 minutes.
+#
+#      NOTE:  The default value is intended to be much larger than any
+#      client would ever need to be connected to your cache.  You
+#      should probably change client_lifetime only as a last resort.
+#      If you seem to have many client connections tying up
+#      filedescriptors, we recommend first tuning the read_timeout,
+#      request_timeout, persistent_request_timeout and quick_abort values.
+#
+#Default:
+# client_lifetime 1 day
+
+#  TAG: half_closed_clients
+#      Some clients may shutdown the sending side of their TCP
+#      connections, while leaving their receiving sides open.  Sometimes,
+#      Squid can not tell the difference between a half-closed and a
+#      fully-closed TCP connection.  By default, half-closed client
+#      connections are kept open until a read(2) or write(2) on the
+#      socket returns an error.  Change this option to 'off' and Squid
+#      will immediately close client connections when read(2) returns
+#      "no more data to read."
+#
+#Default:
+# half_closed_clients on
+
+#  TAG: pconn_timeout
+#      Timeout for idle persistent connections to servers and other
+#      proxies.
+#
+#Default:
+# pconn_timeout 120 seconds
+
+#  TAG: ident_timeout
+#      Maximum time to wait for IDENT lookups to complete.
+#      
+#      If this is too high, and you enabled IDENT lookups from untrusted
+#      users, then you might be susceptible to denial-of-service by having
+#      many ident requests going at once.
+#
+#Default:
+# ident_timeout 10 seconds
+
+#  TAG: shutdown_lifetime      time-units
+#      When SIGTERM or SIGHUP is received, the cache is put into
+#      "shutdown pending" mode until all active sockets are closed.
+#      This value is the lifetime to set for all open descriptors
+#      during shutdown mode.  Any active clients after this many
+#      seconds will receive a 'timeout' message.
+#
+#Default:
+# shutdown_lifetime 30 seconds
+
+
+# ACCESS CONTROLS
+# -----------------------------------------------------------------------------
+
+#  TAG: acl
+#      Defining an Access List
+#
+#      acl aclname acltype string1 ...
+#      acl aclname acltype "file" ...
+#
+#      when using "file", the file should contain one item per line
+#
+#      acltype is one of the types described below
+#
+#      By default, regular expressions are CASE-SENSITIVE.  To make
+#      them case-insensitive, use the -i option.
+#
+#      acl aclname src      ip-address/netmask ... (clients IP address)
+#      acl aclname src      addr1-addr2/netmask ... (range of addresses)
+#      acl aclname dst      ip-address/netmask ... (URL host's IP address)
+#      acl aclname myip     ip-address/netmask ... (local socket IP address)
+#
+#      acl aclname srcdomain   .foo.com ...    # reverse lookup, client IP
+#      acl aclname dstdomain   .foo.com ...    # Destination server from URL
+#      acl aclname srcdom_regex [-i] xxx ...   # regex matching client name
+#      acl aclname dstdom_regex [-i] xxx ...   # regex matching server
+#        # For dstdomain and dstdom_regex  a reverse lookup is tried if a IP
+#        # based URL is used. The name "none" is used if the reverse lookup
+#        # fails.
+#
+#      acl aclname time     [day-abbrevs]  [h1:m1-h2:m2]
+#          day-abbrevs:
+#              S - Sunday
+#              M - Monday
+#              T - Tuesday
+#              W - Wednesday
+#              H - Thursday
+#              F - Friday
+#              A - Saturday
+#          h1:m1 must be less than h2:m2
+#      acl aclname url_regex [-i] ^http:// ... # regex matching on whole URL
+#      acl aclname urlpath_regex [-i] \.gif$ ...       # regex matching on URL path
+#      acl aclname urllogin [-i] [^a-zA-Z0-9] ...      # regex matching on URL login field
+#      acl aclname port     80 70 21 ...
+#      acl aclname port     0-1024 ...         # ranges allowed
+#      acl aclname myport   3128 ...           # (local socket TCP port)
+#      acl aclname proto    HTTP FTP ...
+#      acl aclname method   GET POST ...
+#      acl aclname browser  [-i] regexp ...
+#        # pattern match on User-Agent header
+#        acl aclname referer_regex  [-i] regexp ...
+#          # pattern match on Referer header
+#          # Referer is highly unreliable, so use with care
+#      acl aclname ident    username ...
+#      acl aclname ident_regex [-i] pattern ...
+#        # string match on ident output.
+#        # use REQUIRED to accept any non-null ident.
+#      acl aclname src_as   number ...
+#      acl aclname dst_as   number ...
+#        # Except for access control, AS numbers can be used for
+#        # routing of requests to specific caches. Here's an
+#        # example for routing all requests for AS#1241 and only
+#        # those to mycache.mydomain.net:
+#        # acl asexample dst_as 1241
+#        # cache_peer_access mycache.mydomain.net allow asexample
+#        # cache_peer_access mycache_mydomain.net deny all
+#
+#      acl aclname proxy_auth username ...
+#      acl aclname proxy_auth_regex [-i] pattern ...
+#        # list of valid usernames
+#        # use REQUIRED to accept any valid username.
+#        #
+#        # NOTE: when a Proxy-Authentication header is sent but it is not
+#        # needed during ACL checking the username is NOT logged
+#        # in access.log.
+#        #
+#        # NOTE: proxy_auth requires a EXTERNAL authentication program
+#        # to check username/password combinations (see
+#        # auth_param directive).
+#        #
+#        # WARNING: proxy_auth can't be used in a transparent proxy. It
+#        # collides with any authentication done by origin servers. It may
+#        # seem like it works at first, but it doesn't.
+#
+#      acl aclname snmp_community string ...
+#        # A community string to limit access to your SNMP Agent
+#        # Example:
+#        #
+#        #     acl snmppublic snmp_community public
+#
+#      acl aclname maxconn number
+#        # This will be matched when the client's IP address has
+#        # more than <number> HTTP connections established.
+#
+#      acl aclname max_user_ip [-s] number
+#        # This will be matched when the user attempts to log in from more
+#        # than <number> different ip addresses. The authenticate_ip_ttl
+#        # parameter controls the timeout on the ip entries.
+#        # If -s is specified then the limit is strict, denying browsing
+#        # from any further IP addresses until the ttl has expired. Without
+#        # -s Squid will just annoy the user by "randomly" denying requests.
+#        # (the counter is then reset each time the limit is reached and a
+#        # request is denied)
+#        # NOTE: in acceleration mode or where there is mesh of child proxies,
+#        # clients may appear to come from multiple addresses if they are
+#        # going through proxy farms, so a limit of 1 may cause user problems.
+#
+#      acl aclname req_mime_type mime-type1 ...
+#        # regex match agains the mime type of the request generated
+#        # by the client. Can be used to detect file upload or some
+#        # types HTTP tunelling requests.
+#        # NOTE: This does NOT match the reply. You cannot use this
+#        # to match the returned file type.
+#
+#      acl aclname rep_mime_type mime-type1 ...
+#        # regex match against the mime type of the reply recieved by
+#        # squid. Can be used to detect file download or some
+#        # types HTTP tunelling requests.
+#        # NOTE: This has no effect in http_access rules. It only has
+#        # effect in rules that affect the reply data stream such as
+#        # http_reply_access.
+#
+#      acl acl_name external class_name [arguments...]
+#        # external ACL lookup via a helper class defined by the
+#        # external_acl_type directive.
+#
+#Examples:
+#acl myexample dst_as 1241
+#acl password proxy_auth REQUIRED
+#acl fileupload req_mime_type -i ^multipart/form-data$
+#acl javascript rep_mime_type -i ^application/x-javascript$
+#
+#Recommended minimum configuration:
+acl all src 0.0.0.0/0.0.0.0
+acl manager proto cache_object
+acl localhost src 127.0.0.1/255.255.255.255
+acl to_localhost dst 127.0.0.0/8
+acl SSL_ports port 443 563
+acl Jabber_ports port 5222
+acl Safe_ports port 80         # http
+acl Safe_ports port 21         # ftp
+acl Safe_ports port 443 563    # https, snews
+acl Safe_ports port 70         # gopher
+acl Safe_ports port 210                # wais
+acl Safe_ports port 1025-65535 # unregistered ports
+acl Safe_ports port 280                # http-mgmt
+acl Safe_ports port 488                # gss-http
+acl Safe_ports port 591                # filemaker
+acl Safe_ports port 777                # multiling http
+acl CONNECT method CONNECT
+
+#  TAG: http_access
+#      Allowing or Denying access based on defined access lists
+#
+#      Access to the HTTP port:
+#      http_access allow|deny [!]aclname ...
+#
+#      NOTE on default values:
+#
+#      If there are no "access" lines present, the default is to deny
+#      the request.
+#
+#      If none of the "access" lines cause a match, the default is the
+#      opposite of the last line in the list.  If the last line was
+#      deny, then the default is allow.  Conversely, if the last line
+#      is allow, the default will be deny.  For these reasons, it is a
+#      good idea to have an "deny all" or "allow all" entry at the end
+#      of your access lists to avoid potential confusion.
+#
+#Default:
+# http_access deny all
+#
+#Recommended minimum configuration:
+#
+# Only allow cachemgr access from localhost
+http_access allow manager localhost
+http_access deny manager
+# Deny requests to unknown ports
+http_access deny !Safe_ports
+# Deny CONNECT to other than SSL ports
+http_access deny CONNECT !SSL_ports !Jabber_ports
+#
+# We strongly recommend to uncomment the following to protect innocent
+# web applications running on the proxy server who think that the only
+# one who can access services on "localhost" is a local user
+#http_access deny to_localhost
+#
+# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
+
+# Example rule allowing access from your local networks. Adapt
+# to list your (internal) IP networks from where browsing should
+# be allowed
+acl password proxy_auth REQUIRED
+
+http_access allow password
+
+
+# And finally deny all other access to this proxy
+http_access allow localhost
+http_access deny all
+
+#  TAG: http_reply_access
+#        Allow replies to client requests. This is complementary to http_access.
+#
+#        http_reply_access allow|deny [!] aclname ...
+#
+#        NOTE: if there are no access lines present, the default is to allow
+#      all replies
+#
+#        If none of the access lines cause a match, then the opposite of the
+#        last line will apply. Thus it is good practice to end the rules
+#        with an "allow all" or "deny all" entry.
+#
+#Default:
+# http_reply_access allow all
+#
+#Recommended minimum configuration:
+#
+# Insert your own rules here.
+#
+#
+# and finally allow by default
+http_reply_access allow all
+
+#  TAG: icp_access
+#      Allowing or Denying access to the ICP port based on defined
+#      access lists
+#
+#      icp_access  allow|deny [!]aclname ...
+#
+#      See http_access for details
+#
+#Default:
+# icp_access deny all
+#
+#Allow ICP queries from everyone
+#icp_access allow all
+
+#  TAG: miss_access
+#      Use to force your neighbors to use you as a sibling instead of
+#      a parent.  For example:
+#
+#              acl localclients src 172.16.0.0/16
+#              miss_access allow localclients
+#              miss_access deny  !localclients
+#
+#      This means that only your local clients are allowed to fetch
+#      MISSES and all other clients can only fetch HITS.
+#
+#      By default, allow all clients who passed the http_access rules
+#      to fetch MISSES from us.
+#
+#Default setting:
+# miss_access allow all
+
+#  TAG: cache_peer_access
+#      Similar to 'cache_peer_domain' but provides more flexibility by
+#      using ACL elements.
+#
+#      cache_peer_access cache-host allow|deny [!]aclname ...
+#
+#      The syntax is identical to 'http_access' and the other lists of
+#      ACL elements.  See the comments for 'http_access' below, or
+#      the Squid FAQ (http://www.squid-cache.org/FAQ/FAQ-10.html).
+#
+#Default:
+# none
+
+#  TAG: ident_lookup_access
+#      A list of ACL elements which, if matched, cause an ident
+#      (RFC 931) lookup to be performed for this request.  For
+#      example, you might choose to always perform ident lookups
+#      for your main multi-user Unix boxes, but not for your Macs
+#      and PCs.  By default, ident lookups are not performed for
+#      any requests.
+#
+#      To enable ident lookups for specific client addresses, you
+#      can follow this example:
+#
+#      acl ident_aware_hosts src 198.168.1.0/255.255.255.0
+#      ident_lookup_access allow ident_aware_hosts
+#      ident_lookup_access deny all
+#
+#      Only src type ACL checks are fully supported.  A src_domain
+#      ACL might work at times, but it will not always provide
+#      the correct result.
+#
+#Default:
+# ident_lookup_access deny all
+
+#  TAG: tcp_outgoing_tos
+#      Allows you to select a TOS/Diffserv value to mark outgoing
+#      connections with, based on the username or source address
+#      making the request.
+#
+#      tcp_outgoing_tos ds-field [!]aclname ...
+#
+#      Example where normal_service_net uses the TOS value 0x00
+#      and normal_service_net uses 0x20
+#
+#      acl normal_service_net src 10.0.0.0/255.255.255.0
+#      acl good_service_net src 10.0.1.0/255.255.255.0
+#      tcp_outgoing_tos 0x00 normal_service_net 0x00
+#      tcp_outgoing_tos 0x20 good_service_net
+#
+#      TOS/DSCP values really only have local significance - so you should
+#      know what you're specifying. For more, see RFC 2474
+#
+#      The TOS/DSCP byte must be exactly that - a byte, value  0 - 255, or
+#      "default" to use whatever default your host has.
+#
+#      Processing proceeds in the order specified, and stops at first fully
+#      matching line.
+#
+#Default:
+# none
+
+#  TAG: tcp_outgoing_address
+#      Allows you to map requests to different outgoing IP addresses
+#      based on the username or sourceaddress of the user making
+#      the request.
+#      
+#      tcp_outgoing_address ipaddr [[!]aclname] ...
+#
+#      Example where requests from 10.0.0.0/24 will be forwareded
+#      with source address 10.1.0.1, 10.0.2.0/24 forwarded with 
+#      source address 10.1.0.2 and the rest will be forwarded with
+#      source address 10.1.0.3.
+#
+#      acl normal_service_net src 10.0.0.0/255.255.255.0
+#      acl good_service_net src 10.0.1.0/255.255.255.0
+#      tcp_outgoing_address 10.0.0.1 normal_service_net
+#      tcp_outgoing_address 10.0.0.2 good_service_net
+#      tcp_outgoing_address 10.0.0.3
+#
+#      Processing proceeds in the order specified, and stops at first fully
+#      matching line.
+#
+#Default:
+# none
+
+#  TAG: reply_body_max_size    bytes allow|deny acl acl...
+#        This option specifies the maximum size of a reply body in bytes.
+#      It can be used to prevent users from downloading very large files,
+#      such as MP3's and movies. When the reply headers are recieved,
+#      the reply_body_max_size lines are processed, and the first line with
+#      a result of "allow" is used as the maximum body size for this reply.
+#      This size is then checked twice. First when we get the reply headers,
+#      we check the content-length value.  If the content length value exists
+#      and is larger than the allowed size, the request is denied and the
+#      user receives an error message that says "the request or reply
+#      is too large." If there is no content-length, and the reply
+#      size exceeds this limit, the client's connection is just closed
+#      and they will receive a partial reply.
+#
+#      WARNING: downstream caches probably can not detect a partial reply
+#      if there is no content-length header, so they will cache
+#      partial responses and give them out as hits.  You should NOT
+#      use this option if you have downstream caches.
+#
+#      If you set this parameter to zero (the default), there will be
+#      no limit imposed.
+#
+#Default:
+# reply_body_max_size 0 allow all
+
+
+# ADMINISTRATIVE PARAMETERS
+# -----------------------------------------------------------------------------
+
+#  TAG: cache_mgr
+#      Email-address of local cache manager who will receive
+#      mail if the cache dies.  The default is "webmaster."
+#
+#Default:
+# cache_mgr webmaster
+
+#  TAG: cache_effective_user
+#  TAG: cache_effective_group
+#
+#      If you start Squid as root, it will change its effective/real
+#      UID/GID to the UID/GID specified below.  The default is to
+#      change to UID to nobody.  If you define cache_effective_user,
+#      but not cache_effective_group, Squid sets the GID the
+#      effective user's default group ID (taken from the password
+#      file).
+#
+#      If Squid is not started as root, the cache_effective_user
+#      value is ignored and the GID value is unchanged by default.
+#      However, you can make Squid change its GID to another group
+#      that the process owner is a member of.  Note that if Squid
+#      is not started as root then you cannot set http_port to a
+#      value lower than 1024.
+#
+#Default:
+# cache_effective_user squid
+# cache_effective_group squid
+
+#  TAG: visible_hostname
+#      If you want to present a special hostname in error messages, etc,
+#      then define this.  Otherwise, the return value of gethostname()
+#      will be used. If you have multiple caches in a cluster and
+#      get errors about IP-forwarding you must set them to have individual
+#      names with this setting.
+#
+#Default:
+# none
+
+#  TAG: unique_hostname
+#      If you want to have multiple machines with the same
+#      'visible_hostname' then you must give each machine a different
+#      'unique_hostname' so that forwarding loops can be detected.
+#
+#Default:
+# none
+
+#  TAG: hostname_aliases
+#      A list of other DNS names that your cache has.
+#
+#Default:
+# none
+
+
+# OPTIONS FOR THE CACHE REGISTRATION SERVICE
+# -----------------------------------------------------------------------------
+#
+#      This section contains parameters for the (optional) cache
+#      announcement service.  This service is provided to help
+#      cache administrators locate one another in order to join or
+#      create cache hierarchies.
+#
+#      An 'announcement' message is sent (via UDP) to the registration
+#      service by Squid.  By default, the announcement message is NOT
+#      SENT unless you enable it with 'announce_period' below.
+#
+#      The announcement message includes your hostname, plus the
+#      following information from this configuration file:
+#
+#              http_port
+#              icp_port
+#              cache_mgr
+#
+#      All current information is processed regularly and made
+#      available on the Web at http://www.ircache.net/Cache/Tracker/.
+
+#  TAG: announce_period
+#      This is how frequently to send cache announcements.  The
+#      default is `0' which disables sending the announcement
+#      messages.
+#
+#      To enable announcing your cache, just uncomment the line
+#      below.
+#
+#Default:
+# announce_period 0
+#
+#To enable announcing your cache, just uncomment the line below.
+#announce_period 1 day
+
+#  TAG: announce_host
+#  TAG: announce_file
+#  TAG: announce_port
+#      announce_host and announce_port set the hostname and port
+#      number where the registration message will be sent.
+#
+#      Hostname will default to 'tracker.ircache.net' and port will
+#      default default to 3131.  If the 'filename' argument is given,
+#      the contents of that file will be included in the announce
+#      message.
+#
+#Default:
+# announce_host tracker.ircache.net
+# announce_port 3131
+
+
+# HTTPD-ACCELERATOR OPTIONS
+# -----------------------------------------------------------------------------
+
+#  TAG: httpd_accel_host
+#  TAG: httpd_accel_port
+#      If you want to run Squid as an httpd accelerator, define the
+#      host name and port number where the real HTTP server is.
+#
+#      If you want IP based virtual host support then specify the
+#      hostname as "virtual". This will make Squid use the IP address
+#      where it accepted the request as hostname in the URL.
+#
+#      If you want virtual port support then specify the port as "0".
+#
+#      NOTE: enabling httpd_accel_host disables proxy-caching and
+#      ICP.  If you want these features enabled also, then set
+#      the 'httpd_accel_with_proxy' option.
+#
+#Default:
+# httpd_accel_port 80
+
+#  TAG: httpd_accel_single_host        on|off
+#      If you are running Squid as an accelerator and have a single backend
+#      server then set this to on. This causes Squid to forward the request
+#      to this server irregardles of what any redirectors or Host headers
+#      says.
+#
+#      Leave this at off if you have multiple backend servers, and use a
+#      redirector (or host table or private DNS) to map the requests to the
+#      appropriate backend servers. Note that the mapping needs to be a
+#      1-1 mapping between requested and backend (from redirector) domain
+#      names or caching will fail, as cacing is performed using the
+#      URL returned from the redirector.
+#
+#      See also redirect_rewrites_host_header.
+#
+#Default:
+# httpd_accel_single_host off
+
+#  TAG: httpd_accel_with_proxy on|off
+#      If you want to use Squid as both a local httpd accelerator
+#      and as a proxy, change this to 'on'. Note however that your
+#      proxy users may have trouble to reach the accelerated domains
+#      unless their browsers are configured not to use this proxy for
+#      those domains (for example via the no_proxy browser configuration
+#      setting)
+#
+#Default:
+# httpd_accel_with_proxy off
+
+#  TAG: httpd_accel_uses_host_header   on|off
+#      HTTP/1.1 requests include a Host: header which is basically the
+#      hostname from the URL.  The Host: header is used for domain based
+#      virutal hosts. If your accelerator needs to provide domain based
+#      virtual hosts on the same IP address then you will need to turn this
+#      on.
+#
+#      Note that Squid does NOT check the value of the Host header matches
+#      any of your accelerated server, so it may open a big security hole
+#      unless you take care to set up access controls proper.  We recommend
+#      that this option remain disabled unless you are sure of what you
+#      are doing.
+#
+#      However, you will need to enable this option if you run Squid
+#      as a transparent proxy.  Otherwise, virtual servers which
+#      require the Host: header will not be properly cached.
+#
+#Default:
+# httpd_accel_uses_host_header off
+
+
+# MISCELLANEOUS
+# -----------------------------------------------------------------------------
+
+#  TAG: dns_testnames
+#      The DNS tests exit as soon as the first site is successfully looked up
+#
+#      This test can be disabled with the -D command line option.
+#
+#Default:
+# dns_testnames netscape.com internic.net nlanr.net microsoft.com
+
+#  TAG: logfile_rotate
+#      Specifies the number of logfile rotations to make when you
+#      type 'squid -k rotate'.  The default is 10, which will rotate
+#      with extensions 0 through 9.  Setting logfile_rotate to 0 will
+#      disable the rotation, but the logfiles are still closed and
+#      re-opened.  This will enable you to rename the logfiles
+#      yourself just before sending the rotate signal.
+#
+#      Note, the 'squid -k rotate' command normally sends a USR1
+#      signal to the running squid process.  In certain situations
+#      (e.g. on Linux with Async I/O), USR1 is used for other
+#      purposes, so -k rotate uses another signal.  It is best to get
+#      in the habit of using 'squid -k rotate' instead of 'kill -USR1
+#      <pid>'.
+#
+#Default:
+# logfile_rotate 0
+
+#  TAG: append_domain
+#      Appends local domain name to hostnames without any dots in
+#      them.  append_domain must begin with a period.
+#
+#      Be warned that there today is Internet names with no dots in
+#      them using only top-domain names, so setting this may
+#      cause some Internet sites to become unavailable.
+#
+#Example:
+# append_domain .yourdomain.com
+#
+#Default:
+# none
+
+#  TAG: tcp_recv_bufsize       (bytes)
+#      Size of receive buffer to set for TCP sockets.  Probably just
+#      as easy to change your kernel's default.  Set to zero to use
+#      the default buffer size.
+#
+#Default:
+# tcp_recv_bufsize 0 bytes
+
+#  TAG: err_html_text
+#      HTML text to include in error messages.  Make this a "mailto"
+#      URL to your admin address, or maybe just a link to your
+#      organizations Web page.
+#
+#      To include this in your error messages, you must rewrite
+#      the error template files (found in the "errors" directory).
+#      Wherever you want the 'err_html_text' line to appear,
+#      insert a %L tag in the error template file.
+#
+#Default:
+# none
+
+#  TAG: deny_info
+#      Usage:   deny_info err_page_name acl
+#      or       deny_info http://... acl
+#      Example: deny_info ERR_CUSTOM_ACCESS_DENIED bad_guys
+#
+#      This can be used to return a ERR_ page for requests which
+#      do not pass the 'http_access' rules.  A single ACL will cause
+#      the http_access check to fail.  If a 'deny_info' line exists
+#      for that ACL then Squid returns a corresponding error page.
+#
+#      You may use ERR_ pages that come with Squid or create your own pages
+#      and put them into the configured errors/ directory.
+#
+#      Alternatively you can specify an error URL. The browsers will then
+#      get redirected (302) to the specified URL. %s in the redirection
+#      URL will be replaced by the requested URL.
+#
+#      Alternatively you can tell Squid to reset the TCP connection
+#      by specifying TCP_RESET.
+#
+#Default:
+# none
+
+#  TAG: memory_pools   on|off
+#      If set, Squid will keep pools of allocated (but unused) memory
+#      available for future use.  If memory is a premium on your
+#      system and you believe your malloc library outperforms Squid
+#      routines, disable this.
+#
+#Default:
+# memory_pools on
+
+#  TAG: memory_pools_limit     (bytes)
+#      Used only with memory_pools on:
+#      memory_pools_limit 50 MB
+#
+#      If set to a non-zero value, Squid will keep at most the specified
+#      limit of allocated (but unused) memory in memory pools. All free()
+#      requests that exceed this limit will be handled by your malloc
+#      library. Squid does not pre-allocate any memory, just safe-keeps
+#      objects that otherwise would be free()d. Thus, it is safe to set
+#      memory_pools_limit to a reasonably high value even if your
+#      configuration will use less memory.
+#
+#      If not set (default) or set to zero, Squid will keep all memory it
+#      can. That is, there will be no limit on the total amount of memory
+#      used for safe-keeping.
+#
+#      To disable memory allocation optimization, do not set
+#      memory_pools_limit to 0. Set memory_pools to "off" instead.
+#
+#      An overhead for maintaining memory pools is not taken into account
+#      when the limit is checked. This overhead is close to four bytes per
+#      object kept. However, pools may actually _save_ memory because of
+#      reduced memory thrashing in your malloc library.
+#
+#Default:
+# none
+
+#  TAG: forwarded_for  on|off
+#      If set, Squid will include your system's IP address or name
+#      in the HTTP requests it forwards.  By default it looks like
+#      this:
+#
+#              X-Forwarded-For: 192.1.2.3
+#
+#      If you disable this, it will appear as
+#
+#              X-Forwarded-For: unknown
+#
+#Default:
+# forwarded_for on
+
+#  TAG: log_icp_queries        on|off
+#      If set, ICP queries are logged to access.log. You may wish
+#      do disable this if your ICP load is VERY high to speed things
+#      up or to simplify log analysis.
+#
+#Default:
+# log_icp_queries on
+
+#  TAG: icp_hit_stale  on|off
+#      If you want to return ICP_HIT for stale cache objects, set this
+#      option to 'on'.  If you have sibling relationships with caches
+#      in other administrative domains, this should be 'off'.  If you only
+#      have sibling relationships with caches under your control, then
+#      it is probably okay to set this to 'on'.
+#      If set to 'on', then your siblings should use the option "allow-miss"
+#      on their cache_peer lines for connecting to you.
+#
+#Default:
+# icp_hit_stale off
+
+#  TAG: minimum_direct_hops
+#      If using the ICMP pinging stuff, do direct fetches for sites
+#      which are no more than this many hops away.
+#
+#Default:
+# minimum_direct_hops 4
+
+#  TAG: minimum_direct_rtt
+#      If using the ICMP pinging stuff, do direct fetches for sites
+#      which are no more than this many rtt milliseconds away.
+#
+#Default:
+# minimum_direct_rtt 400
+
+#  TAG: cachemgr_passwd
+#      Specify passwords for cachemgr operations.
+#
+#      Usage: cachemgr_passwd password action action ...
+#
+#      Some valid actions are (see cache manager menu for a full list):
+#              5min
+#              60min
+#              asndb
+#              authenticator
+#              cbdata
+#              client_list
+#              comm_incoming
+#              config *
+#              counters
+#              delay
+#              digest_stats
+#              dns
+#              events
+#              filedescriptors
+#              fqdncache
+#              histograms
+#              http_headers
+#              info
+#              io
+#              ipcache
+#              mem
+#              menu
+#              netdb
+#              non_peers
+#              objects
+#              offline_toggle *
+#              pconn
+#              peer_select
+#              redirector
+#              refresh
+#              server_list
+#              shutdown *
+#              store_digest
+#              storedir
+#              utilization
+#              via_headers
+#              vm_objects
+#
+#      * Indicates actions which will not be performed without a
+#        valid password, others can be performed if not listed here.
+#
+#      To disable an action, set the password to "disable".
+#      To allow performing an action without a password, set the
+#      password to "none".
+#
+#      Use the keyword "all" to set the same password for all actions.
+#
+#Example:
+# cachemgr_passwd secret shutdown
+# cachemgr_passwd lesssssssecret info stats/objects
+# cachemgr_passwd disable all
+#
+#Default:
+# none
+
+#  TAG: store_avg_object_size  (kbytes)
+#      Average object size, used to estimate number of objects your
+#      cache can hold.  See doc/Release-Notes-1.1.txt.  The default is
+#      13 KB.
+#
+#Default:
+# store_avg_object_size 13 KB
+
+#  TAG: store_objects_per_bucket
+#      Target number of objects per bucket in the store hash table.
+#      Lowering this value increases the total number of buckets and
+#      also the storage maintenance rate.  The default is 50.
+#
+#Default:
+# store_objects_per_bucket 20
+
+#  TAG: client_db      on|off
+#      If you want to disable collecting per-client statistics, then
+#      turn off client_db here.
+#
+#Default:
+# client_db on
+
+#  TAG: netdb_low
+#  TAG: netdb_high
+#      The low and high water marks for the ICMP measurement
+#      database.  These are counts, not percents.  The defaults are
+#      900 and 1000.  When the high water mark is reached, database
+#      entries will be deleted until the low mark is reached.
+#
+#Default:
+# netdb_low 900
+# netdb_high 1000
+
+#  TAG: netdb_ping_period
+#      The minimum period for measuring a site.  There will be at
+#      least this much delay between successive pings to the same
+#      network.  The default is five minutes.
+#
+#Default:
+# netdb_ping_period 5 minutes
+
+#  TAG: query_icmp     on|off
+#      If you want to ask your peers to include ICMP data in their ICP
+#      replies, enable this option.
+#
+#      If your peer has configured Squid (during compilation) with
+#      '--enable-icmp' then that peer will send ICMP pings to origin server
+#      sites of the URLs it receives.  If you enable this option then the
+#      ICP replies from that peer will include the ICMP data (if available).
+#      Then, when choosing a parent cache, Squid will choose the parent with
+#      the minimal RTT to the origin server.  When this happens, the
+#      hierarchy field of the access.log will be
+#      "CLOSEST_PARENT_MISS".  This option is off by default.
+#
+#Default:
+# query_icmp off
+
+#  TAG: test_reachability      on|off
+#      When this is 'on', ICP MISS replies will be ICP_MISS_NOFETCH
+#      instead of ICP_MISS if the target host is NOT in the ICMP
+#      database, or has a zero RTT.
+#
+#Default:
+# test_reachability off
+
+#  TAG: buffered_logs  on|off
+#      cache.log log file is written with stdio functions, and as such
+#      it can be buffered or unbuffered. By default it will be unbuffered.
+#      Buffering it can speed up the writing slightly (though you are
+#      unlikely to need to worry unless you run with tons of debugging
+#      enabled in which case performance will suffer badly anyway..).
+#
+#Default:
+# buffered_logs off
+
+#  TAG: reload_into_ims        on|off
+#      When you enable this option, client no-cache or ``reload''
+#      requests will be changed to If-Modified-Since requests.
+#      Doing this VIOLATES the HTTP standard.  Enabling this
+#      feature could make you liable for problems which it
+#      causes.
+#      
+#      see also refresh_pattern for a more selective approach.
+#
+#Default:
+# reload_into_ims off
+
+#  TAG: always_direct
+#      Usage: always_direct allow|deny [!]aclname ...
+#
+#      Here you can use ACL elements to specify requests which should
+#      ALWAYS be forwarded directly to origin servers.  For example,
+#      to always directly forward requests for local servers use
+#      something like:
+#
+#              acl local-servers dstdomain my.domain.net
+#              always_direct allow local-servers
+#
+#      To always forward FTP requests directly, use
+#
+#              acl FTP proto FTP
+#              always_direct allow FTP
+#
+#      NOTE: There is a similar, but opposite option named
+#      'never_direct'.  You need to be aware that "always_direct deny
+#      foo" is NOT the same thing as "never_direct allow foo".  You
+#      may need to use a deny rule to exclude a more-specific case of
+#      some other rule.  Example:
+#
+#              acl local-external dstdomain external.foo.net
+#              acl local-servers dstdomain  .foo.net
+#              always_direct deny local-external
+#              always_direct allow local-servers
+#
+#      This option replaces some v1.1 options such as local_domain
+#      and local_ip.
+#
+#Default:
+# none
+
+#  TAG: never_direct
+#      Usage: never_direct allow|deny [!]aclname ...
+#
+#      never_direct is the opposite of always_direct.  Please read
+#      the description for always_direct if you have not already.
+#
+#      With 'never_direct' you can use ACL elements to specify
+#      requests which should NEVER be forwarded directly to origin
+#      servers.  For example, to force the use of a proxy for all
+#      requests, except those in your local domain use something like:
+#
+#              acl local-servers dstdomain .foo.net
+#              acl all src 0.0.0.0/0.0.0.0
+#              never_direct deny local-servers
+#              never_direct allow all
+#      
+#      or if squid is inside a firewall and there is local intranet
+#      servers inside the firewall then use something like:
+#
+#              acl local-intranet dstdomain .foo.net
+#              acl local-external dstdomain external.foo.net
+#              always_direct deny local-external
+#              always_direct allow local-intranet
+#              never_direct allow all
+#      
+#      This option replaces some v1.1 options such as inside_firewall
+#      and firewall_ip.
+#
+#Default:
+# none
+
+#  TAG: header_access
+#      Usage: header_access header_name allow|deny [!]aclname ...
+#
+#      WARNING: Doing this VIOLATES the HTTP standard.  Enabling
+#      this feature could make you liable for problems which it
+#      causes.
+#
+#      This option replaces the old 'anonymize_headers' and the
+#      older 'http_anonymizer' option with something that is much
+#      more configurable. This new method creates a list of ACLs
+#      for each header, allowing you very fine-tuned header
+#      mangling.
+#
+#      You can only specify known headers for the header name.
+#      Other headers are reclassified as 'Other'. You can also
+#      refer to all the headers with 'All'.
+#
+#      For example, to achieve the same behaviour as the old
+#      'http_anonymizer standard' option, you should use:
+#
+#              header_access From deny all
+#              header_access Referer deny all
+#              header_access Server deny all
+#              header_access User-Agent deny all
+#              header_access WWW-Authenticate deny all
+#              header_access Link deny all
+#
+#      Or, to reproduce the old 'http_anonymizer paranoid' feature
+#      you should use:
+#
+#              header_access Allow allow all
+#              header_access Authorization allow all
+#              header_access WWW-Authenticate allow all
+#              header_access Cache-Control allow all
+#              header_access Content-Encoding allow all
+#              header_access Content-Length allow all
+#              header_access Content-Type allow all
+#              header_access Date allow all
+#              header_access Expires allow all
+#              header_access Host allow all
+#              header_access If-Modified-Since allow all
+#              header_access Last-Modified allow all
+#              header_access Location allow all
+#              header_access Pragma allow all
+#              header_access Accept allow all
+#              header_access Accept-Charset allow all
+#              header_access Accept-Encoding allow all
+#              header_access Accept-Language allow all
+#              header_access Content-Language allow all
+#              header_access Mime-Version allow all
+#              header_access Retry-After allow all
+#              header_access Title allow all
+#              header_access Connection allow all
+#              header_access Proxy-Connection allow all
+#              header_access All deny all
+#
+#      By default, all headers are allowed (no anonymizing is
+#      performed).
+#
+#Default:
+# none
+
+#  TAG: header_replace
+#      Usage:   header_replace header_name message
+#      Example: header_replace User-Agent Nutscrape/1.0 (CP/M; 8-bit)
+#
+#      This option allows you to change the contents of headers
+#      denied with header_access above, by replacing them with
+#      some fixed string. This replaces the old fake_user_agent
+#      option.
+#
+#      By default, headers are removed if denied.
+#
+#Default:
+# none
+
+#  TAG: icon_directory
+#      Where the icons are stored. These are normally kept in
+#      /usr/share/squid/icons
+#
+#Default:
+# icon_directory /usr/share/squid/icons
+
+#  TAG: short_icon_urls
+#      If this is enabled then Squid will use short URLs for icons.
+#
+#      If off then the URLs for icons will always be absolute URLs
+#      including the proxy name and port.
+#
+#Default:
+# short_icon_urls off
+
+#  TAG: error_directory
+#      If you wish to create your own versions of the default
+#      (English) error files, either to customize them to suit your
+#      language or company copy the template English files to another
+#      directory and point this tag at them.
+#
+#Default:
+# error_directory /usr/share/squid/errors/English
+
+#  TAG: maximum_single_addr_tries
+#      This sets the maximum number of connection attempts for a
+#      host that only has one address (for multiple-address hosts,
+#      each address is tried once).
+#
+#      The default value is one attempt, the (not recommended)
+#      maximum is 255 tries.  A warning message will be generated
+#      if it is set to a value greater than ten.
+#
+#      Note: This is in addition to the request reforwarding which
+#      takes place if Squid fails to get a satisfying response.
+#
+#Default:
+# maximum_single_addr_tries 1
+
+#  TAG: snmp_port
+#      Squid can now serve statistics and status information via SNMP.
+#      By default it listens to port 3401 on the machine. If you don't
+#      wish to use SNMP, set this to "0".
+#
+#Default:
+# snmp_port 3401
+
+#  TAG: snmp_access
+#      Allowing or denying access to the SNMP port.
+#
+#      All access to the agent is denied by default.
+#      usage:
+#
+#      snmp_access allow|deny [!]aclname ...
+#
+#Example:
+# snmp_access allow snmppublic localhost
+# snmp_access deny all
+#
+#Default:
+# snmp_access deny all
+
+#  TAG: snmp_incoming_address
+#  TAG: snmp_outgoing_address
+#      Just like 'udp_incoming_address' above, but for the SNMP port.
+#
+#      snmp_incoming_address   is used for the SNMP socket receiving
+#                              messages from SNMP agents.
+#      snmp_outgoing_address   is used for SNMP packets returned to SNMP
+#                              agents.
+#
+#      The default snmp_incoming_address (0.0.0.0) is to listen on all
+#      available network interfaces.
+#
+#      If snmp_outgoing_address is set to 255.255.255.255 (the default)
+#      then it will use the same socket as snmp_incoming_address. Only
+#      change this if you want to have SNMP replies sent using another
+#      address than where this Squid listens for SNMP queries.
+#
+#      NOTE, snmp_incoming_address and snmp_outgoing_address can not have
+#      the same value since they both use port 3401.
+#
+#Default:
+# snmp_incoming_address 0.0.0.0
+# snmp_outgoing_address 255.255.255.255
+
+#  TAG: as_whois_server
+#      WHOIS server to query for AS numbers.  NOTE: AS numbers are
+#      queried only when Squid starts up, not for every request.
+#
+#Default:
+# as_whois_server whois.ra.net
+# as_whois_server whois.ra.net
+
+#  TAG: wccp_router
+#      Use this option to define your WCCP ``home'' router for
+#      Squid.   Setting the 'wccp_router' to 0.0.0.0 (the default)
+#      disables WCCP.
+#
+#Default:
+# wccp_router 0.0.0.0
+
+#  TAG: wccp_version
+#      According to some users, Cisco IOS 11.2 only supports WCCP
+#      version 3.  If you're using that version of IOS, change
+#      this value to 3.
+#
+#Default:
+# wccp_version 4
+
+#  TAG: wccp_incoming_address
+#  TAG: wccp_outgoing_address
+#        wccp_incoming_address   Use this option if you require WCCP
+#                              messages to be received on only one
+#                              interface.  Do NOT use this option if
+#                              you're unsure how many interfaces you
+#                              have, or if you know you have only one
+#                              interface.
+#
+#      wccp_outgoing_address   Use this option if you require WCCP
+#                              messages to be sent out on only one
+#                              interface.  Do NOT use this option if
+#                              you're unsure how many interfaces you
+#                              have, or if you know you have only one
+#                              interface.
+#
+#        The default behavior is to not bind to any specific address.
+#
+#        NOTE, wccp_incoming_address and wccp_outgoing_address can not have
+#        the same value since they both use port 2048.
+#
+#Default:
+# wccp_incoming_address 0.0.0.0
+# wccp_outgoing_address 255.255.255.255
+
+
+# DELAY POOL PARAMETERS (all require DELAY_POOLS compilation option)
+# -----------------------------------------------------------------------------
+
+#  TAG: delay_pools
+#      This represents the number of delay pools to be used.  For example,
+#      if you have one class 2 delay pool and one class 3 delays pool, you
+#      have a total of 2 delay pools.
+#
+#Default:
+# delay_pools 0
+
+#  TAG: delay_class
+#      This defines the class of each delay pool.  There must be exactly one
+#      delay_class line for each delay pool.  For example, to define two
+#      delay pools, one of class 2 and one of class 3, the settings above
+#      and here would be:
+#
+#Example:
+# delay_pools 2      # 2 delay pools
+# delay_class 1 2    # pool 1 is a class 2 pool
+# delay_class 2 3    # pool 2 is a class 3 pool
+#
+#      The delay pool classes are:
+#
+#              class 1         Everything is limited by a single aggregate
+#                              bucket.
+#
+#              class 2         Everything is limited by a single aggregate
+#                              bucket as well as an "individual" bucket chosen
+#                              from bits 25 through 32 of the IP address.
+#
+#              class 3         Everything is limited by a single aggregate
+#                              bucket as well as a "network" bucket chosen
+#                              from bits 17 through 24 of the IP address and a
+#                              "individual" bucket chosen from bits 17 through
+#                              32 of the IP address.
+#
+#      NOTE: If an IP address is a.b.c.d
+#              -> bits 25 through 32 are "d"
+#              -> bits 17 through 24 are "c"
+#              -> bits 17 through 32 are "c * 256 + d"
+#
+#Default:
+# none
+
+#  TAG: delay_access
+#      This is used to determine which delay pool a request falls into.
+#      The first matched delay pool is always used, i.e., if a request falls
+#      into delay pool number one, no more delay are checked, otherwise the
+#      rest are checked in order of their delay pool number until they have
+#      all been checked.  For example, if you want some_big_clients in delay
+#      pool 1 and lotsa_little_clients in delay pool 2:
+#
+#Example:
+# delay_access 1 allow some_big_clients
+# delay_access 1 deny all
+# delay_access 2 allow lotsa_little_clients
+# delay_access 2 deny all
+#
+#Default:
+# none
+
+#  TAG: delay_parameters
+#      This defines the parameters for a delay pool.  Each delay pool has
+#      a number of "buckets" associated with it, as explained in the
+#      description of delay_class.  For a class 1 delay pool, the syntax is:
+#
+#delay_parameters pool aggregate
+#
+#      For a class 2 delay pool:
+#
+#delay_parameters pool aggregate individual
+#
+#      For a class 3 delay pool:
+#
+#delay_parameters pool aggregate network individual
+#
+#      The variables here are:
+#
+#              pool            a pool number - ie, a number between 1 and the
+#                              number specified in delay_pools as used in
+#                              delay_class lines.
+#
+#              aggregate       the "delay parameters" for the aggregate bucket
+#                              (class 1, 2, 3).
+#
+#              individual      the "delay parameters" for the individual
+#                              buckets (class 2, 3).
+#
+#              network         the "delay parameters" for the network buckets
+#                              (class 3).
+#
+#      A pair of delay parameters is written restore/maximum, where restore is
+#      the number of bytes (not bits - modem and network speeds are usually
+#      quoted in bits) per second placed into the bucket, and maximum is the
+#      maximum number of bytes which can be in the bucket at any time.
+#
+#      For example, if delay pool number 1 is a class 2 delay pool as in the
+#      above example, and is being used to strictly limit each host to 64kbps
+#      (plus overheads), with no overall limit, the line is:
+#
+#delay_parameters 1 -1/-1 8000/8000
+#
+#      Note that the figure -1 is used to represent "unlimited".
+#
+#      And, if delay pool number 2 is a class 3 delay pool as in the above
+#      example, and you want to limit it to a total of 256kbps (strict limit)
+#      with each 8-bit network permitted 64kbps (strict limit) and each
+#      individual host permitted 4800bps with a bucket maximum size of 64kb
+#      to permit a decent web page to be downloaded at a decent speed
+#      (if the network is not being limited due to overuse) but slow down
+#      large downloads more significantly:
+#
+#delay_parameters 2 32000/32000 8000/8000 600/8000
+#
+#      There must be one delay_parameters line for each delay pool.
+#
+#Default:
+# none
+
+#  TAG: delay_initial_bucket_level     (percent, 0-100)
+#      The initial bucket percentage is used to determine how much is put
+#      in each bucket when squid starts, is reconfigured, or first notices
+#      a host accessing it (in class 2 and class 3, individual hosts and
+#      networks only have buckets associated with them once they have been
+#      "seen" by squid).
+#
+#Default:
+# delay_initial_bucket_level 50
+
+#  TAG: incoming_icp_average
+#  TAG: incoming_http_average
+#  TAG: incoming_dns_average
+#  TAG: min_icp_poll_cnt
+#  TAG: min_dns_poll_cnt
+#  TAG: min_http_poll_cnt
+#      Heavy voodoo here.  I can't even believe you are reading this.
+#      Are you crazy?  Don't even think about adjusting these unless
+#      you understand the algorithms in comm_select.c first!
+#
+#Default:
+# incoming_icp_average 6
+# incoming_http_average 4
+# incoming_dns_average 4
+# min_icp_poll_cnt 8
+# min_dns_poll_cnt 8
+# min_http_poll_cnt 8
+
+#  TAG: max_open_disk_fds
+#      To avoid having disk as the I/O bottleneck Squid can optionally
+#      bypass the on-disk cache if more than this amount of disk file
+#      descriptors are open.
+#
+#      A value of 0 indicates no limit.
+#
+#Default:
+# max_open_disk_fds 0
+
+#  TAG: offline_mode
+#      Enable this option and Squid will never try to validate cached
+#      objects.
+#
+#Default:
+# offline_mode off
+
+#  TAG: uri_whitespace
+#      What to do with requests that have whitespace characters in the
+#      URI.  Options:
+#
+#      strip:  The whitespace characters are stripped out of the URL.
+#              This is the behavior recommended by RFC2396.
+#      deny:   The request is denied.  The user receives an "Invalid
+#              Request" message.
+#      allow:  The request is allowed and the URI is not changed.  The
+#              whitespace characters remain in the URI.  Note the
+#              whitespace is passed to redirector processes if they
+#              are in use.
+#      encode: The request is allowed and the whitespace characters are
+#              encoded according to RFC1738.  This could be considered
+#              a violation of the HTTP/1.1
+#              RFC because proxies are not allowed to rewrite URI's.
+#      chop:   The request is allowed and the URI is chopped at the
+#              first whitespace.  This might also be considered a
+#              violation.
+#
+#Default:
+# uri_whitespace strip
+
+#  TAG: broken_posts
+#      A list of ACL elements which, if matched, causes Squid to send
+#      an extra CRLF pair after the body of a PUT/POST request.
+#
+#      Some HTTP servers has broken implementations of PUT/POST,
+#      and rely on an extra CRLF pair sent by some WWW clients.
+#
+#      Quote from RFC 2068 section 4.1 on this matter:
+#
+#        Note: certain buggy HTTP/1.0 client implementations generate an
+#        extra CRLF's after a POST request. To restate what is explicitly
+#        forbidden by the BNF, an HTTP/1.1 client must not preface or follow
+#        a request with an extra CRLF.
+#
+#Example:
+# acl buggy_server url_regex ^http://....
+# broken_posts allow buggy_server
+#
+#Default:
+# none
+
+#  TAG: mcast_miss_addr
+# Note: This option is only available if Squid is rebuilt with the
+#       -DMULTICAST_MISS_STREAM option
+#
+#      If you enable this option, every "cache miss" URL will
+#      be sent out on the specified multicast address.
+#
+#      Do not enable this option unless you are are absolutely
+#      certain you understand what you are doing.
+#
+#Default:
+# mcast_miss_addr 255.255.255.255
+
+#  TAG: mcast_miss_ttl
+# Note: This option is only available if Squid is rebuilt with the
+#       -DMULTICAST_MISS_TTL option
+#
+#      This is the time-to-live value for packets multicasted
+#      when multicasting off cache miss URLs is enabled.  By
+#      default this is set to 'site scope', i.e. 16.
+#
+#Default:
+# mcast_miss_ttl 16
+
+#  TAG: mcast_miss_port
+# Note: This option is only available if Squid is rebuilt with the
+#       -DMULTICAST_MISS_STREAM option
+#
+#      This is the port number to be used in conjunction with
+#      'mcast_miss_addr'.
+#
+#Default:
+# mcast_miss_port 3135
+
+#  TAG: mcast_miss_encode_key
+# Note: This option is only available if Squid is rebuilt with the
+#       -DMULTICAST_MISS_STREAM option
+#
+#      The URLs that are sent in the multicast miss stream are
+#      encrypted.  This is the encryption key.
+#
+#Default:
+# mcast_miss_encode_key XXXXXXXXXXXXXXXX
+
+#  TAG: nonhierarchical_direct
+#      By default, Squid will send any non-hierarchical requests
+#      (matching hierarchy_stoplist or not cachable request type) direct
+#      to origin servers.
+#
+#      If you set this to off, then Squid will prefer to send these
+#      requests to parents.
+#
+#      Note that in most configurations, by turning this off you will only
+#      add latency to these request without any improvement in global hit
+#      ratio.
+#
+#      If you are inside an firewall then see never_direct instead of
+#      this directive.
+#
+#Default:
+# nonhierarchical_direct on
+
+#  TAG: prefer_direct
+#      Normally Squid tries to use parents for most requests. If you by some
+#      reason like it to first try going direct and only use a parent if
+#      going direct fails then set this to on.
+#
+#      By combining nonhierarchical_direct off and prefer_direct on you
+#      can set up Squid to use a parent as a backup path if going direct
+#      fails.
+#
+#      Note: If you want Squid to use parents for all requests then see
+#      the never_direct directive. prefer_direct only modifies how Squid
+#      acts on cachable requests.
+#
+#Default:
+# prefer_direct off
+
+#  TAG: strip_query_terms
+#      By default, Squid strips query terms from requested URLs before
+#      logging.  This protects your user's privacy.
+#
+#Default:
+# strip_query_terms on
+
+#  TAG: coredump_dir
+#      By default Squid leaves core files in the directory from where
+#      it was started. If you set 'coredump_dir' to a directory
+#      that exists, Squid will chdir() to that directory at startup
+#      and coredump files will be left there.
+#
+#Default:
+# coredump_dir none
+#
+# Leave coredumps in the first cache dir
+coredump_dir /var/spool/squid
+
+#  TAG: redirector_bypass
+#      When this is 'on', a request will not go through the
+#      redirector if all redirectors are busy.  If this is 'off'
+#      and the redirector queue grows too large, Squid will exit
+#      with a FATAL error and ask you to increase the number of
+#      redirectors.  You should only enable this if the redirectors
+#      are not critical to your caching system.  If you use
+#      redirectors for access control, and you enable this option,
+#      then users may have access to pages that they should not
+#      be allowed to request.
+#
+#Default:
+# redirector_bypass off
+
+#  TAG: ignore_unknown_nameservers
+#      By default Squid checks that DNS responses are received
+#      from the same IP addresses that they are sent to.  If they
+#      don't match, Squid ignores the response and writes a warning
+#      message to cache.log.  You can allow responses from unknown
+#      nameservers by setting this option to 'off'.
+#
+#Default:
+# ignore_unknown_nameservers on
+
+#  TAG: digest_generation
+#      This controls whether the server will generate a Cache Digest
+#      of its contents.  By default, Cache Digest generation is
+#      enabled if Squid is compiled with USE_CACHE_DIGESTS defined.
+#
+#Default:
+# digest_generation on
+
+#  TAG: digest_bits_per_entry
+#      This is the number of bits of the server's Cache Digest which
+#      will be associated with the Digest entry for a given HTTP
+#      Method and URL (public key) combination.  The default is 5.
+#
+#Default:
+# digest_bits_per_entry 5
+
+#  TAG: digest_rebuild_period  (seconds)
+#      This is the number of seconds between Cache Digest rebuilds.
+#
+#Default:
+# digest_rebuild_period 1 hour
+
+#  TAG: digest_rewrite_period  (seconds)
+#      This is the number of seconds between Cache Digest writes to
+#      disk.
+#
+#Default:
+# digest_rewrite_period 1 hour
+
+#  TAG: digest_swapout_chunk_size      (bytes)
+#      This is the number of bytes of the Cache Digest to write to
+#      disk at a time.  It defaults to 4096 bytes (4KB), the Squid
+#      default swap page.
+#
+#Default:
+# digest_swapout_chunk_size 4096 bytes
+
+#  TAG: digest_rebuild_chunk_percentage        (percent, 0-100)
+#      This is the percentage of the Cache Digest to be scanned at a
+#      time.  By default it is set to 10% of the Cache Digest.
+#
+#Default:
+# digest_rebuild_chunk_percentage 10
+
+#  TAG: chroot
+#      Use this to have Squid do a chroot() while initializing.  This
+#      also causes Squid to fully drop root privileges after
+#      initializing.  This means, for example, that if you use a HTTP
+#      port less than 1024 and try to reconfigure, you will get an
+#      error.
+#
+#Default:
+# none
+
+#  TAG: client_persistent_connections
+#  TAG: server_persistent_connections
+#      Persistent connection support for clients and servers.  By
+#      default, Squid uses persistent connections (when allowed)
+#      with its clients and servers.  You can use these options to
+#      disable persistent connections with clients and/or servers.
+#
+#Default:
+# client_persistent_connections on
+# server_persistent_connections on
+
+#  TAG: detect_broken_pconn
+#      Some servers have been found to incorrectly signal the use
+#      of HTTP/1.0 persistent connections even on replies not
+#      compatible, causing significant delays. This server problem
+#      has mostly been seen on redirects.
+#
+#      By enabling this directive Squid attempts to detect such
+#      broken replies and automatically assume the reply is finished
+#      after 10 seconds timeout.
+#
+#Default:
+# detect_broken_pconn off
+
+#  TAG: pipeline_prefetch
+#      To boost the performance of pipelined requests to closer
+#      match that of a non-proxied environment Squid can try to fetch
+#      up to two requests in parallell from a pipeline.
+#
+#      Defaults to off for bandwidth management and access logging
+#      reasons.
+#
+#Default:
+# pipeline_prefetch off
+
+#  TAG: extension_methods
+#      Squid only knows about standardized HTTP request methods.
+#      You can add up to 20 additional "extension" methods here.
+#
+#Default:
+# none
+
+#  TAG: request_entities
+#      Squid defaults to deny GET and HEAD requests with request entities,
+#      as the meaning of such requests are undefined in the HTTP standard
+#      even if not explicitly forbidden.
+#
+#      Set this directive to on if you have clients which insists
+#      on sending request entities in GET or HEAD requests.
+#
+#Default:
+# request_entities off
+
+#  TAG: high_response_time_warning     (msec)
+#      If the one-minute median response time exceeds this value,
+#      Squid prints a WARNING with debug level 0 to get the
+#      administrators attention.  The value is in milliseconds.
+#
+#Default:
+# high_response_time_warning 0
+
+#  TAG: high_page_fault_warning
+#      If the one-minute average page fault rate exceeds this
+#      value, Squid prints a WARNING with debug level 0 to get
+#      the administrators attention.  The value is in page faults
+#      per second.
+#
+#Default:
+# high_page_fault_warning 0
+
+#  TAG: high_memory_warning
+#      If the memory usage (as determined by mallinfo) exceeds
+#      value, Squid prints a WARNING with debug level 0 to get
+#      the administrators attention.
+#
+#Default:
+# high_memory_warning 0
+
+#  TAG: store_dir_select_algorithm
+#      Set this to 'round-robin' as an alternative.
+#
+#Default:
+# store_dir_select_algorithm least-load
+
+#  TAG: forward_log
+# Note: This option is only available if Squid is rebuilt with the
+#       -DWIP_FWD_LOG option
+#
+#      Logs the server-side requests.
+#
+#      This is currently work in progress.
+#
+#Default:
+# none
+
+#  TAG: ie_refresh     on|off
+#      Microsoft Internet Explorer up until version 5.5 Service
+#      Pack 1 has an issue with transparent proxies, wherein it
+#      is impossible to force a refresh.  Turning this on provides
+#      a partial fix to the problem, by causing all IMS-REFRESH
+#      requests from older IE versions to check the origin server
+#      for fresh content.  This reduces hit ratio by some amount
+#      (~10% in my experience), but allows users to actually get
+#      fresh content when they want it.  Note that because Squid
+#      cannot tell if the user is using 5.5 or 5.5SP1, the behavior
+#      of 5.5 is unchanged from old versions of Squid (i.e. a
+#      forced refresh is impossible).  Newer versions of IE will,
+#      hopefully, continue to have the new behavior and will be
+#      handled based on that assumption.  This option defaults to
+#      the old Squid behavior, which is better for hit ratios but
+#      worse for clients using IE, if they need to be able to
+#      force fresh content.
+#
+#Default:
+# ie_refresh off
+
+#  TAG: vary_ignore_expire     on|off
+#      Many HTTP servers supporting Vary gives such objects
+#      immediate expiry time with no cache-control header
+#      when requested by a HTTP/1.0 client. This option
+#      enables Squid to ignore such expiry times until
+#      HTTP/1.1 is fully implemented.
+#      WARNING: This may eventually cause some varying
+#      objects not intended for caching to get cached.
+#
+#Default:
+# vary_ignore_expire off
+
+#  TAG: sleep_after_fork       (microseconds)
+#      When this is set to a non-zero value, the main Squid process
+#      sleeps the specified number of microseconds after a fork()
+#      system call. This sleep may help the situation where your
+#      system reports fork() failures due to lack of (virtual)
+#      memory. Note, however, that if you have a lot of child
+#      processes, then these sleep delays will add up and your
+#      Squid will not service requests for some amount of time
+#      until all the child processes have been started.
+#
+#Default:
+# sleep_after_fork 0
+
diff --git a/gosa-core/contrib/altlinux/init.ldif b/gosa-core/contrib/altlinux/init.ldif
new file mode 100644 (file)
index 0000000..9545ecf
--- /dev/null
@@ -0,0 +1,124 @@
+dn: dc=example,dc=com
+objectClass: top
+objectClass: dcObject
+objectClass: organization
+objectClass: gosaDepartment
+dc: example
+o: Example Inc.
+ou: example
+description: Main building
+
+dn: ou=Apps,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Apps
+
+dn: cn=gosa,ou=Apps,dc=example,dc=com
+objectClass: top
+objectClass: applicationProcess
+objectClass: simpleSecurityObject
+userPassword: gosa
+cn: gosa
+
+dn: cn=smbpasswd,ou=Apps,dc=example,dc=com
+objectClass: top
+objectClass: applicationProcess
+objectClass: simpleSecurityObject
+cn: smbpasswd
+userPassword: smbpasswd
+
+dn: cn=cyrus,ou=Apps,dc=example,dc=com
+objectClass: top
+objectClass: applicationProcess
+objectClass: simpleSecurityObject
+cn: cyrus
+userPassword: cyrus
+
+dn: cn=saslauthd,ou=Apps,dc=example,dc=com
+objectClass: top
+objectClass: applicationProcess
+objectClass: simpleSecurityObject
+cn: saslauthd
+userPassword: saslauthd
+
+dn: ou=Admins,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Admins
+description: Directory administrators
+
+dn: cn=admin,ou=Admins,dc=example,dc=com
+objectClass: person
+cn: admin
+sn: admin
+userPassword: secret
+
+dn: ou=People,dc=example,dc=com
+objectClass: organizationalUnit
+ou: People
+
+dn: uid=administrator,ou=People,dc=example,dc=com
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+objectClass: gosaAccount
+userPassword: secret
+sn: System
+cn: administrator
+givenName: Administrator
+uid: administrator
+
+dn: ou=Groups,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Groups
+
+dn: cn=administrator,ou=Groups,dc=example,dc=com
+objectClass: top
+objectClass: gosaObject
+objectClass: posixGroup
+gosaSubtreeACL:: OmFsbA==
+cn: administrator
+gidNumber: 999
+memberUid: administrator
+
+dn: ou=Computers,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Computers
+
+dn: uid=pdc$,ou=Computers,dc=example,dc=com
+objectClass: top
+objectClass: account
+objectClass: goImapServer
+uid: pdc$
+cn: localhost
+goImapName: mail.example.lan
+goImapConnect: {localhost:143}
+goImapAdmin: cyrus
+goImapSieveServer: localhost
+goImapSievePort: 2000
+goImapPassword: cyrus
+
+dn: dc=branch,dc=example,dc=com
+objectClass: top
+objectClass: dcObject
+objectClass: organizationalUnit
+objectClass: gosaDepartment
+dc: branch
+ou: branch
+description: Remote branch
+
+dn: ou=Addressbook,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Addressbook
+
+dn: ou=Systems,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Systems
+
+dn: ou=configs,ou=systems,dc=example,dc=com
+objectClass: organizationalUnit
+ou: configs
+
+dn: ou=gosa,ou=configs,ou=systems,dc=example,dc=com
+objectClass: organizationalUnit
+ou: gosa
+
diff --git a/gosa-core/contrib/daemon/arp-handler-d b/gosa-core/contrib/daemon/arp-handler-d
new file mode 100755 (executable)
index 0000000..b8698bc
--- /dev/null
@@ -0,0 +1,563 @@
+#!/usr/bin/perl 
+#===============================================================================
+#
+#         FILE:  gosa-support-daemon.pl
+#
+#        USAGE:  ./.gosa-support-daemon.pl
+#
+#  DESCRIPTION:  
+#
+#      OPTIONS:  ---
+# REQUIREMENTS:  ---
+#         BUGS:  ---
+#        NOTES:  ---
+#       AUTHOR:   Andreas Rettenberger, <rettenberger@gonicus.de>
+#      COMPANY:  Gonicus GmbH, Arnsberg
+#      VERSION:  1.0
+#      CREATED:  21.08.2007 15:13:51 CEST
+#     REVISION:  ---
+#===============================================================================
+
+use strict;
+use warnings;
+use Getopt::Long;
+use Config::IniFiles;
+use POSIX;
+use Fcntl;
+use Net::LDAP;
+use Net::LDAP::LDIF;
+use Net::LDAP::Entry;
+use Switch;
+
+
+my ($verbose, $cfg_file, $log_file, $pid_file, $foreground); 
+my ($timeout, $mailto, $mailfrom, $user, $group);
+my ($procid, $pid, $loglevel);
+my ($fifo_path, $max_process_timeout, $max_process );
+my %daemon_children;
+my ($ldap, $bind_phrase, $password, $ldap_base) ;
+
+$procid = -1 ;
+$foreground = 0 ;
+$verbose = 0 ;
+$max_process = 2 ;
+$max_process_timeout = 1 ;
+$ldap_base = "dc=gonicus,dc=de" ;
+#$ldap_path = "/var/run/gosa-support-daemon.socket";
+#$log_path = "/var/log/gosa-support-daemon.log";
+#$pid_path = "/var/run/gosa-support-daemon/gosa-support-daemon.pid";
+
+#---------------------------------------------------------------------------
+#  parse commandline options
+#---------------------------------------------------------------------------
+Getopt::Long::Configure( "bundling" );
+GetOptions( "v|verbose+" => \$verbose,
+        "c|config=s" => \$cfg_file,
+        "h|help" => \&usage,
+        "l|logfile=s" => \$log_file,
+        "p|pid=s" => \$pid_file,
+        "f|foreground" => \$foreground);
+
+#---------------------------------------------------------------------------
+#  read and set config parameters
+#---------------------------------------------------------------------------
+my %cfg_defaults =
+("Allgemein" =>
+ {"timeout"  => [ \$timeout, 1000 ],
+ "mailto"   => [ \$mailto, 'root@localhost' ],
+ "mailfrom" => [ \$mailfrom, 'sps-daemon@localhost' ],
+ "user"     => [ \$user, "nobody" ],
+ "group"    => [ \$group, "nogroup" ],
+ "fifo_path" => [ \$fifo_path, "/home/rettenbe/gonicus/gosa-support/tmp/fifo" ],
+ "log_file"  => [ \$log_file, "/home/rettenbe/gonicus/gosa-support/tmp/gosa-support.log" ],
+ "pid_file"  => [ \$pid_file, "/home/rettenbe/gonicus/gosa-support/tmp/gosa-support.pid" ],
+ "loglevel"     => [ \$loglevel, 1]
+ },
+"LDAP"  =>
+    {"bind" => [ \$bind_phrase, "cn=ldapadmin,dc=gonicus,dc=de" ],
+     "password" => [ \$password, "tester" ],
+    }
+ );
+&read_configfile;
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  check_cmdline_param
+#      PURPOSE:  checks all commandline parameters to validity
+#   PARAMETERS:  none
+#      RETURNS:  none
+#  DESCRIPTION:  ????
+#       THROWS:  no exceptions
+#     COMMENTS:  none
+#     SEE ALSO:  n/a
+#===============================================================================
+sub check_cmdline_param () {
+    my $err_config;
+    my $err_log;
+    my $err_pid;
+    my $err_counter = 0;
+    if( not defined( $cfg_file)) {
+        $err_config = "please specify a config file";
+        $err_counter += 1;
+    }
+    if( not defined( $log_file)) {
+        $err_log = "please specify a log file";
+        $err_counter += 1;
+    }
+    if( not defined( $pid_file)) {
+        $err_pid = "please specify a pid file";
+        $err_counter += 1;
+    }
+    if( $err_counter > 0 ) {
+        &usage( "", 1 );
+        if( defined( $err_config)) { print STDERR "$err_config\n"}
+        if( defined( $err_log)) { print STDERR "$err_log\n" }
+        if( defined( $err_pid)) { print STDERR "$err_pid\n"}
+        print STDERR "\n";
+        exit( -1 );
+    }
+}
+
+#===  FUNCTION  ================================================================
+#         NAME:  check_pid
+#      PURPOSE:  
+#   PARAMETERS:  none
+#      RETURNS:  none
+#  DESCRIPTION:  ????
+#       THROWS:  no exceptions
+#     COMMENTS:  none
+#     SEE ALSO:  n/a
+#===============================================================================
+sub check_pid { 
+    if( open( LOCK_FILE, "<$pid_file") ) {
+        $procid = <LOCK_FILE>;
+        if( defined $procid ) {
+            chomp( $procid );
+            if( -f "/proc/$procid/stat" ) {
+                my($stat) = `cat /proc/$procid/stat` =~ m/$procid \((.+)\).*/;
+                print "\t".$stat."\n";
+                if( "sps-daemon.pl" eq $stat ) {
+                    close( LOCK_FILE );
+                    exit -1;
+                }
+            }
+        }
+        close( LOCK_FILE );
+        unlink( $pid_file );
+    }
+
+    # Try to open PID file
+    if (!sysopen(LOCK_FILE, $pid_file, O_WRONLY|O_CREAT|O_EXCL, 0644)) {
+        my($msg) = "Couldn't obtain lockfile '$pid_file' ";
+        if (open(LOCK_FILE, "<", $pid_file) && ($pid = <LOCK_FILE>)) {
+            chomp($pid);
+            $msg .= "(PID $pid)\n";
+        } else {
+            $msg .= "(unable to read PID)\n";
+        }
+        if ( ! $foreground ) {
+            daemon_log( $msg."\n");
+        } else {
+            print( STDERR " $msg " );
+        }
+        exit( -1 );
+    }
+}
+
+#===  FUNCTION  ================================================================
+#         NAME:  read_configfile
+#      PURPOSE:  read the configuration file and provide the programm with 
+#                parameters
+#   PARAMETERS:  none
+#      RETURNS:  none
+#  DESCRIPTION:  ????
+#       THROWS:  no exceptions
+#     COMMENTS:  none
+#     SEE ALSO:  n/a
+#===============================================================================
+sub read_configfile {
+    my $log_time = localtime(time);
+    my $cfg;
+    if( defined( $cfg_file) && ( length($cfg_file) > 0 )) {
+        if( -r $cfg_file ) { 
+            $cfg = Config::IniFiles->new( -file => $cfg_file ); 
+        } else { 
+            usage( "Couldn't read config file: $cfg_file \n" ); 
+        }
+    } else { 
+        $cfg = Config::IniFiles->new() ; 
+    }
+
+    foreach my $section (keys %cfg_defaults) {      # "Parse" config into values
+        foreach my $param (keys %{$cfg_defaults{ $section }}) {
+            my $pinfo = $cfg_defaults{ $section }{ $param };
+            ${@$pinfo[ 0 ]} = $cfg->val( $section, $param, @$pinfo[ 1 ] );
+        }
+    }
+
+    if(-e $log_file ) { unlink $log_file }
+    daemon_log("$log_time: config file read\n");
+}
+
+#===  FUNCTION  ================================================================
+#         NAME:  daemon_log
+#      PURPOSE:  log messages to specified logfile
+#   PARAMETERS:  $msg, $level
+#      RETURNS:  ????
+#  DESCRIPTION:  Takes a message ($msg) and append it to the logfile. The 
+#                standard log-level ($level) is 1. Messages whith higher level
+#                than the verbosity-level (defined by commandline) are printed 
+#                out to commandline. Messages with log-level lower than 2 are 
+#                not logged to logfile!
+#       THROWS:  no exceptions
+#     COMMENTS:  none
+#     SEE ALSO:  n/a
+#===============================================================================
+sub daemon_log {
+    my( $msg, $level ) = @_;
+    if(not defined $msg) { return } 
+    if(not defined $level) { $level = 1 }
+    open(LOG_HANDLE, ">>$log_file");
+    if(not defined open( LOG_HANDLE, ">>$log_file" ) ) { return }
+    chomp($msg);
+    #if( $verbose >= $level ) { print "$msg"."\n" }
+    if( $level <= 1 ) { print LOG_HANDLE $msg."\n"  }
+    if( $foreground ) { print $msg."\n" }
+    close( LOG_HANDLE );
+    }
+
+#===  FUNCTION  ================================================================
+#         NAME:  signal handler
+#      PURPOSE:  catches signals from the programm and do diffrent things 
+#                than default
+#   PARAMETERS:  none
+#      RETURNS:  none
+#  DESCRIPTION:  sighandler
+#       THROWS:  no exceptions
+#     COMMENTS:  none
+#     SEE ALSO:  n/a
+#===============================================================================
+sub sigINT {
+    my $log_time = localtime(time);
+    print "INT\n";
+    if( -p $fifo_path ) {
+        close FIFO  ;
+        unlink($fifo_path) ;
+        daemon_log( "$log_time: FIFO closed after signal INT!\n") ;
+        }
+    if(defined($ldap)) {
+        $ldap->unbind;
+    }
+    $SIG{INT} = "DEFAULT" ;
+    kill INT => $$ ;
+}
+$SIG{INT} = \&sigINT ;
+
+#===  FUNCTION  ================================================================
+#         NAME:  usage
+#      PURPOSE:  
+#   PARAMETERS:  none
+#      RETURNS:  none
+#  DESCRIPTION:  print out the usage of the program
+#       THROWS:  no exceptions
+#     COMMENTS:  none
+#     SEE ALSO:  n/a
+#===============================================================================
+sub usage {
+        my( $text, $help ) = @_;
+        $text = undef if( "h" eq $text );
+        (defined $text) && print STDERR "\n$text\n";
+        if( (defined $help && $help) || (!defined $help && !defined $text) ) {
+                print STDERR << "EOF" ;
+usage: $0 [-hvf] [-c config, -l logfile, -p pidfile]
+
+    -h        : this (help) message
+    -c <file> : config file
+    -l <file> : log file (example: /var/log/sps/sps.log)
+    -p <file> : pid file (example: /var/run/sps/sps.pid)
+    -f        : foreground (don"t fork)
+    -v        : be verbose (multiple to increase verbosity)
+EOF
+        }
+        print "\n" ;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  open_fifo
+#      PURPOSE:  
+#   PARAMETERS:  $fifo_path
+#      RETURNS:  0: FIFO couldn"t be setup, 1: FIFO setup correctly
+#  DESCRIPTION:  creates a FIFO at $fifo_path
+#       THROWS:  no exceptions
+#     COMMENTS:  none
+#     SEE ALSO:  n/a
+#===============================================================================
+sub open_fifo {
+    my ($fifo_path) = @_ ;
+    my $log_time = localtime( time );
+    if( -p $fifo_path ) {
+        daemon_log("$log_time: FIFO at $fifo_path already exists\n");
+        return 0;
+        } 
+    POSIX::mkfifo($fifo_path, 0666) or die "can't mkfifo $fifo_path: $!";
+    daemon_log( "$log_time: FIFO started at $fifo_path\n" ) ;
+    return 1;
+    }
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  add_ldap_entry
+#      PURPOSE:  adds an element to ldap-tree
+#   PARAMETERS:  
+#      RETURNS:  none
+#  DESCRIPTION:  ????
+#       THROWS:  no exceptions
+#     COMMENTS:  none
+#     SEE ALSO:  n/a
+#===============================================================================
+sub add_ldap_entry {
+    my ($ldap_tree, $ldap_base, $mac, $gotoSysStatus, $ip, $interface, $desc) = @_;
+    my $dn = "cn=$mac,ou=incoming,$ldap_base";
+    my $s_res = &search_ldap_entry($ldap_tree, $ldap_base, "(|(macAddress=$mac)(dhcpHWAddress=ethernet $mac))");
+    my $c_res = $s_res->count;
+    if($c_res == 1) {
+        daemon_log("WARNING: macAddress $mac already in LDAP", 1);
+        return;
+    } elsif($c_res > 0) {
+        daemon_log("ERROR: macAddress $mac exists $c_res times in LDAP", 1);
+        return;
+    }
+
+    # create LDAP entry 
+    my $entry = Net::LDAP::Entry->new( $dn );
+    $entry->dn($dn);
+    $entry->add("objectClass" => "goHard");
+    $entry->add("cn" => $mac);
+    $entry->add("macAddress" => $mac);
+    if(defined $gotoSysStatus) {$entry->add("gotoSysStatus" => $gotoSysStatus)}
+    if(defined $ip) {$entry->add("ipHostNumber" => $ip) }
+    #if(defined $interface) { }
+    if(defined $desc) {$entry->add("description" => $desc) }
+    
+    # submit entry to LDAP
+    my $result = $entry->update ($ldap_tree); 
+        
+    # for $result->code constants please look at Net::LDAP::Constant
+    my $log_time = localtime( time );
+    if($result->code == 68) {   # entry already exists 
+        daemon_log("WARNING: $log_time: $dn ".$result->error, 3);
+    } elsif($result->code == 0) {   # everything went fine
+        daemon_log("$log_time: add entry $dn to ldap", 1);
+    } else {  # if any other error occur
+        daemon_log("ERROR: $log_time: $dn, ".$result->code.", ".$result->error, 1);
+    }
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  change_ldap_entry
+#      PURPOSE:  ????
+#   PARAMETERS:  ????
+#      RETURNS:  ????
+#  DESCRIPTION:  ????
+#       THROWS:  no exceptions
+#     COMMENTS:  none
+#     SEE ALSO:  n/a
+#===============================================================================
+sub change_ldap_entry {
+    my ($ldap_tree, $ldap_base, $mac, $gotoSysStatus ) = @_;
+    
+    # check if ldap_entry exists or not
+    my $s_res = &search_ldap_entry($ldap_tree, $ldap_base, "(|(macAddress=$mac)(dhcpHWAddress=ethernet $mac))");
+    my $c_res = $s_res->count;
+    if($c_res == 0) {
+        daemon_log("WARNING: macAddress $mac not in LDAP", 1);
+        return;
+    } elsif($c_res > 1) {
+        daemon_log("ERROR: macAddress $mac exists $c_res times in LDAP", 1);
+        return;
+    }
+
+    my $s_res_entry = $s_res->pop_entry();
+    my $dn = $s_res_entry->dn();
+    my $result = $ldap->modify( $dn, replace => {'gotoSysStatus' => $gotoSysStatus } );
+
+    # for $result->code constants please look at Net::LDAP::Constant
+    my $log_time = localtime( time );
+    if($result->code == 32) {   # entry doesnt exists 
+        &add_ldap_entry($mac, $gotoSysStatus);
+    } elsif($result->code == 0) {   # everything went fine
+        daemon_log("$log_time: entry $dn changed successful", 1);
+    } else {  # if any other error occur
+        daemon_log("ERROR: $log_time: $dn, ".$result->code.", ".$result->error, 1);
+    }
+
+    return;
+}
+
+#===  FUNCTION  ================================================================
+#         NAME:  search_ldap_entry
+#      PURPOSE:  ????
+#   PARAMETERS:  [Net::LDAP] $ldap_tree - object of an ldap-tree
+#                string $sub_tree - dn of the subtree the search is performed
+#                string $search_string - either a string or a Net::LDAP::Filter object
+#      RETURNS:  [Net::LDAP::Search] $msg - result object of the performed search
+#  DESCRIPTION:  ????
+#       THROWS:  no exceptions
+#     COMMENTS:  none
+#     SEE ALSO:  n/a
+#===============================================================================
+sub search_ldap_entry {
+    my ($ldap_tree, $sub_tree, $search_string) = @_;
+    my $msg = $ldap_tree->search( # perform a search
+                        base   => $sub_tree,
+                        filter => $search_string,
+                      ) or daemon_log("cannot perform search at ldap: $@", 1);
+#    if(defined $msg) {
+#        print $sub_tree."\t".$search_string."\t";
+#        print $msg->count."\n";
+#        foreach my $entry ($msg->entries) { $entry->dump; };
+#    }
+
+    return $msg;
+}
+
+
+
+#========= MAIN = main ========================================================
+daemon_log( "####### START DAEMON ######\n", 1 );
+&check_cmdline_param ;
+&check_pid;
+&open_fifo($fifo_path);
+
+# Just fork, if we"re not in foreground mode
+if( ! $foreground ) { $pid = fork(); }
+else { $pid = $$; }
+
+# Do something useful - put our PID into the pid_file
+if( 0 != $pid ) {
+    open( LOCK_FILE, ">$pid_file" );
+    print LOCK_FILE "$pid\n";
+    close( LOCK_FILE );
+    if( !$foreground ) { exit( 0 ) };
+}
+
+
+if( not -p $fifo_path ) { die "fifo file disappeared\n" }
+sysopen(FIFO, $fifo_path, O_RDONLY) or die "can't read from $fifo_path: $!" ;
+
+while( 1 ) {
+    # checke alle prozesse im hash daemon_children ob sie noch aktiv sind, wenn
+    # nicht, dann entferne prozess aus hash
+    while( (my $key, my $val) = each( %daemon_children) ) {
+        my $status = waitpid( $key, &WNOHANG) ;
+        if( $status == -1 ) { 
+            delete $daemon_children{$key} ; 
+            daemon_log("childprocess finished: $key", 3) ;
+        }
+    }
+
+    # ist die max_process anzahl von prozesskindern erreicht, dann warte und 
+    # prüfe erneut, ob in der zwischenzeit prozesse fertig geworden sind
+    if( keys( %daemon_children ) >= $max_process ) { 
+        sleep($max_process_timeout) ;
+        next ;
+    }
+
+    my $msg = <FIFO>;
+    if( not defined( $msg )) { next ; }
+    
+    chomp( $msg );
+    if( length( $msg ) == 0 ) { next ; }
+
+    my $forked_pid = fork();
+#=== PARENT = parent ==========================================================
+    if ( $forked_pid != 0 ) { 
+        daemon_log("childprocess forked: $forked_pid", 3) ;
+        $daemon_children{$forked_pid} = 0 ;
+    }
+#=== CHILD = child ============================================================
+    else {
+        # parse the incoming message from arp, split the message and return 
+        # the values in an array. not defined values are set to "none" 
+        #my ($mac, $ip, $interface, $arp_sig, $desc) = &parse_input( $msg ) ;
+        daemon_log( "childprocess read from arp: $fifo_path\nline: $msg", 3);
+        my ($mac, $ip, $interface, $arp_sig, $desc) = split('\s', $msg, 5);
+
+        # create connection to LDAP
+        $ldap = Net::LDAP->new( "localhost" ) or die "$@";
+        $ldap->bind($bind_phrase,
+                    password => $password,
+                    ) ;
+        
+        switch($arp_sig) {
+            case 0 {&change_ldap_entry($ldap, $ldap_base, 
+                                      $mac, "ip-changed",
+                                      )} 
+            case 1 {&change_ldap_entry($ldap, $ldap_base, 
+                                      $mac, "mac-not-whitelisted",
+                                      )}
+            case 2 {&change_ldap_entry($ldap, $ldap_base, 
+                                      $mac, "mac-in-blacklist",
+                                      )}
+            case 3 {&add_ldap_entry($ldap, $ldap_base, 
+                                   $mac, "new-mac-address", $ip, 
+                                   $interface, $desc, 
+                                   )}
+            case 4 {&change_ldap_entry($ldap, $ldap_base, 
+                                      $mac, "unauthorized-arp-request",
+                                      )}
+            case 5 {&change_ldap_entry($ldap, $ldap_base, 
+                                      $mac, "abusive-number-of-arp-requests",
+                                      )}
+            case 6 {&change_ldap_entry($ldap, $ldap_base, 
+                                      $mac, "ether-and-arp-mac-differs",
+                                      )}
+            case 7 {&change_ldap_entry($ldap, $ldap_base, 
+                                      $mac, "flood-detected",
+                                      )}
+            case 8 {&add_ldap_entry($ldap, $ldap_base, 
+                                   $mac, $ip, "new-system",
+                                   )}
+            case 9 {&change_ldap_entry($ldap, $ldap_base, 
+                                      $mac, "mac-changed",
+                                      )}
+        }
+
+
+        # ldap search
+#        my $base_phrase = "dc=gonicus,dc=de";
+#        my $filter_phrase = "cn=keinesorge";
+#        my $attrs_phrase = "cn macAdress";
+#        my $msg_search = $ldap->search( base   => $base_phrase,
+#                                        filter => $filter_phrase,
+#                                        attrs => $attrs_phrase,
+#                                        );
+#        $msg_search->code && die $msg_search->error;
+#        
+#        my @entries = $msg_search->entries;
+#        my $max = $msg_search->count;
+#        print "anzahl der entries: $max\n";
+#        my $i;
+#        for ( $i = 0 ; $i < $max ; $i++ ) {
+#            my $entry = $msg_search->entry ( $i );
+#            foreach my $attr ( $entry->attributes ) {
+#                if( not $attr eq "cn") {
+#                    next;
+#                }
+#                print join( "\n ", $attr, $entry->get_value( $attr ) ), "\n\n";
+#            }
+#        }
+
+        # ldap add
+       
+        
+        $ldap->unbind;
+        exit;
+    }
+
+}
+
+
diff --git a/gosa-core/contrib/daemon/arp-handler-d.cfg b/gosa-core/contrib/daemon/arp-handler-d.cfg
new file mode 100644 (file)
index 0000000..36c24a3
--- /dev/null
@@ -0,0 +1,14 @@
+[Allgemein]
+timeout   = 1000 
+mailto    = root@localhost
+mailfrom  = gosa-sd@localhost
+user      = rettenbe
+group     = usr
+fifo_path = /home/rettenbe/gonicus/projekte/gosa-trunk/contrib/daemon/fifo
+log_file  = /home/rettenbe/gonicus/projekte/gosa-trunk/contrib/daemon/gosa-sd.log
+pid_file  = /home/rettenbe/gonicus/projekte/gosa-trunk/contrib/daemon/gosa-sd.pid
+loglevel  = 1
+
+[LDAP]
+bind     = cn=ldapadmin,dc=gonicus,dc=de 
+password = tester
diff --git a/gosa-core/contrib/daemon/debian/README.debian b/gosa-core/contrib/daemon/debian/README.debian
new file mode 100644 (file)
index 0000000..100bd2d
--- /dev/null
@@ -0,0 +1,11 @@
+README.Debian for GOto 3.0
+--------------------------
+
+* Configuring GOto 3.0
+
+You need a proper LDAP/FAI/GOsa setup to make this run. More
+text will follow later. Sorry.
+
+----
+Cajus Pollmeier <cajus@debian.org>  Fri 02 Jun 2006 16:23:50 +0200
+
diff --git a/gosa-core/contrib/daemon/debian/changelog b/gosa-core/contrib/daemon/debian/changelog
new file mode 100644 (file)
index 0000000..3367299
--- /dev/null
@@ -0,0 +1,6 @@
+gosa-sd (1.0-1) unstable; urgency=low
+
+  * Initial release
+
+ -- Cajus Pollmeier <cajus@debian.org>  Fri,  7 Dec 2007 11:37:45 +0100
+
diff --git a/gosa-core/contrib/daemon/debian/compat b/gosa-core/contrib/daemon/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/gosa-core/contrib/daemon/debian/control b/gosa-core/contrib/daemon/debian/control
new file mode 100644 (file)
index 0000000..b7b873d
--- /dev/null
@@ -0,0 +1,40 @@
+Source: gosa-si
+Section: utils
+Priority: optional
+Maintainer: Cajus Pollmeier <cajus@debian.org>
+Standards-Version: 3.7.2.2
+Build-Depends: debhelper(>= 4.2.32), dpatch
+
+Package: gosa-si-common
+Architecture: any
+Depends: libconfig-inifiles-perl, libcrypt-rijndael-perl, libxml-simple-perl, libipc-shareable-perl, libdata-dumper-simple-perl, libmime-perl
+Suggests: gosa-si-daemon, gosa-si-client
+Description: GOsa support infrastructure
+ This package provides common library functionality used by the
+ infrastructure server and client packages.
+ .
+ GOsa is a combination of system-administrator and end-user web
+ interface, designed to handle LDAP based setups.
+
+Package: gosa-si-daemon
+Architecture: any
+Depends: gosa-si-common
+Suggests: gosa
+Description: GOsa support infrastructure daemon
+ This package provides everything you need in order to deploy a simple
+ or distributed GOsa support infrastructure. It can be used to trigger
+ certain actions or retrieve information from clients.
+ .
+ GOsa is a combination of system-administrator and end-user web
+ interface, designed to handle LDAP based setups.
+
+Package: gosa-si-client
+Architecture: any
+Depends: gosa-si-common
+Suggests: gosa
+Description: GOsa support infrastructure client
+ This package lets you join to a GOsa support infrastructure as a
+ client in order to provide information or to act on events.
+ .
+ GOsa is a combination of system-administrator and end-user web
+ interface, designed to handle LDAP based setups.
diff --git a/gosa-core/contrib/daemon/debian/copyright b/gosa-core/contrib/daemon/debian/copyright
new file mode 100644 (file)
index 0000000..d7463ef
--- /dev/null
@@ -0,0 +1,8 @@
+This package was debianized by Cajus Pollmeier
+<cajus@debian.org> on Mon, 25 Jun 2007 12:57:35 +0100.
+
+Copyright: GPL2
+
+This code is released under the terms of the GPLv2 license.
+
+See /usr/share/common-licenses/GPL-2 for the full license.
diff --git a/gosa-core/contrib/daemon/debian/default b/gosa-core/contrib/daemon/debian/default
new file mode 100644 (file)
index 0000000..10df929
--- /dev/null
@@ -0,0 +1,2 @@
+# /etc/default/gosa-si - configure the init script
+START_BUS=0
diff --git a/gosa-core/contrib/daemon/debian/gosa-si-client.dirs b/gosa-core/contrib/daemon/debian/gosa-si-client.dirs
new file mode 100644 (file)
index 0000000..763e43a
--- /dev/null
@@ -0,0 +1,4 @@
+usr/share/ltsp/plugins/ltsp-build-client/common
+usr/share/ltsp/scripts
+usr/sbin
+etc/default
diff --git a/gosa-core/contrib/daemon/debian/gosa-si-client.install b/gosa-core/contrib/daemon/debian/gosa-si-client.install
new file mode 100644 (file)
index 0000000..8155a9c
--- /dev/null
@@ -0,0 +1,12 @@
+debian/goto                     etc/default
+build-goto-client               usr/sbin
+plugins/001-ltsp-addon-packages usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/020-ssh-pubkey-login    usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/001-goto-ldap-packages  usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/001-sane-packages       usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/020-nx-client           usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/010-goto-ldap-files     usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/999-goto-ldap-final     usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/001-snmp-packages       usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/030-late-packages-goto  usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/000-goto-ldap-vars      usr/share/ltsp/plugins/ltsp-build-client/common
diff --git a/gosa-core/contrib/daemon/debian/gosa-si-common.dirs b/gosa-core/contrib/daemon/debian/gosa-si-common.dirs
new file mode 100644 (file)
index 0000000..763e43a
--- /dev/null
@@ -0,0 +1,4 @@
+usr/share/ltsp/plugins/ltsp-build-client/common
+usr/share/ltsp/scripts
+usr/sbin
+etc/default
diff --git a/gosa-core/contrib/daemon/debian/gosa-si-common.install b/gosa-core/contrib/daemon/debian/gosa-si-common.install
new file mode 100644 (file)
index 0000000..8155a9c
--- /dev/null
@@ -0,0 +1,12 @@
+debian/goto                     etc/default
+build-goto-client               usr/sbin
+plugins/001-ltsp-addon-packages usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/020-ssh-pubkey-login    usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/001-goto-ldap-packages  usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/001-sane-packages       usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/020-nx-client           usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/010-goto-ldap-files     usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/999-goto-ldap-final     usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/001-snmp-packages       usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/030-late-packages-goto  usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/000-goto-ldap-vars      usr/share/ltsp/plugins/ltsp-build-client/common
diff --git a/gosa-core/contrib/daemon/debian/gosa-si-server.dirs b/gosa-core/contrib/daemon/debian/gosa-si-server.dirs
new file mode 100644 (file)
index 0000000..763e43a
--- /dev/null
@@ -0,0 +1,4 @@
+usr/share/ltsp/plugins/ltsp-build-client/common
+usr/share/ltsp/scripts
+usr/sbin
+etc/default
diff --git a/gosa-core/contrib/daemon/debian/gosa-si-server.init b/gosa-core/contrib/daemon/debian/gosa-si-server.init
new file mode 100755 (executable)
index 0000000..26fb1cb
--- /dev/null
@@ -0,0 +1,91 @@
+#!/bin/sh
+# Start/stop the GOsa support daemon infrastructure.
+#
+### BEGIN INIT INFO
+# Provides:          gosa-si
+# Required-Start:    $syslog $time
+# Required-Stop:     $syslog $time
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: GOsa message bus and server component
+# Description:       gosa-si establishes the communication between a couple of
+#                    GOsa hosting servers and optionally clients to do event
+#                    signaling for all communication partners.
+### END INIT INFO
+
+# Sanity checks
+test -f /usr/sbin/gosa-si-server || exit 0
+test -f /usr/sbin/gosa-si-bus || exit 0
+
+# Load defaults
+START_BUS=0
+[ -r /etc/default/gosa-si ] && . /etc/default/gosa-si
+
+# Load LSB support functions
+. /lib/lsb/init-functions
+
+
+start_bus() {
+       start-stop-daemon --start --quiet --pidfile /var/run/gosa-si-bus.pid --name gosa-si-bus --startas /usr/sbin/gosa-si-bus
+}
+
+
+start_server() {
+       start-stop-daemon --start --quiet --pidfile /var/run/gosa-si-server.pid --name gosa-si-server --startas /usr/sbin/gosa-si-server -- $1
+}
+
+
+stop_bus() {
+       start-stop-daemon --stop --retry 5 --quiet --pidfile /var/run/gosa-si-bus.pid --name gosa-si-bus
+}
+
+
+stop_server() {
+       start-stop-daemon --stop --retry 5 --quiet --pidfile /var/run/gosa-si-server.pid --name gosa-si-server
+}
+
+
+case "$1" in
+start)  log_daemon_msg "Starting GOsa support infrastructure"
+       if [ "$START_BUS" == "1" ]; then
+               log_progress_msg "bus"
+               start_bus
+               log_progress_msg "daemon"
+               start_server
+       else
+               log_progress_msg "daemon"
+               start_server --no-bus
+       fi
+        log_end_msg $?
+       ;;
+stop)   log_daemon_msg "Stopping GOsa support infrastructure"
+       if [ "$START_BUS" == "1" ]; then
+               log_progress_msg "daemon"
+               stop_server
+               log_progress_msg "bus"
+               stop_bus
+       else
+               log_progress_msg "daemon"
+               stop_server
+       fi
+        log_end_msg $?
+        ;;
+reload|force-reload|restart) log_daemon_msg "Restarting GOsa support infrastructure" 
+       if [ "$START_BUS" == "1" ]; then
+               stop_server
+               stop_bus
+               start_bus
+               start_server --no-bus
+               log_progress_msg "done"
+       else
+               stop_server
+               start_server --no-bus
+               log_progress_msg "done"
+       fi
+        log_end_msg $?
+        ;;
+*)     log_action_msg "Usage: /etc/init.d/gosa-si {start|stop|restart|reload|force-reload}"
+        exit 2
+        ;;
+esac
+exit 0
diff --git a/gosa-core/contrib/daemon/debian/gosa-si-server.install b/gosa-core/contrib/daemon/debian/gosa-si-server.install
new file mode 100644 (file)
index 0000000..8155a9c
--- /dev/null
@@ -0,0 +1,12 @@
+debian/goto                     etc/default
+build-goto-client               usr/sbin
+plugins/001-ltsp-addon-packages usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/020-ssh-pubkey-login    usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/001-goto-ldap-packages  usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/001-sane-packages       usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/020-nx-client           usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/010-goto-ldap-files     usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/999-goto-ldap-final     usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/001-snmp-packages       usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/030-late-packages-goto  usr/share/ltsp/plugins/ltsp-build-client/common
+plugins/000-goto-ldap-vars      usr/share/ltsp/plugins/ltsp-build-client/common
diff --git a/gosa-core/contrib/daemon/debian/rules b/gosa-core/contrib/daemon/debian/rules
new file mode 100755 (executable)
index 0000000..78cd0aa
--- /dev/null
@@ -0,0 +1,77 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+build: patch 
+       #********************************************************
+       #*  Building ltsp-goto into a Debian/GNU Linux Package  *
+       #*                    please stand by                   *
+       #********************************************************
+
+clean: clean-patched unpatch
+clean-patched:
+       dh_testdir
+       rm -f install-stamp 
+       -rm -f debian/files
+       -rm -rf debian/tmp
+       -rm -f debian/substvars
+       dh_clean
+
+unpatch:
+       dpatch deapply-all
+       rm -rf patch-stamp debian/patched
+
+install: install-stamp
+install-stamp: 
+       dh_testdir
+       dh_testroot
+       dh_clean -k
+       dh_installdirs
+
+       # Create a copy, remove svn stuff
+       -mkdir debian/tmp
+       -for i in `ls | grep -v debian`; do \
+               cp -R $$i debian/tmp ; \
+       done
+       -find debian/tmp -name '*.svn' -type d -exec rm -rf {} \; 2> /dev/null
+
+       touch install-stamp
+
+patch: patch-stamp
+patch-stamp:
+       dpatch apply-all
+       dpatch cat-all >patch-stamp
+
+binary-indep: install
+       dh_testdir
+       dh_testroot
+       
+       dh_install
+       dh_installdocs 
+       dh_installcron
+       dh_installexamples
+       dh_installchangelogs
+       #dh_installdebconf
+       #dh_installcron -p goto-agents-printmanager
+       dh_link
+       dh_strip
+       dh_compress
+       dh_fixperms 
+       dh_perl
+       dh_installdeb
+       dh_shlibdeps
+       
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+source diff:                                                                  
+       @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false
+
+binary: binary-indep 
+.PHONY: build install clean binary-indep binary
+
+binary-arch:
+
diff --git a/gosa-core/contrib/daemon/gosa-si-bus b/gosa-core/contrib/daemon/gosa-si-bus
new file mode 100755 (executable)
index 0000000..a56a38e
--- /dev/null
@@ -0,0 +1,1183 @@
+#!/usr/bin/perl
+#===============================================================================
+#
+#         FILE:  gosa-server
+#
+#        USAGE:  ./gosa-server
+#
+#  DESCRIPTION:
+#
+#      OPTIONS:  ---
+# REQUIREMENTS:  ---
+#         BUGS:  ---
+#        NOTES: 
+#       AUTHOR:   (Andreas Rettenberger), <rettenberger@gonicus.de>
+#      COMPANY:
+#      VERSION:  1.0
+#      CREATED:  12.09.2007 08:54:41 CEST
+#     REVISION:  ---
+#===============================================================================
+
+use strict;
+use warnings;
+use Getopt::Long;
+use Config::IniFiles;
+use POSIX;
+use Time::HiRes qw( gettimeofday );
+
+use IO::Socket::INET;
+use Crypt::Rijndael;
+use MIME::Base64;
+use Digest::MD5  qw(md5 md5_hex md5_base64);
+use XML::Simple;
+use Data::Dumper;
+use Sys::Syslog qw( :DEFAULT setlogsock);
+use Cwd;
+use File::Spec;
+use IPC::Shareable qw( :lock);
+IPC::Shareable->clean_up_all;
+
+my ($cfg_file, $default_cfg_file, %cfg_defaults, $foreground, $verbose);
+my ($bus_activ, $bus_passwd, $bus_ip, $bus_port, $bus_address, $bus, $bus_mac_address);
+my ($pid_file, $procid, $pid, $log_file, $my_own_address);
+my (%free_child, %busy_child, $child_max, $child_min, %child_alive_time, $child_timeout);
+my ($xml, $bus_cipher, $known_daemons, $shmkh);
+
+$foreground = 0 ;
+$known_daemons = {};
+$shmkh = tie($known_daemons, 'IPC::Shareable', undef, {create => 1, 
+                                                            exclusive => 1, 
+                                                            mode => 0666, 
+                                                            destroy => 1,
+                                                            });
+%cfg_defaults =
+("general" =>
+    {"log_file" => [\$log_file, "/var/run/".$0.".log"],
+    "pid_file" => [\$pid_file, "/var/run/".$0.".pid"],
+    "child_max" => [\$child_max, 10],
+    "child_min" => [\$child_min, 3],
+    "child_timeout" => [\$child_timeout, 180],
+
+    },
+"bus" =>
+    {"bus_activ" => [\$bus_activ, "on"],
+    "bus_passwd" => [\$bus_passwd, ""],
+    "bus_port" => [\$bus_port, "20080"],
+    }
+    );
+
+#===  FUNCTION  ================================================================
+#         NAME:  read_configfile
+#   PARAMETERS:  cfg_file - string - 
+#      RETURNS:  nothing 
+#  DESCRIPTION:  read cfg_file and set variables
+#===============================================================================
+sub read_configfile {
+    my $cfg;
+    if( defined( $cfg_file) && ( length($cfg_file) > 0 )) {
+        if( -r $cfg_file ) {
+            $cfg = Config::IniFiles->new( -file => $cfg_file );
+        } else {
+            print STDERR "Couldn't read config file!";
+        }
+    } else {
+        $cfg = Config::IniFiles->new() ;
+    }
+    foreach my $section (keys %cfg_defaults) {
+        foreach my $param (keys %{$cfg_defaults{ $section }}) {
+            my $pinfo = $cfg_defaults{ $section }{ $param };
+            ${@$pinfo[ 0 ]} = $cfg->val( $section, $param, @$pinfo[ 1 ] );
+        }
+    }
+}
+
+#===  FUNCTION  ================================================================
+#         NAME:  logging
+#   PARAMETERS:  level - string - default 'info' 
+#                msg - string - 
+#                facility - string - default 'LOG_DAEMON' 
+#      RETURNS:  nothing
+#  DESCRIPTION:  function for logging
+#===============================================================================
+sub daemon_log {
+    my( $msg, $level ) = @_;
+    if(not defined $msg) { return }
+    if(not defined $level) { $level = 1 }
+    if(defined $log_file){
+        open(LOG_HANDLE, ">>$log_file");
+        if(not defined open( LOG_HANDLE, ">>$log_file" )) { 
+            print STDERR "cannot open $log_file: $!";
+            return }
+        chomp($msg);
+        if($level <= $verbose){
+            print LOG_HANDLE $msg."\n";
+            if(defined $foreground) { print $msg."\n" }
+        }
+    }
+    close( LOG_HANDLE );
+#    my ($msg, $level, $facility) = @_;
+#    if(not defined $msg) {return}
+#    if(not defined $level) {$level = "info"}
+#    if(not defined $facility) {$facility = "LOG_DAEMON"}
+#    openlog($0, "pid,cons,", $facility);
+#    syslog($level, $msg);
+#    closelog;
+#    return;
+}
+
+#===  FUNCTION  ================================================================
+#         NAME:  check_cmdline_param
+#   PARAMETERS:  nothing
+#      RETURNS:  nothing
+#  DESCRIPTION:  validates commandline parameter 
+#===============================================================================
+sub check_cmdline_param () {
+    my $err_config;
+    my $err_counter = 0;
+    if( not defined( $cfg_file)) {
+        my $cwd = getcwd;
+        my $name = "/etc/gosa/gosa-si-bus.conf";
+        $cfg_file = File::Spec->catfile( $cwd, $name );
+        print STDERR "no conf file specified\n   try to use default: $cfg_file\n";
+    }
+    if( $err_counter > 0 ) {
+        &usage( "", 1 );
+        if( defined( $err_config)) { print STDERR "$err_config\n"}
+        print STDERR "\n";
+        exit( -1 );
+    }
+}
+
+#===  FUNCTION  ================================================================
+#         NAME:  check_pid
+#   PARAMETERS:  nothing
+#      RETURNS:  nothing
+#  DESCRIPTION:  handels pid processing
+#===============================================================================
+sub check_pid {
+    $pid = -1;
+    # Check, if we are already running
+    if( open(LOCK_FILE, "<$pid_file") ) {
+        $pid = <LOCK_FILE>;
+        if( defined $pid ) {
+            chomp( $pid );
+            if( -f "/proc/$pid/stat" ) {
+                my($stat) = `cat /proc/$pid/stat` =~ m/$pid \((.+)\).*/;
+                if( $0 eq $stat ) {
+                    close( LOCK_FILE );
+                    exit -1;
+                }
+            }
+        }
+        close( LOCK_FILE );
+        unlink( $pid_file );
+    }
+
+    # create a syslog msg if it is not to possible to open PID file
+    if (not sysopen(LOCK_FILE, $pid_file, O_WRONLY|O_CREAT|O_EXCL, 0644)) {
+        my($msg) = "Couldn't obtain lockfile '$pid_file' ";
+        if (open(LOCK_FILE, '<', $pid_file)
+                && ($pid = <LOCK_FILE>))
+        {
+            chomp($pid);
+            $msg .= "(PID $pid)\n";
+        } else {
+            $msg .= "(unable to read PID)\n";
+        }
+        if( ! ($foreground) ) {
+            openlog( $0, "cons,pid", "daemon" );
+            syslog( "warning", $msg );
+            closelog();
+        }
+        else {
+            print( STDERR " $msg " );
+        }
+        exit( -1 );
+    }
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  usage
+#   PARAMETERS:  nothing
+#      RETURNS:  nothing
+#  DESCRIPTION:  print out usage text to STDERR
+#===============================================================================
+sub usage {
+    print STDERR << "EOF" ;
+usage: $0 [-hvf] [-c config]
+
+    -h        : this (help) message
+    -c <file> : config file
+    -f        : foreground, process will not be forked to background
+    -v        : be verbose (multiple to increase verbosity)
+EOF
+    print "\n" ;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  sig_int_handler
+#   PARAMETERS:  signal - string - signal arose from system
+#      RETURNS:  noting
+#  DESCRIPTION:  handels tasks to be done befor signal becomes active
+#===============================================================================
+sub sig_int_handler {
+    my ($signal) = @_;
+    if($bus){
+        close($bus);
+        print "$bus closed\n";
+    }
+    print "$signal\n";
+    IPC::Shareable->clean_up;
+    exit(1);
+}
+$SIG{INT} = \&sig_int_handler;
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  get_ip_and_mac 
+#   PARAMETERS:  nothing
+#      RETURNS:  (ip, mac) 
+#  DESCRIPTION:  executes /sbin/ifconfig and parses the output, the first occurence 
+#                of a inet address is returned as well as the mac address in the line
+#                above the inet address
+#===============================================================================
+sub get_ip_and_mac {
+    my $ip = "0.0.0.0.0"; # Defualt-IP
+    my $mac_address = "00:00:00:00:00:00";  # Default-MAC
+    my @ifconfig = qx(/sbin/ifconfig);
+    foreach(@ifconfig) {
+        if (/Hardware Adresse (\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2})/) {
+            $mac_address = "$1:$2:$3:$4:$5:$6";
+            next;
+        }
+        if (/inet Adresse:(\d+).(\d+).(\d+).(\d+)/) {
+            $ip = "$1.$2.$3.$4";
+            last;
+        }
+    }
+    return ($ip, $mac_address);
+}
+
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  activating_child
+#   PARAMETERS:  msg - string - incoming message
+#                host - string - host from which the incomming message comes
+#      RETURNS:  nothing
+#  DESCRIPTION:  handels the distribution of incoming messages to working childs
+#===============================================================================
+sub activating_child {
+    my ($msg, $host) = @_;
+    my $child = &get_processing_child();
+    my $pipe_wr = $$child{'pipe_wr'};
+    daemon_log("activating: childpid: $$child{'pid'}", 5);
+    print $pipe_wr $msg.".".$host."\n";
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  get_processing_child
+#   PARAMETERS:  nothing
+#      RETURNS:  child - hash - holding the process id and the references to the pipe
+#                               handles pipe_wr and pipe_rd
+#  DESCRIPTION:  handels the forking, reactivating and keeping alive tasks
+#===============================================================================
+sub get_processing_child {
+    my $child;
+    # checking %busy_child{pipe_wr} if msg is 'done', then set child from busy to free
+    while(my ($key, $val) = each(%busy_child)) {
+        # check wether process still exists
+        my $exitus_pid = waitpid($key, WNOHANG);
+        if($exitus_pid != 0) {
+            delete $busy_child{$key};
+            daemon_log( "prozess:$key wurde aus busy_child entfernt\n", 5);
+            next;
+        }
+
+        # check wether process sitll works
+        my $fh = $$val{'pipe_rd'};
+        $fh->blocking(0); 
+        my $child_answer;
+        if(not $child_answer = <$fh>) { next }
+        chomp($child_answer);
+        if($child_answer eq "done") {
+            delete $busy_child{$key};
+            $free_child{$key} = $val;
+        }
+    }
+
+    while(my ($key, $val) = each(%free_child)) {
+        my $exitus_pid = waitpid($key, WNOHANG);
+        if($exitus_pid != 0) {
+            delete $free_child{$key};
+            daemon_log( "prozess:$key wurde aus free_child entfernt\n", 5);
+        }
+        daemon_log("free child:$key\n", 5);
+    }
+    # check @free_child and @busy_child
+    my $free_len = scalar(keys(%free_child));
+    my $busy_len = scalar(keys(%busy_child));
+    daemon_log("free children $free_len, busy children $busy_len\n",5);
+    
+    # if there is a free child, let the child work 
+    if($free_len > 0){
+        my @keys = keys(%free_child);
+        $child = $free_child{$keys[0]};
+        if(defined $child) {
+            $busy_child{$$child{'pid'}} = $child ; 
+            delete $free_child{$$child{'pid'}};          
+        }
+        return $child;
+    }
+    
+    # no free child, try to fork another one 
+    if($free_len + $busy_len < $child_max) {
+                
+        daemon_log("not enough children, create a new one\n",5);
+
+        # New pipes for communication
+        my( $PARENT_wr, $PARENT_rd );
+        my( $CHILD_wr, $CHILD_rd );
+        pipe( $CHILD_rd,  $PARENT_wr );
+        pipe( $PARENT_rd, $CHILD_wr  );
+        $PARENT_wr->autoflush(1);
+        $CHILD_wr->autoflush(1);
+
+        ############
+        # fork child
+        ############
+        my $child_pid = fork();
+        
+        #CHILD
+        if($child_pid == 0) {
+            # Close unused pipes
+            close( $CHILD_rd );
+            close( $CHILD_wr );
+            while( 1 ) {
+                my $rbits = "";
+                vec( $rbits, fileno $PARENT_rd , 1 ) = 1;
+
+                # waiting child_timeout for jobs to do
+                my $nf = select($rbits, undef, undef, $child_timeout);
+                if($nf < 0 ) {
+                    # if $nf < 1, error handling
+                    die "select(): $!\n";
+                } elsif (! $nf) {
+                    # if already child_min childs are alive, then leave loop
+                    $free_len = scalar(keys(%free_child));
+                    $busy_len = scalar(keys(%busy_child));
+                    if($free_len + $busy_len >= $child_min) {
+                        last;
+                    } else {
+                        redo;
+                    }
+                } 
+
+                # a job for a child arise
+                if ( vec $rbits, fileno $PARENT_rd, 1 ) {
+                    # read everything from pipe
+                    my $msg = "";
+                    $PARENT_rd->blocking(0);
+                    while(1) {
+                        my $read = <$PARENT_rd>;
+                        if(not defined $read) { last}
+                        $msg .= $read;
+                    }
+
+                    # forward the job msg to another function
+                    &process_incoming_msg($msg);
+                    daemon_log("processing of msg finished", 5);
+
+                    # important!!! wait until child says 'done', until then child is set from busy to free
+                    print $PARENT_wr "done";
+                    redo;
+                }
+            }
+            # childs leaving the loop are allowed to die
+            exit(0);
+
+        #PARENT
+        } else {
+            # Close unused pipes
+            close( $PARENT_rd );
+            close( $PARENT_wr );
+            # add child to child alive hash
+            my %child_hash = (
+                    'pid' => $child_pid,
+                    'pipe_wr' => $CHILD_wr,
+                    'pipe_rd' => $CHILD_rd,
+                    );
+
+            $child = \%child_hash;
+            $busy_child{$$child{'pid'}} = $child;
+            return $child;
+        }
+    }
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  process_incoming_msg
+#   PARAMETERS:  crypted_msg - string - incoming crypted message
+#      RETURNS:  nothing
+#  DESCRIPTION:  handels the proceeded distribution to the appropriated functions
+#===============================================================================
+sub process_incoming_msg {
+    my ($crypted_msg) = @_;
+    if(not defined $crypted_msg) {
+        daemon_log("function 'process_incoming_msg': got no msg", 7);
+        return;
+    }
+    $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
+    $crypted_msg = $1;
+    my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
+
+    daemon_log("msg from host:\n\t$host", 1);
+    daemon_log("crypted_msg:\n\t$crypted_msg", 7);
+
+    my @valid_keys;
+    my @daemon_keys = keys %$known_daemons;
+    foreach my $daemon_key (@daemon_keys) {    
+        if($daemon_key =~ "^$daemon_key") {
+            push(@valid_keys, $daemon_key);
+        }
+    }
+
+    my $l = @valid_keys;
+    daemon_log("number of valid daemons: $l\n", 7);
+
+    my ($msg, $msg_hash);
+    my $msg_flag = 0;    
+
+    # collect addresses from possible incoming clients
+    foreach my $host_key (@valid_keys) {
+        eval{
+            daemon_log( "daemon: $host_key\n", 7);
+            my $key_passwd = $known_daemons->{$host_key}->{passwd};
+            daemon_log("daemon_passwd: $key_passwd\n", 7);
+            my $key_cipher = &create_ciphering($key_passwd);
+            $msg = &decrypt_msg($crypted_msg, $key_cipher);
+            daemon_log("daemon decrypted msg:$msg", 7);
+            $msg_hash = $xml->XMLin($msg, ForceArray=>1);
+        };
+        if($@) {
+            daemon_log("msg processing raise error", 7);
+            daemon_log("error string: $@", 7);
+            $msg_flag += 1;
+        } else {
+            last;
+        }
+    } 
+    
+    if($msg_flag >= $l)  {
+        daemon_log("\nERROR: do not understand the message:\n$msg" , 1);
+        return;
+    }
+
+    my $header = &get_content_from_xml_hash($msg_hash, "header");
+    my $target = &get_content_from_xml_hash($msg_hash, "target");
+
+    daemon_log("header from msg:\n\t$header", 1);
+    daemon_log("msg to process:\n\t$msg", 5);
+    daemon_log("msg is for: \n\t$target", 7);
+
+    if($target eq $bus_address) {
+        # msg is for bus
+        if($header eq 'here_i_am'){ &here_i_am($msg_hash)}
+        elsif($header eq 'confirm_new_passwd'){ &confirm_new_passwd($msg_hash)}
+        elsif($header eq 'got_ping') { &got_ping($msg_hash)} 
+        elsif($header eq 'ping') { &ping($msg_hash)}
+        elsif($header eq 'who_has') { &who_has($msg_hash)}
+        elsif($header eq 'new_client') { &new_client($msg_hash)}
+        elsif($header eq 'delete_client') { &delete_client($msg_hash)}
+    } else {
+        # msg is for any other server
+        my @targets = @{$msg_hash->{target}};
+        my $len_targets = @targets;
+    
+        if ($len_targets == 0){
+            # no targets specified
+
+            daemon_log("ERROR: no target specified for msg $header", 1);
+
+        } elsif ($targets[0] eq "*"){
+            # all deamons in known_daemons are targets
+
+            my $target = $targets[0];
+            my $source = @{$msg_hash->{source}}[0];
+            my @target_addresses = keys(%$known_daemons);
+            foreach my $target_address (@target_addresses) {
+                if ($target_address eq $source) { next; }
+                if ($target_address eq $bus_address) { next ; }
+                $msg_hash->{target} = [$target_address];
+                &send_msg_hash2address($msg_hash, $target_address);
+            }
+
+        } else {
+            # a list of targets is specified            
+            
+            my $target_address;
+            foreach $target_address (@targets) {
+                if (exists $known_daemons->{$target_address}) {
+                    &send_msg_hash2address($msg_hash, $target_address);
+                } else { 
+                    my @daemon_addresses = keys %$known_daemons;
+                    my $daemon_address;
+                    foreach $daemon_address (@daemon_addresses) {
+                        if (exists $known_daemons->{$daemon_address}->{clients}->{$target_address}) {
+                            my $header = &get_content_from_xml_hash($msg_hash, "header");
+                            &send_msg_hash2address($msg_hash, $daemon_address);
+                            daemon_log("bus forwards msg $header for client $target_address to server $daemon_address", 3);
+                            last;
+                        }
+                    }
+
+                }
+            }
+        }
+    }
+
+    &print_known_daemons_hash();
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  get_content_of_known_daemons
+#   PARAMETERS:
+#      RETURNS:
+#  DESCRIPTION:
+#===============================================================================
+#sub get_content_of_known_daemons {
+#    my ($host, $content) = @_;
+#    return;
+#}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_passwd
+#   PARAMETERS:  nothing
+#      RETURNS:  new_passwd - string 
+#  DESCRIPTION:  creates a 32 bit long random passwd out of "a".."z","A".."Z",0..9
+#===============================================================================
+sub create_passwd {
+    my $new_passwd = "";
+    for(my $i=0; $i<31; $i++) {
+        $new_passwd .= ("a".."z","A".."Z",0..9)[int(rand(62))]
+    }
+    return $new_passwd;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_ciphering
+#   PARAMETERS:  passwd - string - used to create ciphering
+#      RETURNS:  cipher - object 
+#  DESCRIPTION:  creates a Crypt::Rijndael::MODE_CBC object with passwd as key
+#===============================================================================
+sub create_ciphering {
+    my ($passwd) = @_;
+    $passwd = substr(md5_hex("$passwd") x 32, 0, 32);
+    my $iv = substr(md5_hex('GONICUS GmbH'),0, 16);
+
+    #daemon_log("iv: $iv", 7);
+    #daemon_log("key: $passwd", 7);
+    my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC());
+    $my_cipher->set_iv($iv);
+    return $my_cipher;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  encrypt_msg
+#   PARAMETERS:  msg - string - message to encrypt
+#                my_cipher - ref - reference to a Crypt::Rijndael object
+#      RETURNS:  crypted_msg - string - crypted message
+#  DESCRIPTION:  crypts the incoming message with the Crypt::Rijndael module
+#===============================================================================
+sub encrypt_msg {
+    my ($msg, $my_cipher) = @_;
+    if(not defined $my_cipher) { print "no cipher object\n"; }
+    $msg = "\0"x(16-length($msg)%16).$msg;
+    my $crypted_msg = $my_cipher->encrypt($msg);
+    chomp($crypted_msg = &encode_base64($crypted_msg));
+    return $crypted_msg;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  decrypt_msg
+#   PARAMETERS:  crypted_msg - string - message to decrypt
+#                my_cipher - ref - reference to a Crypt::Rijndael object
+#      RETURNS:  msg - string - decrypted message
+#  DESCRIPTION:  decrypts the incoming message with the Crypt::Rijndael module
+#===============================================================================
+sub decrypt_msg {
+    my ($crypted_msg, $my_cipher) = @_ ;
+    $crypted_msg = &decode_base64($crypted_msg);
+    my $msg = $my_cipher->decrypt($crypted_msg); 
+    $msg =~ s/^\0*//g;
+    return $msg;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_xml_hash
+#   PARAMETERS:  header - string - message header (required)
+#                source - string - where the message come from (required)
+#                target - string - where the message should go to (required)
+#                [header_value] - string - something usefull (optional)
+#      RETURNS:  hash - hash - nomen est omen
+#  DESCRIPTION:  creates a key-value hash, all values are stored in a array
+#===============================================================================
+sub create_xml_hash {
+    my ($header, $source, $target, $header_value) = @_ ;
+    
+    if (not defined $header || not defined $source || not defined $target) {
+        daemon_log("ERROR: create_xml_hash function is invoked with uncompleted parameters", 7);
+    }
+
+    my $hash = {
+            header => [$header],
+            source => [$source],
+            target => [$target],
+            $header => [$header_value],
+    };
+    #daemon_log("create_xml_hash:", 7),
+    #chomp(my $tmp = Dumper $hash);
+    #daemon_log("\t$tmp\n", 7);
+    return $hash
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_xml_string
+#   PARAMETERS:  xml_hash - hash - hash from function create_xml_hash
+#      RETURNS:  xml_string - string - xml string representation of the hash
+#  DESCRIPTION:  transform the hash to a string using XML::Simple module
+#===============================================================================
+sub create_xml_string {
+    my ($xml_hash) = @_ ;
+    my $xml_string = $xml->XMLout($xml_hash, RootName => 'xml');
+    $xml_string =~ s/[\n]+//g;
+    return $xml_string;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  add_content2xml_hash
+#   PARAMETERS:  xml_ref - ref - reference to a hash from function create_xml_hash
+#                element - string - key for the hash
+#                content - string - value for the hash
+#      RETURNS:  nothing 
+#  DESCRIPTION:  add key-value pair to xml_ref, if key alread exists, then append value to list
+#===============================================================================
+sub add_content2xml_hash {
+    my ($xml_ref, $element, $content) = @_;
+    if(not exists $$xml_ref{$element} ) {
+        $$xml_ref{$element} = [];
+    }
+    my $tmp = $$xml_ref{$element};
+    push(@$tmp, $content);
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  get_content_from_xml_hash
+#   PARAMETERS:  xml_ref - ref - reference of the xml hash
+#                element - string - key of the value you want
+#      RETURNS:  value - string - if key is either header, target or source
+#                value - list - for all other keys in xml hash
+#  DESCRIPTION:  
+#===============================================================================
+sub get_content_from_xml_hash {
+    my ($xml_ref, $element) = @_;
+    my $result = $xml_ref->{$element};
+    if( $element eq "header" || $element eq "target" || $element eq "source") {
+        return @$result[0];
+    }
+    return @$result;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  open_socket
+#   PARAMETERS:  PeerAddr - string - something like 192.168.1.1 or 192.168.1.1:10000
+#                [PeerPort] - string - necessary if port not appended by PeerAddr
+#      RETURNS:  socket - IO::Socket::INET
+#  DESCRIPTION:  open a socket to PeerAddr 
+#===============================================================================
+sub open_socket {
+    my ($PeerAddr, $PeerPort) = @_ ;
+    if(defined($PeerPort)){
+        $PeerAddr = $PeerAddr.":".$PeerPort;
+    }
+    my $socket;
+    $socket = new IO::Socket::INET(PeerAddr => $PeerAddr ,
+            Porto => "tcp" ,
+            Type => SOCK_STREAM,
+            Reuse => 1,
+            Timeout => 5,
+            );
+    if(not defined $socket) {
+        return;
+    }
+    return $socket;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  read_from_socket
+#   PARAMETERS:  socket - fh - filehandel to read from  
+#      RETURNS:  result - string - readed characters from socket
+#  DESCRIPTION:  reads data from socket in 16 byte steps
+#===============================================================================
+sub read_from_socket {
+    my ($socket) = @_;
+
+    $socket->blocking(1);
+    my $result = <$socket>;
+    $socket->blocking(0);
+    my $part_msg;
+    while ($part_msg = <$socket>) {
+        if (not defined $part_msg) { last; }
+        $result .= $part_msg;
+    }
+    
+    #my $result = "";
+    #my $len = 16;
+    #while($len == 16){
+    #    my $char;
+    #    $len = sysread($socket, $char, 16);
+    #    if($len != 16) { last }
+    #    if($len != 16) { last }
+    #    $result .= $char;
+    #}
+    return $result;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  send_msg_hash2address
+#   PARAMETERS:  msg_hash - hash - xml_hash created with function create_xml_hash
+#                PeerAddr string - socket address to send msg
+#                PeerPort string - socket port, if not included in socket address
+#      RETURNS:  nothing
+#  DESCRIPTION:  ????
+#===============================================================================
+sub send_msg_hash2address {
+    my ($msg_hash, $address) = @_ ;
+
+    # fetch header for logging
+    my $header = &get_content_from_xml_hash($msg_hash, "header");
+
+    # generate xml string
+    my $msg_xml = &create_xml_string($msg_hash);
+
+    # fetch the appropriated passwd from hash
+    my $passwd = $known_daemons->{$address}->{passwd};
+
+    # create a ciphering object
+    my $act_cipher = &create_ciphering($passwd);
+
+    # encrypt xml msg
+    my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher);
+
+    # open socket
+    my $socket = &open_socket($address);
+    if(not defined $socket){
+        daemon_log("ERROR: cannot send '$header'-msg to $address , server not reachable", 1);
+        return;
+    }
+
+    # send xml msg
+    print $socket $crypted_msg."\n";
+
+    close $socket;
+    daemon_log("send '$header'-msg to $address", 5);
+    daemon_log("crypted_msg:\n\t$crypted_msg", 7);
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  send_msg_hash2all
+#   PARAMETERS:  msg_hash - hash - xml_hash created with function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  send msg_hash to all registered daemons
+#===============================================================================
+sub send_msg_hash2all {
+    my ($msg_hash) = @_;
+
+    # fetch header for logging
+    my $header = &get_content_from_xml_hash($msg_hash, "header");
+
+    # generate xml string
+    my $msg_xml = &create_xml_string($msg_hash);
+
+    # fetch a list of all target addresses 
+    my @targets = keys(%$known_daemons);
+
+    # itterates through the list an send each the msg
+    foreach my $target (@targets) {
+        if($target eq $bus_address) {next};   # do not send msg to bus
+
+        # fetch the appropriated passwd
+        my $passwd = $known_daemons->{$target}->{passwd};
+
+        # create ciphering object
+        my $act_cipher = &create_ciphering($passwd);
+
+        # encrypt xml msg
+        my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher);
+
+        # open socket
+        my $socket = &open_socket($target);
+        if(not defined $socket){
+            daemon_log("ERROR: cannot open socket to $target , server not reachable", 1);
+            &update_known_daemons_entry(hostname=>$target, status=>"down");
+            next;
+        }
+
+        # send xml msg
+        print $socket $crypted_msg."\n";
+
+        close $socket;
+        daemon_log("send '$header'-msg to $target", 5);
+        daemon_log("crypted_msg:\n\t$crypted_msg", 7);
+    }
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  here_i_am
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  process the incoming msg 'here_i_am'
+#===============================================================================
+sub here_i_am {
+    my ($msg_hash) = @_ ;
+    my $source = &get_content_from_xml_hash($msg_hash, "source");
+
+    my $new_passwd = &create_passwd();
+
+    # create known_daemons entry
+    &create_known_daemons_entry($source);
+    &update_known_daemons_entry(hostname=>$source, status=>"registered", passwd=>$bus_passwd);
+
+    # create outgoing msg
+    my $out_hash = &create_xml_hash("new_passwd", "$bus_ip:$bus_port", $source, $new_passwd);
+    &send_msg_hash2address($out_hash, $source);
+
+    # change passwd, reason
+    # &send_msg_hash2address takes $known_daemons->{"$source"}->{passwd} to cipher msg
+    &update_known_daemons_entry(hostname=>$source, status=>"new_passwd", passwd=>$new_passwd);
+
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  confirm_new_passwd
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+sub confirm_new_passwd {
+    my ($msg_hash) = @_ ;
+    my $source = &get_content_from_xml_hash($msg_hash, "source");
+    &update_known_daemons_entry(hostname=>$source, status=>"confirmed_new_passwd");
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  ping
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+sub ping {
+    my ($msg_hash) = @_ ;
+    my $source = &get_content_from_xml_hash($msg_hash, "source");   
+    &update_known_daemons_entry(hostname=>$source, status=>"ping");
+    my $out_hash = &create_xml_hash("got_ping", $bus_address, $source);
+    &send_msg_hash2address($out_hash, $source);
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  make ping
+#   PARAMETERS:  address - string - address which should be pinged
+#      RETURNS:  nothing
+#  DESCRIPTION:  send ping message to address
+#===============================================================================
+sub make_ping {
+    my ($address) = @_;
+    daemon_log("ping:$address\n", 1);
+    my $out_hash = &create_xml_hash("ping", "$bus_ip:$bus_port", $address);
+    &send_msg_hash2address($out_hash, $address);
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  got_ping
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+sub got_ping {
+    my ($msg_hash) = @_;
+    my $source = &get_content_from_xml_hash($msg_hash, "source");
+    &update_known_daemons_entry(hostname=>$source, status=>"got_ping");
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  new_client
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+sub new_client {
+    my ($msg_hash) = @_ ;
+    my $source = &get_content_from_xml_hash($msg_hash, "source");
+    my $header = &get_content_from_xml_hash($msg_hash, "header");
+    my $new_client = (&get_content_from_xml_hash($msg_hash, $header))[0];
+    
+    &update_known_daemons_entry(hostname=>$source, client=>$new_client);
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  delete_client
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+sub delete_client {
+    my ($msg_hash) = @_ ;
+    my $source = &get_content_from_xml_hash($msg_hash, "source");
+    my $header = &get_content_from_xml_hash($msg_hash, "header");
+    my $del_client = (&get_content_from_xml_hash($msg_hash, $header))[0];
+   
+    if (not exists $known_daemons->{$source}->{$del_client}) {
+        daemon_log
+    }
+    delete $known_daemons->{$source}->{$del_client};
+    
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  print_known_daemons_hash
+#   PARAMETERS:  nothing
+#      RETURNS:  nothing
+#  DESCRIPTION:  nome est omen
+#===============================================================================
+sub print_known_daemons_hash {
+    my ($tmp) = @_;
+    print "####################################\n";
+    print "# status of known_daemons\n";
+    my $hosts;
+    my $host_hash;
+    $shmkh->shlock(LOCK_EX);
+    my @hosts = keys %$known_daemons;
+    foreach my $host (@hosts) {
+        my $status = $known_daemons->{$host}->{status} ;
+        my $passwd = $known_daemons->{$host}->{passwd};
+        my $timestamp = $known_daemons->{$host}->{timestamp};
+        my @clients = keys %{$known_daemons->{$host}->{clients}};
+        my $client_string = join(", ", @clients);
+        print "$host\n";
+        print "\tstatus:    $status\n";
+        print "\tpasswd:    $passwd\n";
+        print "\ttimestamp: $timestamp\n";
+        print "\tclients:   $client_string\n";
+        
+    }
+    $shmkh->shunlock(LOCK_EX);
+    print "####################################\n\n";
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_known_daemons_entry
+#   PARAMETERS:  hostname - string - ip address and port of host
+#      RETURNS:  nothing
+#  DESCRIPTION:  nome est omen
+#===============================================================================
+sub create_known_daemons_entry {
+    my ($hostname) = @_;
+    $shmkh->shlock(LOCK_EX);
+    $known_daemons->{$hostname} = {};
+    $known_daemons->{$hostname}->{status} = "none";
+    $known_daemons->{$hostname}->{passwd} = "none";
+    $known_daemons->{$hostname}->{timestamp} = "none";
+    $known_daemons->{$hostname}->{clients} = {};
+    $shmkh->shunlock(LOCK_EX); 
+    return;  
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  update_known_daemons_entry
+#   PARAMETERS:  hostname - string - ip address and port of host (required)
+#                status - string - (optional)
+#                passwd - string - (optional)
+#                client - string - ip address and port of client (optional)
+#      RETURNS:  nothing
+#  DESCRIPTION:  nome est omen and updates each time the timestamp of hostname
+#===============================================================================
+sub update_known_daemons_entry {
+    my $arg = {
+        hostname => undef, status => undef, passwd => undef,
+        client => undef,
+        @_ };
+    my $hostname = $arg->{hostname};
+    my $status = $arg->{status};
+    my $passwd = $arg->{passwd};
+    my $client = $arg->{client};
+
+    if (not defined $hostname) {
+        daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1);
+        return;
+    }
+
+    my ($seconds, $minutes, $hours, $monthday, $month,
+    $year, $weekday, $yearday, $sommertime) = localtime(time);
+    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
+    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
+    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
+    $month+=1;
+    $month = $month < 10 ? $month = "0".$month : $month;
+    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
+    $year+=1900;
+    my $t = "$year$month$monthday$hours$minutes$seconds";
+
+    $shmkh->shlock(LOCK_EX);
+    if (defined $status) {
+        $known_daemons->{$hostname}->{status} = $status;
+    }
+    if (defined $passwd) {
+        $known_daemons->{$hostname}->{passwd} = $passwd;
+    }
+    if (defined $client) {
+        $known_daemons->{$hostname}->{clients}->{$client} = "";
+    }
+    $known_daemons->{$hostname}->{timestamp} = $t;
+    $shmkh->shunlock(LOCK_EX);
+    return;
+}
+
+
+#==== MAIN = main ==============================================================
+
+#  parse commandline options
+Getopt::Long::Configure( "bundling" );
+GetOptions("h|help" => \&usage,
+           "c|config=s" => \$cfg_file,
+           "f|foreground" => \$foreground,
+           "v|verbose+" => \$verbose,
+           );
+
+#  read and set config parameters
+&check_cmdline_param ;
+&read_configfile;
+&check_pid;
+
+$SIG{CHLD} = 'IGNORE';
+
+# restart daemon log file
+if(-e $log_file ) { unlink $log_file }
+daemon_log("$0 started!");
+
+# Just fork, if we"re not in foreground mode
+if( ! $foreground ) { $pid = fork(); }
+else { $pid = $$; }
+
+# Do something useful - put our PID into the pid_file
+if( 0 != $pid ) {
+    open( LOCK_FILE, ">$pid_file" );
+    print LOCK_FILE "$pid\n";
+    close( LOCK_FILE );
+    if( !$foreground ) { exit( 0 ) };
+}
+
+# detect own ip and mac address
+($bus_ip, $bus_mac_address) = &get_ip_and_mac(); 
+if (not defined $bus_ip) {
+    die "EXIT: ip address of $0 could not be detected";
+}
+daemon_log("bus ip address detected: $bus_ip", 1);
+daemon_log("bus mac address detected: $bus_mac_address", 1);
+
+
+# setup xml parser
+$xml = new XML::Simple();
+
+# create cipher object
+$bus_cipher = &create_ciphering($bus_passwd);
+$bus_address = "$bus_ip:$bus_port";
+
+# create reading and writing vectors
+my $rbits = my $wbits = my $ebits = "";
+
+# open the bus socket
+if($bus_activ eq "on") {
+    $bus = IO::Socket::INET->new(LocalPort => $bus_port,
+            Type => SOCK_STREAM,
+            Reuse => 1,
+            Listen => 20,
+            ) or die "kann kein TCP-Server an Port $bus_port sein: $@\n";
+    vec($rbits, fileno $bus, 1) = 1;
+    vec($wbits, fileno $bus, 1) = 1;
+    print "start bus at $bus_ip:$bus_port\n";        
+}
+
+# add bus to known_daemons 
+&create_known_daemons_entry($bus_address);
+&update_known_daemons_entry(hostname=>$bus_address, status=>"bus", passwd=>$bus_passwd);
+
+
+while(1) {
+    my $nf = select($rbits, $wbits, undef, undef);
+    # error handling
+    if($nf < 0 ) { 
+    }
+
+    # something is coming in 
+    if(vec $rbits, fileno $bus, 1 ) {
+        my $client = $bus->accept();
+        my $other_end = getpeername($client);
+        if(not defined $other_end) {
+            daemon_log("Gegenstelle konnte nicht identifiziert werden: $!\n");
+        } else {
+            my ($port, $iaddr) = unpack_sockaddr_in($other_end);
+            my $actual_ip = inet_ntoa($iaddr);
+            daemon_log("\naccept client from $actual_ip\n", 5);
+            my $in_msg = &read_from_socket($client);
+            if(defined $in_msg){
+                &activating_child($in_msg, $actual_ip);
+            } else {
+                daemon_log("cannot read from $actual_ip\n",1);
+            }
+        }
+        close($client);        
+    }
+
+}
+
+
diff --git a/gosa-core/contrib/daemon/gosa-si-bus.conf-template b/gosa-core/contrib/daemon/gosa-si-bus.conf-template
new file mode 100644 (file)
index 0000000..7ca56e9
--- /dev/null
@@ -0,0 +1,13 @@
+[general]
+log_file = /var/log/gosa-si-bus.log
+pid_file = /var/run/gosa-si-bus.pid
+child_max = 10
+child_min = 2
+child_timeout = 10
+
+[bus]
+bus_activ = on
+bus_passwd = secret-bus-password
+bus_ip = 127.0.0.1
+bus_port = 20080
+
diff --git a/gosa-core/contrib/daemon/gosa-si-client b/gosa-core/contrib/daemon/gosa-si-client
new file mode 100755 (executable)
index 0000000..3825940
--- /dev/null
@@ -0,0 +1,1109 @@
+#!/usr/bin/perl
+#===============================================================================
+#
+#         FILE:  gosa-server
+#
+#        USAGE:  ./gosasc
+#
+#  DESCRIPTION:
+#
+#      OPTIONS:  ---
+# REQUIREMENTS:  ---
+#         BUGS:  ---
+#        NOTES:
+#       AUTHOR:   (Andreas Rettenberger), <rettenberger@gonicus.de>
+#      COMPANY:
+#      VERSION:  1.0
+#      CREATED:  12.09.2007 08:54:41 CEST
+#     REVISION:  ---
+#===============================================================================
+
+use strict;
+use warnings;
+use Getopt::Long;
+use Config::IniFiles;
+use POSIX;
+use Time::HiRes qw( gettimeofday );
+
+use Fcntl;
+use IO::Socket::INET;
+use Crypt::Rijndael;
+use MIME::Base64;
+use Digest::MD5  qw(md5 md5_hex md5_base64);
+use XML::Simple;
+use Data::Dumper;
+use Sys::Syslog qw( :DEFAULT setlogsock);
+use File::Spec;
+use Cwd;
+use GosaSupportDaemon;
+
+
+my ($cfg_file, %cfg_defaults, $foreground, $verbose, $pid_file, $procid, $pid, $log_file);
+my ($server_address, $server_ip, $server_port, $server_domain, $server_passwd, $server_cipher, $server_timeout);
+my ($client_address, $client_ip, $client_port, $client_mac_address);
+my ($input_socket, $rbits, $wbits, $ebits, $xml, $known_hosts);
+my (@events);
+
+# default variables
+my $event_dir = "/etc/gosac/events";
+$known_hosts = {};
+$foreground = 0 ;
+%cfg_defaults =
+("general" =>
+    {"log_file" => [\$log_file, "/var/run/".$0.".log"],
+    "pid_file" => [\$pid_file, "/var/run/".$0.".pid"],
+    },
+"client" => 
+    {"client_port" => [\$client_port, "20083"],
+    },
+"server" =>
+    {"server_ip" => [\$server_ip, ""],
+    "server_port" => [\$server_port, "20081"],
+    "server_passwd" => [\$server_passwd, ""],
+    "server_timeout" => [\$server_timeout, 10],
+    "server_domain" => [\$server_domain, ""],
+    },
+    );
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  read_configfile
+#   PARAMETERS:  cfg_file - string - 
+#      RETURNS:  
+#  DESCRIPTION: 
+#===============================================================================
+sub read_configfile {
+    my $cfg;
+    if( defined( $cfg_file) && ( length($cfg_file) > 0 )) {
+        if( -r $cfg_file ) {
+            $cfg = Config::IniFiles->new( -file => $cfg_file );
+        } else {
+            print STDERR "Couldn't read config file!";
+        }
+    } else {
+        $cfg = Config::IniFiles->new() ;
+    }
+    foreach my $section (keys %cfg_defaults) {
+        foreach my $param (keys %{$cfg_defaults{ $section }}) {
+            my $pinfo = $cfg_defaults{ $section }{ $param };
+            ${@$pinfo[ 0 ]} = $cfg->val( $section, $param, @$pinfo[ 1 ] );
+        }
+    }
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  logging
+#   PARAMETERS:  level - string - default 'info' 
+#                msg - string - 
+#                facility - string - default 'LOG_DAEMON' 
+#      RETURNS:  
+#  DESCRIPTION: 
+#===============================================================================
+sub daemon_log {
+    my( $msg, $level ) = @_;
+    if(not defined $msg) { return }
+    if(not defined $level) { $level = 1 }
+    if(defined $log_file){
+        open(LOG_HANDLE, ">>$log_file");
+        if(not defined open( LOG_HANDLE, ">>$log_file" )) { 
+            print STDERR "cannot open $log_file: $!";
+            return }
+        chomp($msg);
+        if($level <= $verbose){
+            print LOG_HANDLE $msg."\n";
+            if(defined $foreground) { print $msg."\n" }
+        }
+    }
+    close( LOG_HANDLE );
+#    my ($msg, $level, $facility) = @_;
+#    if(not defined $msg) {return}
+#    if(not defined $level) {$level = "info"}
+#    if(not defined $facility) {$facility = "LOG_DAEMON"}
+#    openlog($0, "pid,cons,", $facility);
+#    syslog($level, $msg);
+#    closelog;
+#    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME: check_cmdline_param
+#   PARAMETERS: 
+#      RETURNS:  
+#  DESCRIPTION: 
+#===============================================================================
+sub check_cmdline_param () {
+    my $err_config;
+    my $err_counter = 0;
+    if( not defined( $cfg_file)) {
+        #$err_config = "please specify a config file";
+        #$err_counter += 1;
+        my $cwd = getcwd;
+        my $name = "/etc/gosa/gosa-si-client.conf";
+        $cfg_file = File::Spec->catfile( $cwd, $name );
+        print STDERR "no conf file specified\n   try to use default: $cfg_file\n";        
+    }
+    if( $err_counter > 0 ) {
+        &usage( "", 1 );
+        if( defined( $err_config)) { print STDERR "$err_config\n"}
+        print STDERR "\n";
+        exit( -1 );
+    }
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME: check_pid
+#   PARAMETERS:
+#      RETURNS:
+#  DESCRIPTION:
+#===============================================================================
+sub check_pid {
+    $pid = -1;
+    # Check, if we are already running
+    if( open(LOCK_FILE, "<$pid_file") ) {
+        $pid = <LOCK_FILE>;
+        if( defined $pid ) {
+            chomp( $pid );
+            if( -f "/proc/$pid/stat" ) {
+                my($stat) = `cat /proc/$pid/stat` =~ m/$pid \((.+)\).*/;
+                if( $0 eq $stat ) {
+                    close( LOCK_FILE );
+                    exit -1;
+                }
+            }
+        }
+        close( LOCK_FILE );
+        unlink( $pid_file );
+    }
+
+    # create a syslog msg if it is not to possible to open PID file
+    if (not sysopen(LOCK_FILE, $pid_file, O_WRONLY|O_CREAT|O_EXCL, 0644)) {
+        my($msg) = "Couldn't obtain lockfile '$pid_file' ";
+        if (open(LOCK_FILE, '<', $pid_file)
+                && ($pid = <LOCK_FILE>))
+        {
+            chomp($pid);
+            $msg .= "(PID $pid)\n";
+        } else {
+            $msg .= "(unable to read PID)\n";
+        }
+        if( ! ($foreground) ) {
+            openlog( $0, "cons,pid", "daemon" );
+            syslog( "warning", $msg );
+            closelog();
+        }
+        else {
+            print( STDERR " $msg " );
+        }
+        exit( -1 );
+    }
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  get_ip_and_mac 
+#   PARAMETERS:  nothing
+#      RETURNS:  (ip, mac) 
+#  DESCRIPTION:  executes /sbin/ifconfig and parses the output, the first occurence 
+#                of a inet address is returned as well as the mac address in the line
+#                above the inet address
+#===============================================================================
+sub get_ip_and_mac {
+    my $ip = "0.0.0.0.0"; # Defualt-IP
+    my $mac = "00:00:00:00:00:00";  # Default-MAC
+    my @ifconfig = qx(/sbin/ifconfig);
+    foreach(@ifconfig) {
+        if (/Hardware Adresse (\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2})/) {
+            $mac = "$1:$2:$3:$4:$5:$6";
+            next;
+        }
+        if (/inet Adresse:(\d+).(\d+).(\d+).(\d+)/) {
+            $ip = "$1.$2.$3.$4";
+            last;
+        }
+    }
+    return ($ip, $mac);
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  usage
+#   PARAMETERS: 
+#      RETURNS:  
+#  DESCRIPTION: 
+#===============================================================================
+sub usage {
+        my( $text, $help ) = @_;
+        $text = undef if( "h" eq $text );
+        (defined $text) && print STDERR "\n$text\n";
+        if( (defined $help && $help) || (!defined $help && !defined $text) ) {
+                print STDERR << "EOF" ;
+usage: $0 [-hvf] [-c config]
+
+    -h        : this (help) message
+    -c <file> : config file
+    -f        : foreground, process will not be forked to background
+    -v        : be verbose (multiple to increase verbosity)
+EOF
+        }
+        print "\n" ;
+}
+
+#===  FUNCTION  ================================================================
+#         NAME:  get_server_addresses
+#   PARAMETERS:  
+#      RETURNS:  
+#  DESCRIPTION:  
+#===============================================================================
+sub get_server_addresses {
+    my $domain= shift;
+    my @result;
+    my $dig_cmd= 'dig +nocomments srv _gosad._tcp.'.$domain;
+
+    my $output= `$dig_cmd 2>&1`;
+    open (PIPE, "$dig_cmd 2>&1 |");
+    while(<PIPE>) {
+        chomp $_;
+        # If it's not a comment
+        if($_ =~ m/^[^;]/) {
+            my @matches= split /\s+/;
+
+            # Push hostname with port
+            if($matches[3] eq 'SRV') {
+                push @result, $matches[7].':'.$matches[6];
+            } elsif ($matches[3] eq 'A') {
+                my $i=0;
+
+                # Substitute the hostname with the ip address of the matching A record
+                foreach my $host (@result) {
+                    if ((split /\:/, $host)[0] eq $matches[0]) {
+                        $result[$i]= $matches[4].':'.(split /\:/, $host)[1];
+                    }
+                    $i++;
+                }
+            }
+        }
+    }
+    close(PIPE);
+    return @result;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  register_at_server
+#   PARAMETERS:  
+#      RETURNS:  
+#  DESCRIPTION:  
+#===============================================================================
+sub register_at_server {
+    my ($tmp) = @_;
+
+    # create new passwd and ciphering object for client-server communication
+    my $new_server_passwd = &create_passwd();
+    my $new_server_cipher;
+
+    # detect all client accepted events
+    opendir(DIR, $event_dir) 
+        or daemon_log("cannot find directory $event_dir!\ngosac starts without any accepting events!", 1);
+    my $file_name;
+    @events = ();
+    while(defined($file_name = readdir(DIR))){
+        if ($file_name eq "." || $file_name eq "..") {
+            next;
+        }
+        push(@events, $file_name);
+    }
+    my $events = join(",", @events);
+    daemon_log("found events: $events", 1);
+
+    # fill in all possible servers
+    my @servers;
+    if (defined $server_domain) {
+        my @tmp_servers = &get_server_addresses($server_domain);
+        foreach my $server (@tmp_servers) { unshift(@servers, $server); }
+    }
+    # add server address from config file at first position of server list
+    if (defined $server_address) {
+        unshift(@servers, $server_address);
+    }
+    daemon_log("found servers in configuration file and via DNS:", 5);
+    foreach my $server (@servers) {
+        daemon_log("\t$server", 5);
+    }
+
+    my ($rout, $wout, $reg_server);
+    foreach my $server (@servers) {
+        # create msg hash
+        my $register_hash = &create_xml_hash("here_i_am", $client_address, $server);
+        &add_content2xml_hash($register_hash, "new_passwd", $new_server_passwd);
+        &add_content2xml_hash($register_hash, "client_mac_address", $client_mac_address);
+        &add_content2xml_hash($register_hash, "events", $events);
+
+        # send xml hash to server with general server passwd
+        my $answer = &send_msg_hash2address($register_hash, $server, $server_passwd);
+        
+        # sending fails, no sens to wait for response
+        if ($answer ne "done") { next; }
+    
+        # waiting for response
+        daemon_log("waiting for response...\n", 5);
+        my $nf = select($rout=$rbits, $wout=$wbits, undef, $server_timeout);
+
+        # something is coming in
+        if(vec $rout, fileno $input_socket, 1) {
+            my $crypted_msg;
+            my $client = $input_socket->accept();
+            my $other_end = getpeername($client);
+            if(not defined $other_end) {
+                daemon_log("client cannot be identified: $!\n");
+            } else {
+                my ($port, $iaddr) = unpack_sockaddr_in($other_end);
+                my $actual_ip = inet_ntoa($iaddr);
+                daemon_log("\naccept client from $actual_ip\n", 5);
+                my $in_msg = &read_from_socket($client);
+                if(defined $in_msg){
+                    chomp($in_msg);
+                    $crypted_msg = $in_msg;
+                } else {
+                    daemon_log("cannot read from $actual_ip\n", 5);
+                }
+            }
+            close($client);
+            
+            # validate acknowledge msg from server
+            $new_server_cipher = &create_ciphering($new_server_passwd);
+            my $msg_hash;
+            eval {
+                my $decrypted_msg = &decrypt_msg($crypted_msg, $new_server_cipher);
+                daemon_log("decrypted register msg: $decrypted_msg", 5);
+                $msg_hash = $xml->XMLin($decrypted_msg, ForceArray=>1);
+            };
+            if($@) {
+                daemon_log("ERROR: do not understand the incoming message:" , 5);  
+                daemon_log("$@", 7); 
+            } else {
+                my $header = &get_content_from_xml_hash($msg_hash, "header");
+                if($header eq "registered") {
+                    $reg_server = $server;
+                    last;
+                } elsif($header eq "denied") {
+                    my $reason = (&get_content_from_xml_hash($msg_hash, "denied"))[0];
+                    daemon_log("registration at $server denied: $reason", 1);
+                } else {
+                    daemon_log("cannot register at $server", 1);
+                }
+            }
+        }
+        # kommt antwort nicht, dann probiere es mit dem nächsten in der liste
+
+    }
+    
+    if(defined $reg_server) {
+        daemon_log("registered at $reg_server", 1);
+    } else {
+        daemon_log("cannot register at any server", 1);
+        daemon_log("exiting!!!", 1);
+        exit(1);
+    }
+
+    # update the global available variables
+    $server_address = $reg_server;
+    $server_passwd = $new_server_passwd;
+    $server_cipher = $new_server_cipher;
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_xml_hash
+#   PARAMETERS:  
+#      RETURNS:
+#  DESCRIPTION:
+#===============================================================================
+sub create_xml_hash {
+    my ($header, $source, $target, $header_value) = @_;
+    my $hash = {
+            header => [$header],
+            source => [$source],
+            target => [$target],
+            $header => [$header_value],
+    };
+    daemon_log("create_xml_hash:", 7),
+    chomp(my $tmp = Dumper $hash);
+    daemon_log("\t$tmp\n", 7);
+    return $hash
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_xml_string
+#   PARAMETERS:  
+#      RETURNS:
+#  DESCRIPTION:
+#===============================================================================
+sub create_xml_string {
+    my ($xml_hash) = @_ ;
+    my $xml_string = $xml->XMLout($xml_hash, RootName => 'xml');
+    $xml_string =~ s/[\n]+//g;
+    daemon_log("create_xml_string:\n\t$xml_string\n", 7);
+    return $xml_string;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  add_content2xml_hash
+#   PARAMETERS:  
+#      RETURNS:
+#  DESCRIPTION:
+#===============================================================================
+sub add_content2xml_hash {
+    my ($xml_ref, $element, $content) = @_;
+    if(not exists $$xml_ref{$element} ) {
+        $$xml_ref{$element} = [];
+    }
+    my $tmp = $$xml_ref{$element};
+    push(@$tmp, $content);
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  get_content_from_xml_hash
+#   PARAMETERS:  ref : reference to the xml hash
+#                string: key of the value you want
+#      RETURNS:  STRING AND ARRAY
+#  DESCRIPTION:  if key of the hash is either 'header', 'target' or 'source' the 
+#                function returns a string cause it is expected that these keys
+#                do just have one value, all other keys returns an array!!!
+#===============================================================================
+sub get_content_from_xml_hash {
+    my ($xml_ref, $element) = @_;
+    my $result = $xml_ref->{$element};
+    if( $element eq "header" || $element eq "target" || $element eq "source") {
+        return @$result[0];
+    }
+    return @$result;
+}
+
+#    my ($xml_ref, $element) = @_;
+#    if (exists $xml_ref->{$element}) {
+#        my $result = $xml_ref->{$element};
+#        if( $element eq "header" || $element eq "target" || $element eq "source") {
+#            return @$result[0];
+#        } else {
+#            return @$result;
+#        }
+#        
+#    } else {
+#        my $result = ();
+#        return @$result;
+#    }
+#}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  encrypt_msg
+#   PARAMETERS:
+#      RETURNS:
+#  DESCRIPTION:
+#===============================================================================
+sub encrypt_msg {
+    my ($msg, $my_cipher) = @_;
+    if(not defined $my_cipher) { print "no cipher object\n"; }
+    $msg = "\0"x(16-length($msg)%16).$msg;
+    my $crypted_msg = $my_cipher->encrypt($msg);
+    chomp($crypted_msg = &encode_base64($crypted_msg));
+    return $crypted_msg;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  decrypt_msg
+#   PARAMETERS:
+#      RETURNS:
+#  DESCRIPTION:
+#===============================================================================
+sub decrypt_msg {
+    my ($crypted_msg, $my_cipher) = @_ ;
+    $crypted_msg = &decode_base64($crypted_msg);
+    my $msg = $my_cipher->decrypt($crypted_msg); 
+    $msg =~ s/\0*//g;
+    return $msg;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_ciphering
+#   PARAMETERS:  
+#      RETURNS:  cipher object
+#  DESCRIPTION:  
+#===============================================================================
+sub create_ciphering {
+    my ($passwd) = @_;
+    $passwd = substr(md5_hex("$passwd") x 32, 0, 32);
+    my $iv = substr(md5_hex('GONICUS GmbH'),0, 16);
+
+    #daemon_log("iv: $iv", 7);
+    #daemon_log("key: $passwd", 7);
+    my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC());
+    $my_cipher->set_iv($iv);
+    return $my_cipher;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_passwd
+#   PARAMETERS:
+#      RETURNS:  cipher object
+#  DESCRIPTION:
+#===============================================================================
+sub create_passwd {
+    my $new_passwd = "";
+    for(my $i=0; $i<31; $i++) {
+        $new_passwd .= ("a".."z","A".."Z",0..9)[int(rand(62))]
+    }
+
+    return $new_passwd;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  send_msg_hash2address
+#   PARAMETERS:  msg string - xml message
+#                PeerAddr string - socket address to send msg
+#                PeerPort string - socket port, if not included in socket address
+#      RETURNS:  nothing
+#  DESCRIPTION:  ????
+#===============================================================================
+sub send_msg_hash2address {
+    my ($msg_hash, $address, $passwd) = @_ ;
+
+    # fetch header for logging
+    my $header = @{$msg_hash->{header}}[0];
+
+    # generiere xml string
+    my $msg_xml = &create_xml_string($msg_hash);
+
+    # hole das entsprechende passwd aus dem hash
+    if(not defined $passwd) {
+        if(exists $known_hosts->{$address}) {
+            $passwd = $known_hosts->{$address}->{passwd};
+        } elsif ($address eq $server_address) {
+            $passwd = $server_passwd;
+        } else {
+            daemon_log("$address not known, neither as server nor as client", 1);
+            return "failed";
+        }
+    }
+
+    # erzeuge ein ciphering object
+    my $act_cipher = &create_ciphering($passwd);
+
+    # encrypt xml msg
+    my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher);
+
+    # Ã¶ffne socket
+    my $socket = &open_socket($address);
+    if(not defined $socket){
+        daemon_log("cannot open socket to $address, server not reachable", 1);
+        daemon_log("cannot send '$header'-msg", 1);
+        return "failed";
+    }
+
+    # versende xml msg
+    print $socket $crypted_msg."\n";
+
+    # schließe socket
+    close $socket;
+
+    daemon_log("send '$header'-msg to $address", 5);
+    daemon_log("crypted_msg:\n\t$crypted_msg", 7);
+
+    return "done";
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  open_socket
+#   PARAMETERS:  PeerAddr string something like 192.168.1.1 or 192.168.1.1:10000
+#                [PeerPort] string necessary if port not appended by PeerAddr
+#      RETURNS:  socket IO::Socket::INET
+#  DESCRIPTION:
+#===============================================================================
+sub open_socket {
+    my ($PeerAddr, $PeerPort) = @_ ;
+    if(defined($PeerPort)){
+        $PeerAddr = $PeerAddr.":".$PeerPort;
+    }
+    my $socket;
+    $socket = new IO::Socket::INET(PeerAddr => $PeerAddr ,
+            Porto => "tcp" ,
+            Type => SOCK_STREAM,
+            Timeout => 5,
+            );
+    if(not defined $socket) {
+        #daemon_log("cannot connect to socket at $PeerAddr, $@\n");
+        return;
+    }
+    daemon_log("open_socket:\n\t$PeerAddr", 7);
+    return $socket;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  read_from_socket
+#   PARAMETERS:  socket fh - 
+#      RETURNS:  result string - readed characters from socket
+#  DESCRIPTION:  reads data from socket in 16 byte steps
+#===============================================================================
+sub read_from_socket {
+    my ($socket) = @_;
+    my $result = "";
+
+    $socket->blocking(1);
+    $result = <$socket>;
+
+    $socket->blocking(0);
+    while ( my $char = <$socket> ) {
+        if (not defined $char) { last }
+        $result .= $char;
+    }
+    return $result;
+
+
+
+#    my ($socket) = @_;
+#    my $result = "";
+#    my $len = 16;
+#    while($len == 16){
+#        my $char;
+#        $len = sysread($socket, $char, 16);
+#        if($len != 16) { last }
+#        if($len != 16) { last }
+#        $result .= $char;
+#    }
+#    return $result;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  print_known_hosts_hash
+#   PARAMETERS:
+#      RETURNS: 
+#  DESCRIPTION: 
+#===============================================================================
+sub print_known_hosts_hash {
+    my ($tmp) = @_;
+    print "####################################\n";
+    print "# status of known_hosts\n";
+    my $hosts;
+    my $host_hash;
+    my @hosts = keys %$known_hosts;
+    foreach my $host (@hosts) {
+        #my @elements = keys %$known_hosts->{$host};
+        my $status = $known_hosts->{$host}->{status} ;
+        my $passwd = $known_hosts->{$host}->{passwd};
+        my $timestamp = $known_hosts->{$host}->{timestamp};
+        print "$host\n";
+        print "\t$status\n";
+        print "\t$passwd\n";
+        print "\t$timestamp\n";
+    }
+    print "####################################\n";
+    return;
+}
+
+#===  FUNCTION  ================================================================
+#         NAME:  
+#   PARAMETERS:
+#      RETURNS: 
+#  DESCRIPTION: 
+#===============================================================================
+sub create_known_hosts_entry {
+    my ($hostname) = @_;
+    $known_hosts->{$hostname} = {};
+    $known_hosts->{$hostname}->{status} = "none";
+    $known_hosts->{$hostname}->{passwd} = "none";
+    $known_hosts->{$hostname}->{timestamp} = "none";
+    return;  
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  
+#   PARAMETERS:
+#      RETURNS: 
+#  DESCRIPTION: 
+#===============================================================================
+sub update_known_hosts_entry {
+    my ($hostname, $status, $passwd, $timestamp) = @_;
+    my ($seconds, $minutes, $hours, $monthday, $month,
+    $year, $weekday, $yearday, $sommertime) = localtime(time);
+    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
+    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
+    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
+    $month+=1;
+    $month = $month < 10 ? $month = "0".$month : $month;
+    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
+    $year+=1900;
+    my $t = "$year$month$monthday$hours$minutes$seconds";
+
+    if($status) {
+        $known_hosts->{$hostname}->{status} = $status;
+    }
+    if($passwd) {
+        $known_hosts->{$hostname}->{passwd} = $passwd;
+    }
+    if($timestamp) {
+        $t = $timestamp;
+    }
+    $known_hosts->{$hostname}->{timestamp} = $t;
+    return;  
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  
+#   PARAMETERS:
+#      RETURNS: 
+#  DESCRIPTION: 
+#===============================================================================
+sub add_content2known_hosts {
+    my ($hostname, $element, $content) = @_;
+    my ($seconds, $minutes, $hours, $monthday, $month,
+    $year, $weekday, $yearday, $sommertime) = localtime(time);
+    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
+    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
+    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
+    $month+=1;
+    $month = $month < 10 ? $month = "0".$month : $month;
+    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
+    $year+=1900;
+    my $t = "$year$month$monthday$hours$minutes$seconds";
+    
+    $known_hosts->{$hostname}->{$element} = $content;
+    $known_hosts->{$hostname}->{timestamp} = $t;
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  
+#   PARAMETERS:
+#      RETURNS: 
+#  DESCRIPTION: 
+#===============================================================================
+sub process_incoming_msg {
+    my ($crypted_msg) = @_;
+    if(not defined $crypted_msg) {
+        daemon_log("function 'process_incoming_msg': got no msg", 7);
+    }
+    $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
+    $crypted_msg = $1;
+    my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
+    daemon_log("msg from host:", 1);
+    daemon_log("\t$host", 1);
+    daemon_log("crypted msg:", 7);
+    daemon_log("\t$crypted_msg", 7);
+
+    my $act_cipher = &create_ciphering($server_passwd);
+
+    # try to decrypt incoming msg
+    my ($msg, $msg_hash);
+    eval{
+        $msg = &decrypt_msg($crypted_msg, $act_cipher);
+        $msg_hash = $xml->XMLin($msg, ForceArray=>1);
+    };
+    if($@) {
+        daemon_log("ERROR: incoming msg cannot be decrypted with server passwd", 1);
+        return;
+    } 
+
+    my $header = &get_content_from_xml_hash($msg_hash, "header");
+    
+    daemon_log("header from msg:", 1);
+    daemon_log("\t$header", 1);
+    daemon_log("msg to process:", 7);
+    daemon_log("\t$msg", 7);
+
+    #check whether msg to process is a event 
+    opendir(DIR, $event_dir) 
+        or daemon_log("cannot find directory $event_dir, no events specified", 5);
+    my $file_name;
+    while(defined($file_name = readdir(DIR))){
+        if ($file_name eq "." || $file_name eq "..") {
+            next;
+        }
+        if ($file_name eq $header) {
+            my $cmd = "$event_dir/$file_name '$msg'";
+            my $result_xml = "";
+            open(PIPE, "$cmd 2>&1 |");
+            while(<PIPE>) {
+                $result_xml.=$_;
+                last;
+            }
+            close(PIPE);
+            my $res_hash = &transform_msg2hash($result_xml);
+            my $res_target = @{$res_hash->{target}}[0];
+            &send_msg_hash2address($res_hash, $server_address);
+            
+            return;
+        }
+    }
+    close(DIR);
+    daemon_log("could not assign the msg $header to an event", 5);
+    
+
+
+    if ($header eq 'new_ldap_config') { &new_ldap_config($msg_hash)}
+    elsif ($header eq 'ping') { &got_ping($msg_hash) }
+    elsif ($header eq 'wake_up') { &execute_event($msg_hash)}
+    elsif ($header eq 'new_passwd') { &new_passwd()}
+    else { daemon_log("ERROR: no function assigned to msg $header", 5) }
+
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  
+#   PARAMETERS:
+#      RETURNS: 
+#  DESCRIPTION: 
+#===============================================================================
+sub update_status { 
+    my ($new_status) = @_ ;
+    my $out_hash = &create_xml_hash("update_status", $client_address, $server_address);      
+    &add_content2xml_hash($out_hash, "update_status", $new_status);
+    &send_msg_hash2address($out_hash, $server_address);
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  
+#   PARAMETERS:
+#      RETURNS: 
+#  DESCRIPTION: 
+#===============================================================================
+sub server_leaving {
+    my ($msg_hash) = @_ ;
+    my $source = &get_content_from_xml_hash("source");
+    my $header = &get_content_from_xml_hash("header");
+    
+    daemon_log("gosa daemon $source is going down, cause registration procedure", 1);
+    my $server_address = "none";
+    my $server_passwd = "none";
+    my $server_cipher = "none";
+
+    # reinitialization of default values in config file
+    &read_configfile;
+    
+    # registrated at new daemon
+    &register_at_server();
+       
+    return;   
+}
+
+
+sub got_ping {
+    my ($msg_hash) = @_ ;
+
+    my $source = &get_content_from_xml_hash($msg_hash, 'source');
+    my $target = &get_content_from_xml_hash($msg_hash, 'target');
+    my $header = &get_content_from_xml_hash($msg_hash, 'header');    
+    
+    &add_content2known_hosts(hostname=>$target, status=>$header);
+    
+    my $out_hash = &create_xml_hash("got_ping", $target, $source);
+    &send_msg_hash2address($out_hash, $source, $server_passwd);
+
+    return;
+}
+
+
+sub new_ldap_config {
+    my ($msg_hash) = @_ ;
+
+    my @gotoLdapServer = &get_content_from_xml_hash($msg_hash, "new_ldap_config");
+    print Dumper @gotoLdapServer;
+
+
+    return;
+
+}
+
+
+sub execute_event {
+    my ($msg_hash)= @_;
+    my $configdir= '/etc/gosac/events/';
+    my $result;
+
+    my $header = &get_content_from_xml_hash($msg_hash, 'header');
+    my $source = &get_content_from_xml_hash($msg_hash, 'source');
+    my $target = &get_content_from_xml_hash($msg_hash, 'target');
+
+
+    if((not defined $source)
+            && (not defined $target)
+            && (not defined $header)) {
+        daemon_log("ERROR: Entries missing in XML msg for gosa events under /etc/gosac/events");
+    } else {
+        my $parameters="";
+        my @params = &get_content_from_xml_hash($msg_hash, $header);
+        my $params = join(", ", @params);
+        daemon_log("execute_event: got parameters: $params", 5);
+
+        if (@params) {
+            foreach my $param (@params) {
+                my $param_value = (&get_content_from_xml_hash($msg_hash, $param))[0];
+                daemon_log("execute_event: parameter -> value: $param -> $param_value", 7);
+                $parameters.= " ".$param_value;
+            }
+        }
+
+        my $cmd= $configdir.$header."$parameters";
+        daemon_log("execute_event: executing cmd: $cmd", 7);
+        $result= "";
+        open(PIPE, "$cmd 2>&1 |");
+        while(<PIPE>) {
+            $result.=$_;
+        }
+        close(PIPE);
+    }
+
+    # process the event result
+
+
+    return;
+}
+
+
+sub new_passwd {
+    # my ($msg_hash) = @_ ;
+    my $new_server_passwd = &create_passwd();
+    my $new_server_cipher = &create_ciphering($new_server_passwd);
+
+    my $out_hash = &create_xml_hash("new_passwd", $client_address, $server_address, $new_server_passwd);
+    
+    &send_msg_hash2address($out_hash, $server_address, $server_passwd);
+
+    $server_passwd = $new_server_passwd;
+    $server_cipher = $new_server_cipher;
+    return; 
+}
+
+
+
+
+#==== MAIN = main ==============================================================
+
+#  parse commandline options
+Getopt::Long::Configure( "bundling" );
+GetOptions("h|help" => \&usage,
+           "c|config=s" => \$cfg_file,
+           "f|foreground" => \$foreground,
+           "v|verbose+" => \$verbose,
+           );
+
+#  read and set config parameters
+&check_cmdline_param ;
+&read_configfile;
+&check_pid;
+
+# restart daemon log file
+if(-e $log_file ) { unlink $log_file }
+daemon_log("started!");
+
+# Just fork, if we"re not in foreground mode
+if( ! $foreground ) { $pid = fork(); }
+else { $pid = $$; }
+
+# Do something useful - put our PID into the pid_file
+if( 0 != $pid ) {
+    open( LOCK_FILE, ">$pid_file" );
+    print LOCK_FILE "$pid\n";
+    close( LOCK_FILE );
+    if( !$foreground ) { exit( 0 ) };
+}
+
+# detect own ip and mac address
+($client_ip, $client_mac_address) = &get_ip_and_mac(); 
+if (not defined $client_ip) {
+    die "EXIT: ip address of $0 could not be detected";
+}
+daemon_log("client ip address detected: $client_ip", 1);
+daemon_log("client mac address detected: $client_mac_address", 1);
+
+# prepare variables
+if (defined $server_ip && defined $server_port) {
+    $server_address = $server_ip.":".$server_port;
+}
+$client_address = $client_ip.":".$client_port;
+
+# setup xml parser
+$xml = new XML::Simple();
+
+# create input socket
+$rbits = $wbits = $ebits = "";
+$input_socket = IO::Socket::INET->new(LocalPort => $client_port,
+        Type => SOCK_STREAM,
+        Reuse => 1,
+        Listen => 20,
+        ); 
+if(not defined $input_socket){
+    daemon_log("cannot be a tcp server at $client_port : $@\n");
+} else {
+    daemon_log("start server:\n\t$server_ip:$client_port",1) ;
+    vec($rbits, fileno $input_socket, 1) = 1;
+    vec($wbits, fileno $input_socket, 1) = 1;
+}
+
+# register at server
+&register_at_server();
+
+
+##############
+# Debugging
+#############
+#sleep(2);
+#&update_status("ich_bin_ein_neuer_status");
+
+###################################
+#everything ready, okay, lets start
+###################################
+while(1) {
+    my ($rout, $wout);
+    my $nf = select($rout=$rbits, $wout=$wbits, undef, undef);
+
+    # error handling
+    if($nf < 0 ) {
+    }
+
+    # something is coming in
+    if(vec $rout, fileno $input_socket, 1) {
+        my $client = $input_socket->accept();
+        my $other_end = getpeername($client);
+        
+        if(not defined $other_end) {
+            daemon_log("client cannot be identified: $!");
+        } else {
+            my ($port, $iaddr) = unpack_sockaddr_in($other_end);
+            my $actual_ip = inet_ntoa($iaddr);
+            daemon_log("accept client from $actual_ip", 5);
+            my $in_msg = &read_from_socket($client);
+            if(defined $in_msg){
+                chomp($in_msg);
+                $in_msg = $in_msg.".".$actual_ip;
+                &process_incoming_msg($in_msg);
+
+            }
+        }
+    }
+}
+
+
+
diff --git a/gosa-core/contrib/daemon/gosa-si-client.conf-template b/gosa-core/contrib/daemon/gosa-si-client.conf-template
new file mode 100644 (file)
index 0000000..0c65e2c
--- /dev/null
@@ -0,0 +1,13 @@
+[general]
+log_file = /var/log/gosa-si-client.log
+pid_file = /var/run/gosa-si-client.pid
+
+[client]
+client_port = 20083
+
+[server]
+server_ip = 127.0.0.1
+server_port = 20081
+server_passwd = secret-server-password
+server_timeout = 5
+server_domain = intranet.gonicus.de
diff --git a/gosa-core/contrib/daemon/gosa-si-server b/gosa-core/contrib/daemon/gosa-si-server
new file mode 100755 (executable)
index 0000000..0966374
--- /dev/null
@@ -0,0 +1,2025 @@
+#!/usr/bin/perl
+#===============================================================================
+#
+#         FILE:  gosa-sd
+#
+#        USAGE:  ./gosa-sd
+#
+#  DESCRIPTION:
+#
+#      OPTIONS:  ---
+# REQUIREMENTS:  libconfig-inifiles-perl libcrypt-rijndael-perl libxml-simple-perl libipc-shareable-perl libdata-dumper-simple-perl
+#         BUGS:  ---
+#        NOTES:
+#       AUTHOR:   (Andreas Rettenberger), <rettenberger@gonicus.de>
+#      COMPANY:
+#      VERSION:  1.0
+#      CREATED:  12.09.2007 08:54:41 CEST
+#     REVISION:  ---
+#===============================================================================
+
+
+use strict;
+use warnings;
+use Getopt::Long;
+use Config::IniFiles;
+use POSIX;
+use Time::HiRes qw( gettimeofday );
+
+use Fcntl;
+use IO::Socket::INET;
+use Crypt::Rijndael;
+use MIME::Base64;
+use Digest::MD5  qw(md5 md5_hex md5_base64);
+use XML::Simple;
+use Data::Dumper;
+use Sys::Syslog qw( :DEFAULT setlogsock);
+use Cwd;
+use File::Spec;
+use IPC::Shareable qw( :lock);
+IPC::Shareable->clean_up_all;
+
+use lib "/etc/gosad/modules";
+my $modules_path = "/etc/gosad/modules";
+
+my ($cfg_file, %cfg_defaults, $foreground, $verbose, $ping_timeout, $no_bus);
+my ($bus, $msg_to_bus, $bus_cipher);
+my ($server, $server_mac_address, $server_events);
+my ($gosa_server);
+my ($known_daemons, $shmda, $known_clients, $shmcl, $known_modules);
+my ($max_clients);
+my ($pid_file, $procid, $pid, $log_file);
+my (%free_child, %busy_child, $child_max, $child_min, %child_alive_time, $child_timeout);
+my ($arp_activ, $arp_fifo, $arp_fifo_path, $no_arp);
+
+# variables declared in config file are always set to 'our'
+our (%cfg_defaults, $log_file, $pid_file, 
+    $bus_activ, $bus_passwd, $bus_ip, $bus_port,
+    $server_activ, $server_ip, $server_port, $server_passwd, $max_clients,
+    $arp_activ, $arp_fifo_path,
+    $gosa_activ, $gosa_passwd, $gosa_ip, $gosa_port, $gosa_timeout,
+);
+
+# additional variable which should be globaly accessable
+our $xml;
+our $server_address;
+our $bus_address;
+our $gosa_address;
+
+# specifies the verbosity of the daemon_log
+$verbose = 0 ;
+
+# if foreground is not null, script will be not forked to background
+$foreground = 0 ;
+
+# specifies the timeout seconds while checking the online status of a registrating client
+$ping_timeout = 5;
+
+$no_bus = 0;
+
+$no_arp = 0;
+
+# holds all other gosa-sd as well as the gosa-sd-bus
+our $known_daemons = {};
+our $shmda = tie($known_daemons, 'IPC::Shareable', undef, {create => 1, 
+                                                            exclusive => 1, 
+                                                            mode => 0666, 
+                                                            destroy => 1,
+                                                            });
+# holds all registrated clients
+our $known_clients = {};
+our $shmcl = tie($known_clients, 'IPC::Shareable', undef, {create => 1, 
+                                                            exclusive => 1, 
+                                                            mode => 0666, 
+                                                            destroy => 1,
+                                                            });
+
+
+%cfg_defaults =
+("general" =>
+    {"log_file" => [\$log_file, "/var/run/".$0.".log"],
+    "pid_file" => [\$pid_file, "/var/run/".$0.".pid"],
+    "child_max" => [\$child_max, 10],
+    "child_min" => [\$child_min, 3],
+    "child_timeout" => [\$child_timeout, 180],
+   },
+"bus" =>
+    {"bus_activ" => [\$bus_activ, "on"],
+    "bus_passwd" => [\$bus_passwd, ""],
+    "bus_ip" => [\$bus_ip, ""],
+    "bus_port" => [\$bus_port, "20080"],
+    },
+"server" =>
+    {"server_activ" => [\$server_activ, "on"],
+    "server_ip" => [\$server_ip, ""],
+    "server_port" => [\$server_port, "20081"],
+    "server_passwd" => [\$server_passwd, ""],
+    "max_clients" => [\$max_clients, 100],
+    },
+"arp" =>
+    {"arp_activ" => [\$arp_activ, "on"],
+    "arp_fifo_path" => [\$arp_fifo_path, "/var/run/gosa-si/arp-notify"],
+    },
+"gosa" =>
+    {"gosa_activ" => [\$gosa_activ, "on"],
+    "gosa_ip" => [\$gosa_ip, ""],
+    "gosa_port" => [\$gosa_port, "20082"],
+    "gosa_passwd" => [\$gosa_passwd, "none"],
+    },
+    );
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  usage
+#   PARAMETERS:  nothing
+#      RETURNS:  nothing
+#  DESCRIPTION:  print out usage text to STDERR
+#===============================================================================
+sub usage {
+    print STDERR << "EOF" ;
+usage: $0 [-hvf] [-c config]
+
+           -h        : this (help) message
+           -c <file> : config file
+           -f        : foreground, process will not be forked to background
+           -v        : be verbose (multiple to increase verbosity)
+EOF
+    print "\n" ;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  read_configfile
+#   PARAMETERS:  cfg_file - string -
+#      RETURNS:  nothing
+#  DESCRIPTION:  read cfg_file and set variables
+#===============================================================================
+sub read_configfile {
+    my $cfg;
+    if( defined( $cfg_file) && ( length($cfg_file) > 0 )) {
+        if( -r $cfg_file ) {
+            $cfg = Config::IniFiles->new( -file => $cfg_file );
+        } else {
+            print STDERR "Couldn't read config file!";
+        }
+    } else {
+        $cfg = Config::IniFiles->new() ;
+    }
+    foreach my $section (keys %cfg_defaults) {
+        foreach my $param (keys %{$cfg_defaults{ $section }}) {
+            my $pinfo = $cfg_defaults{ $section }{ $param };
+            ${@$pinfo[ 0 ]} = $cfg->val( $section, $param, @$pinfo[ 1 ] );
+        }
+    }
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  logging
+#   PARAMETERS:  level - string - default 'info'
+#                msg - string -
+#                facility - string - default 'LOG_DAEMON'
+#      RETURNS:  nothing
+#  DESCRIPTION:  function for logging
+#===============================================================================
+sub daemon_log {
+# log into log_file
+    my( $msg, $level ) = @_;
+    if(not defined $msg) { return }
+    if(not defined $level) { $level = 1 }
+    if(defined $log_file){
+        open(LOG_HANDLE, ">>$log_file");
+        if(not defined open( LOG_HANDLE, ">>$log_file" )) {
+            print STDERR "cannot open $log_file: $!";
+            return }
+            chomp($msg);
+            if($level <= $verbose){
+                print LOG_HANDLE "$level $msg\n";
+                if(defined $foreground) { print $msg."\n" }
+            }
+    }
+    close( LOG_HANDLE );
+#log into syslog
+#    my ($msg, $level, $facility) = @_;
+#    if(not defined $msg) {return}
+#    if(not defined $level) {$level = "info"}
+#    if(not defined $facility) {$facility = "LOG_DAEMON"}
+#    openlog($0, "pid,cons,", $facility);
+#    syslog($level, $msg);
+#    closelog;
+#    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  check_cmdline_param
+#   PARAMETERS:  nothing
+#      RETURNS:  nothing
+#  DESCRIPTION:  validates commandline parameter
+#===============================================================================
+sub check_cmdline_param () {
+    my $err_config;
+    my $err_counter = 0;
+    if( not defined( $cfg_file)) {
+        #$err_config = "please specify a config file";
+        #$err_counter += 1;
+        my $cwd = getcwd;
+        my $name = "/etc/gosa/gosa-si-server.conf";
+        $cfg_file = File::Spec->catfile( $cwd, $name );
+        print STDERR "no conf file specified\n   try to use default: $cfg_file\n";       
+    }
+    if( $err_counter > 0 ) {
+        &usage( "", 1 );
+        if( defined( $err_config)) { print STDERR "$err_config\n"}
+        print STDERR "\n";
+        exit( -1 );
+    }
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  check_pid
+#   PARAMETERS:  nothing
+#      RETURNS:  nothing
+#  DESCRIPTION:  handels pid processing
+#===============================================================================
+sub check_pid {
+    $pid = -1;
+    # Check, if we are already running
+    if( open(LOCK_FILE, "<$pid_file") ) {
+        $pid = <LOCK_FILE>;
+        if( defined $pid ) {
+            chomp( $pid );
+            if( -f "/proc/$pid/stat" ) {
+                my($stat) = `cat /proc/$pid/stat` =~ m/$pid \((.+)\).*/;
+                if( $0 eq $stat ) {
+                    close( LOCK_FILE );
+                    exit -1;
+                }
+            }
+        }
+        close( LOCK_FILE );
+        unlink( $pid_file );
+    }
+
+    # create a syslog msg if it is not to possible to open PID file
+    if (not sysopen(LOCK_FILE, $pid_file, O_WRONLY|O_CREAT|O_EXCL, 0644)) {
+        my($msg) = "Couldn't obtain lockfile '$pid_file' ";
+        if (open(LOCK_FILE, '<', $pid_file)
+                && ($pid = <LOCK_FILE>))
+        {
+            chomp($pid);
+            $msg .= "(PID $pid)\n";
+        } else {
+            $msg .= "(unable to read PID)\n";
+        }
+        if( ! ($foreground) ) {
+            openlog( $0, "cons,pid", "daemon" );
+            syslog( "warning", $msg );
+            closelog();
+        }
+        else {
+            print( STDERR " $msg " );
+        }
+        exit( -1 );
+    }
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  get_ip_and_mac 
+#   PARAMETERS:  nothing
+#      RETURNS:  (ip, mac) 
+#  DESCRIPTION:  executes /sbin/ifconfig and parses the output, the first occurence 
+#                of a inet address is returned as well as the mac address in the line
+#                above the inet address
+#===============================================================================
+sub get_ip_and_mac {
+    my $ip = "0.0.0.0.0"; # Defualt-IP
+    my $mac = "00:00:00:00:00:00";  # Default-MAC
+    my @ifconfig = qx(/sbin/ifconfig);
+    foreach(@ifconfig) {
+        if (/Hardware Adresse (\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2})/) {
+            $mac = "$1:$2:$3:$4:$5:$6";
+            next;
+        }
+        if (/inet Adresse:(\d+).(\d+).(\d+).(\d+)/) {
+            $ip = "$1.$2.$3.$4";
+            last;
+        }
+    }
+    return ($ip, $mac);
+}
+
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  import_modules
+#   PARAMETERS:  module_path - string - abs. path to the directory the modules are stored
+#      RETURNS:  nothing
+#  DESCRIPTION:  each file in module_path which ends with '.pm' is imported by "require 'file';"
+#===============================================================================
+sub import_modules {
+    daemon_log(" ", 1);
+
+    if (not -e $modules_path) {
+        daemon_log("ERROR: cannot find directory or directory is not readable: $modules_path", 1);   
+    }
+
+    opendir (DIR, $modules_path) or die "ERROR while loading modules from directory $modules_path : $!\n";
+    while (defined (my $file = readdir (DIR))) {
+        if (not $file =~ /(\S*?).pm$/) {
+            next;
+        }
+        eval { require $file; };
+        if ($@) {
+            daemon_log("ERROR: gosa-sd could not load module $file", 1);
+            daemon_log("$@", 5);
+            next;
+        }
+        my $mod_name = $1;
+        my $module_tag_hash = eval( $mod_name.'::get_module_tags()' );
+        $known_modules->{$mod_name} = $module_tag_hash;
+
+        daemon_log("load module $mod_name", 1);
+    }   
+
+    # for debugging
+    #while ( my ($module, $tag_hash) = each(%$known_modules)) {
+    #    print "\tmodule: $module"."\n";   
+    #    print "\ttags: ".join(", ", keys(%$tag_hash))."\n";
+    #}
+    close (DIR);
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  register_at_bus
+#   PARAMETERS:  nothing
+#      RETURNS:  nothing
+#  DESCRIPTION:  creates an entry in known_daemons and send a 'here_i_am' msg to bus
+#===============================================================================
+sub register_at_bus {
+
+    # create known_daemons entry
+    &create_known_daemon($bus_address);
+    &add_content2known_daemons(hostname=>$bus_address, status=>"register_at_bus", passwd=>$bus_passwd);
+    daemon_log("register at bus: $bus_address", 1);
+
+    my $msg_hash = &create_xml_hash("here_i_am", "$server_ip:$server_port", $bus_address);
+    &send_msg_hash2address($msg_hash, $bus_address);
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  sig_int_handler
+#   PARAMETERS:  signal - string - signal arose from system
+#      RETURNS:  noting
+#  DESCRIPTION:  handels tasks to be done befor signal becomes active
+#===============================================================================
+sub sig_int_handler {
+    my ($signal) = @_;
+    if($server){
+        close($server);
+        daemon_log("daemon server closed", 1);
+    }
+    if( -p $arp_fifo_path ) {
+        close $arp_fifo  ;
+        unlink($arp_fifo_path) ;
+        daemon_log("ARP_FIFO closed", 1) ;
+    }
+
+    if($gosa_server){
+        close($gosa_server);
+        daemon_log("gosa server closed", 1);
+    }
+
+    print STDERR "$signal\n";
+    
+    exit(1);
+}
+$SIG{INT} = \&sig_int_handler;
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  activating_child
+#   PARAMETERS:  msg - string - incoming message
+#                host - string - host from which the incomming message comes
+#      RETURNS:  nothing
+#  DESCRIPTION:  handels the distribution of incoming messages to working childs
+#===============================================================================
+sub activating_child {
+    my ($msg, $host, $client) = @_;
+    my $child = &get_processing_child();
+    my $pipe_wr = $$child{'pipe_wr'};
+    my $pipe_rd = $$child{'pipe_rd'};
+    $$child{client_ref} = $client;
+    daemon_log("activating: childpid:$$child{'pid'}", 5);
+
+    print $pipe_wr $msg.".".$host."\n";
+
+#    if (defined $client) {
+#        my $rbits = "";
+#        vec($rbits, fileno $client, 1) = 1;
+#        
+#        my ($rout);
+#        my $nf = select($rout=$rbits, undef, undef, $gosa_timeout);
+#        if($gosa_activ eq "on" && vec($rout, fileno $gosa_server, 1)) {
+#            
+#        }
+#    }
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  get_processing_child
+#   PARAMETERS:  nothing
+#      RETURNS:  child - hash - holding the process id and the references to the pipe
+#                               handles pipe_wr and pipe_rd
+#  DESCRIPTION:  handels the forking, reactivating and keeping alive tasks
+#===============================================================================
+sub get_processing_child {
+    my $child;
+    # checking %busy_child{pipe_wr} if msg is 'done', then set child from busy to free
+#    while(my ($key, $val) = each(%busy_child)) {
+#        # test ob prozess noch existiert
+#        my $exitus_pid = waitpid($key, WNOHANG);
+#        if($exitus_pid != 0) {
+#            delete $busy_child{$key};
+#            print "prozess:$key wurde aus busy_child entfernt\n";
+#            next;
+#        }
+#
+#        # check wether process sitll works
+#        my $fh = $$val{'pipe_rd'};
+#        $fh->blocking(0);
+#        my $child_answer;
+#        if(not $child_answer = <$fh>) { next }
+#        chomp($child_answer);
+#        if($child_answer eq "done") {
+#            delete $busy_child{$key};
+#            $free_child{$key} = $val;
+#        }
+#    }
+
+    while(my ($key, $val) = each(%free_child)) {
+        my $exitus_pid = waitpid($key, WNOHANG);
+        if($exitus_pid != 0) {
+            delete $free_child{$key};
+        }
+        daemon_log("free child:$key", 5);
+    }
+    # check @free_child and @busy_child
+    my $free_len = scalar(keys(%free_child));
+    my $busy_len = scalar(keys(%busy_child));
+    daemon_log("free children $free_len, busy children $busy_len", 5);
+
+    # if there is a free child, let the child work
+    if($free_len > 0){
+        my @keys = keys(%free_child);
+        $child = $free_child{$keys[0]};
+        if(defined $child) {
+            $busy_child{$$child{'pid'}} = $child ;
+            delete $free_child{$$child{'pid'}};
+        }
+        return $child;
+    }
+
+    # no free child, try to fork another one
+    if($free_len + $busy_len < $child_max) {
+
+        daemon_log("not enough children, create a new one", 5);
+
+        # New pipes for communication
+        my( $PARENT_wr, $PARENT_rd );
+        my( $CHILD_wr, $CHILD_rd );
+        pipe( $CHILD_rd,  $PARENT_wr );
+        pipe( $PARENT_rd, $CHILD_wr  );
+        $PARENT_wr->autoflush(1);
+        $CHILD_wr->autoflush(1);
+
+        ############
+        # fork child
+        ############
+        my $child_pid = fork();
+        
+        #CHILD
+        if($child_pid == 0) {
+            # Close unused pipes
+            close( $CHILD_rd );
+            close( $CHILD_wr );
+            while( 1 ) {
+                my $rbits = "";
+                vec( $rbits, fileno $PARENT_rd , 1 ) = 1;
+                my $nf = select($rbits, undef, undef, $child_timeout);
+                if($nf < 0 ) {
+                    die "select(): $!\n";
+                } elsif (! $nf) {
+                    # if already child_min childs are alive, then leave loop
+                    $free_len = scalar(keys(%free_child));
+                    $busy_len = scalar(keys(%busy_child));
+                    if($free_len + $busy_len >= $child_min) {
+                        last;
+                    } else {
+                        redo;
+                    }
+                }
+
+                # a job for a child arise
+                if ( vec $rbits, fileno $PARENT_rd, 1 ) {
+                    # read everything from pipe
+                    my $msg = "";
+                    $PARENT_rd->blocking(0);
+                    while(1) {
+                        my $read = <$PARENT_rd>;
+                        if(not defined $read) { last}
+                        $msg .= $read;
+                    }
+
+                    ######################################
+                    # forward msg to all imported modules 
+                    no strict "refs";
+                    my $answer;
+                    while( my ($module, $tag_hash) = each(%$known_modules)) {
+                        #if(exists $known_modules->{$module}->{server_packages}) {
+                            my $tmp = &{ $module."::process_incoming_msg" }($msg);
+                            if (defined $tmp) {
+                                $answer = $tmp;
+                            }
+                        #}
+                    }        
+
+                    &print_known_daemons();
+                    &print_known_clients();
+
+                    daemon_log("processing of msg finished", 5);
+
+                    if (defined $answer) {
+                        print $PARENT_wr $answer."\n";
+                        daemon_log("\t$answer", 5);
+                        daemon_log(" ", 5);
+                    } else {
+                        print $PARENT_wr "done"."\n";
+                        daemon_log(" ", 5);
+                    }
+                    redo;
+                }
+            }
+            # childs leaving the loop are allowed to die
+            exit(0);
+
+
+        #PARENT
+        } else {
+            # Close unused pipes
+            close( $PARENT_rd );
+            close( $PARENT_wr );
+
+            # add child to child alive hash
+            my %child_hash = (
+                    'pid' => $child_pid,
+                    'pipe_wr' => $CHILD_wr,
+                    'pipe_rd' => $CHILD_rd,
+                    'client_ref' => "",
+                    );
+
+            $child = \%child_hash;
+            $busy_child{$$child{'pid'}} = $child;
+            return $child;
+        }
+    }
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  process_incoming_msg
+#   PARAMETERS:  crypted_msg - string - incoming crypted message
+#      RETURNS:  nothing
+#  DESCRIPTION:  handels the proceeded distribution to the appropriated functions
+#===============================================================================
+sub process_incoming_msg {
+    my ($crypted_msg) = @_;
+    if(not defined $crypted_msg) {
+        daemon_log("function 'process_incoming_msg': got no msg", 7);
+    }
+    $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
+    $crypted_msg = $1;
+    my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
+    daemon_log("msg from host:", 1);
+    daemon_log("\t$host", 1);
+    #daemon_log("crypted msg:", 7);
+    #daemon_log("\t$crypted_msg", 7);
+
+    # collect addresses from possible incoming clients
+    my @valid_keys;
+    my @host_keys = keys %$known_daemons;
+    foreach my $host_key (@host_keys) {    
+        if($host_key =~ "^$host") {
+            push(@valid_keys, $host_key);
+        }
+    }
+    my @client_keys = keys %$known_clients;
+    foreach my $client_key (@client_keys) {
+        if($client_key =~ "^$host"){
+            push(@valid_keys, $client_key);
+        }
+    }
+    push(@valid_keys, $server_address);
+    
+    my $l = @valid_keys;
+    my ($msg, $msg_hash);
+    my $msg_flag = 0;    
+
+    # determine the correct passwd for deciphering of the incoming msgs
+    foreach my $host_key (@valid_keys) {
+        eval{
+            daemon_log( "key: $host_key", 7);
+            my $key_passwd;
+            if (exists $known_daemons->{$host_key}) {
+                $key_passwd = $known_daemons->{$host_key}->{passwd};
+            } elsif (exists $known_clients->{$host_key}) {
+                $key_passwd = $known_clients->{$host_key}->{passwd};
+            } elsif ($host_key eq $server_address) {
+                $key_passwd = $server_passwd;
+            } 
+            daemon_log("key_passwd: $key_passwd", 7);
+            my $key_cipher = &create_ciphering($key_passwd);
+            $msg = &decrypt_msg($crypted_msg, $key_cipher);
+            $msg_hash = $xml->XMLin($msg, ForceArray=>1);
+        };
+        if($@) {
+            daemon_log("key raise error", 7);
+            $msg_flag += 1;
+        } else {
+            last;
+        }
+    } 
+    
+    if($msg_flag >= $l)  {
+        daemon_log("ERROR: do not understand the message:", 1);
+        daemon_log("\t$msg", 1);
+        return;
+    }
+
+    # process incoming msg
+    my $header = &get_content_from_xml_hash($msg_hash, "header");
+    my $source = @{$msg_hash->{source}}[0];
+
+    daemon_log("header from msg:", 1);
+    daemon_log("\t$header", 1);
+    daemon_log("msg to process:", 5);
+    daemon_log("\t$msg", 5);
+
+    my @targets = @{$msg_hash->{target}};
+    my $len_targets = @targets;
+    if ($len_targets == 0){     
+        daemon_log("ERROR: no target specified for msg $header", 1);
+
+    } elsif ($len_targets == 1){
+        # we have only one target symbol
+
+        my $target = $targets[0];
+        daemon_log("msg is for:", 7);
+        daemon_log("\t$target", 7);
+
+        if ($target eq $server_address) {
+            # msg is for server
+            if ($header eq 'new_passwd'){ &new_passwd($msg_hash)}
+            elsif ($header eq 'here_i_am') { &here_i_am($msg_hash)}
+            elsif ($header eq 'who_has') { &who_has($msg_hash) }
+            elsif ($header eq 'who_has_i_do') { &who_has_i_do($msg_hash)}
+            elsif ($header eq 'update_status') { &update_status($msg_hash) }
+            #elsif ($header eq 'got_ping') { &got_ping($msg_hash)}
+            elsif ($header eq 'get_load') { &execute_actions($msg_hash)}
+            else { daemon_log("ERROR: no function assigned to this msg", 5) }
+
+        
+       } elsif ($target eq "*") {
+            # msg is for all clients
+
+            my @target_addresses = keys(%$known_clients);
+            foreach my $target_address (@target_addresses) {
+                if ($target_address eq $source) { next; }
+                $msg_hash->{target} = [$target_address];
+                &send_msg_hash2address($msg_hash, $target_address);
+            }           
+        } else {
+            # msg is for one client
+
+            if (exists $known_clients->{$target}) {
+                # target is known
+
+                &send_msg_hash2address($msg_hash, $target);
+            } else {
+                # target is not known
+
+                daemon_log("ERROR: target $target is not known in known_clients", 1);
+            }
+        }
+    } else {
+        # we have multiple target symbols
+
+        my $target_string = join(", ", @targets);
+        daemon_log("msg is for:", 7);
+        daemon_log("\t$target_string", 7);
+        
+        my $target_address;
+        foreach $target_address (@targets) {
+            if (exists $known_clients->{$target_address}) {
+                # target_address is known
+
+                &send_msg_hash2address($msg_hash, $target_address);
+                daemon_log("server forwards msg $header to client $target_address", 3);
+            } else {
+                # target is not known
+
+                daemon_log("ERROR: target $target_address is not known in known_clients", 1);
+            }
+        }
+
+
+    }
+
+   return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  open_socket
+#   PARAMETERS:  PeerAddr string something like 192.168.1.1 or 192.168.1.1:10000
+#                [PeerPort] string necessary if port not appended by PeerAddr
+#      RETURNS:  socket IO::Socket::INET
+#  DESCRIPTION:  open a socket to PeerAddr
+#===============================================================================
+sub open_socket {
+    my ($PeerAddr, $PeerPort) = @_ ;
+    if(defined($PeerPort)){
+        $PeerAddr = $PeerAddr.":".$PeerPort;
+    }
+    my $socket;
+    $socket = new IO::Socket::INET(PeerAddr => $PeerAddr ,
+            Porto => "tcp" ,
+            Type => SOCK_STREAM,
+            Timeout => 5,
+            );
+    if(not defined $socket) {
+        return;
+    }
+    daemon_log("open_socket:", 7);
+    daemon_log("\t$PeerAddr", 7);
+    return $socket;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  open_fifo
+#   PARAMETERS:  $fifo_path
+#      RETURNS:  0: FIFO couldn"t be setup, 1: FIFO setup correctly
+#  DESCRIPTION:  creates a FIFO at $fifo_path
+#===============================================================================
+sub open_fifo {
+    my ($fifo_path) = @_ ;
+    if( -p $fifo_path ) {
+        daemon_log("FIFO at $fifo_path already exists! Is being deleted!", 1);
+        unlink($fifo_path);
+    }
+    POSIX::mkfifo($fifo_path, 0666) or die "can't mkfifo $fifo_path: $!";
+    daemon_log( "FIFO started at $fifo_path", 1) ;
+    return 1;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  read_from_socket
+#   PARAMETERS:  socket fh - 
+#      RETURNS:  result string - readed characters from socket
+#  DESCRIPTION:  reads data from socket in 16 byte steps
+#===============================================================================
+sub read_from_socket {
+    my ($socket) = @_;
+    my $result = "";
+
+    $socket->blocking(1);
+    $result = <$socket>;
+
+    $socket->blocking(0);
+    while ( my $char = <$socket> ) {
+        if (not defined $char) { last }
+        $result .= $char;
+    }
+
+#    my $len = 16;
+#    while($len == 16){
+#        my $char;
+#        $len = sysread($socket, $char, 16);
+#        if($len != 16) { last }
+#        $result .= $char;
+#    }
+    return $result;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_xml_hash
+#   PARAMETERS:  header - string - message header (required)
+#                source - string - where the message come from (required)
+#                target - string - where the message should go to (required)
+#                [header_value] - string - something usefull (optional)
+#      RETURNS:  hash - hash - nomen est omen
+#  DESCRIPTION:  creates a key-value hash, all values are stored in a array
+#===============================================================================
+sub create_xml_hash {
+    my ($header, $source, $target, $header_value) = @_;
+    my $hash = {
+            header => [$header],
+            source => [$source],
+            target => [$target],
+            $header => [$header_value],
+    };
+    #daemon_log("create_xml_hash:", 7),
+    #chomp(my $tmp = Dumper $hash);
+    #daemon_log("\t$tmp", 7);
+    return $hash
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_xml_string
+#   PARAMETERS:  xml_hash - hash - hash from function create_xml_hash
+#      RETURNS:  xml_string - string - xml string representation of the hash
+#  DESCRIPTION:  transform the hash to a string using XML::Simple module
+#===============================================================================
+sub create_xml_string {
+    my ($xml_hash) = @_ ;
+    my $xml_string = $xml->XMLout($xml_hash, RootName => 'xml');
+    $xml_string =~ s/[\n]+//g;
+    #daemon_log("create_xml_string:",7);
+    #daemon_log("$xml_string\n", 7);
+    return $xml_string;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  add_content2xml_hash
+#   PARAMETERS:  xml_ref - ref - reference to a hash from function create_xml_hash
+#                element - string - key for the hash
+#                content - string - value for the hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  add key-value pair to xml_ref, if key alread exists, then append value to list
+#===============================================================================
+sub add_content2xml_hash {
+    my ($xml_ref, $element, $content) = @_;
+    if(not exists $$xml_ref{$element} ) {
+        $$xml_ref{$element} = [];
+    }
+    my $tmp = $$xml_ref{$element};
+    push(@$tmp, $content);
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  get_content_from_xml_hash
+#   PARAMETERS:  xml_ref - ref - reference of the xml hash
+#                element - string - key of the value you want
+#      RETURNS:  value - string - if key is either header, target or source
+#                value - list - for all other keys in xml hash
+#  DESCRIPTION:
+#===============================================================================
+sub get_content_from_xml_hash {
+    my ($xml_ref, $element) = @_ ;
+    my $result = $xml_ref->{$element};
+    if( $element eq "header" || $element eq "target" || $element eq "source") {
+        return @$result[0];
+    }
+    return @$result;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  encrypt_msg
+#   PARAMETERS:  msg - string - message to encrypt
+#                my_cipher - ref - reference to a Crypt::Rijndael object
+#      RETURNS:  crypted_msg - string - crypted message
+#  DESCRIPTION:  crypts the incoming message with the Crypt::Rijndael module
+#===============================================================================
+sub encrypt_msg {
+    my ($msg, $my_cipher) = @_;
+    if(not defined $my_cipher) { print "no cipher object\n"; }
+    $msg = "\0"x(16-length($msg)%16).$msg;
+    my $crypted_msg = $my_cipher->encrypt($msg);
+    chomp($crypted_msg = &encode_base64($crypted_msg));
+    return $crypted_msg;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  decrypt_msg
+#   PARAMETERS:  crypted_msg - string - message to decrypt
+#                my_cipher - ref - reference to a Crypt::Rijndael object
+#      RETURNS:  msg - string - decrypted message
+#  DESCRIPTION:  decrypts the incoming message with the Crypt::Rijndael module
+#===============================================================================
+sub decrypt_msg {
+    my ($crypted_msg, $my_cipher) = @_ ;
+    $crypted_msg = &decode_base64($crypted_msg);
+    my $msg = $my_cipher->decrypt($crypted_msg); 
+    $msg =~ s/\0*//g;
+    return $msg;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_ciphering
+#   PARAMETERS:  passwd - string - used to create ciphering
+#      RETURNS:  cipher - object
+#  DESCRIPTION:  creates a Crypt::Rijndael::MODE_CBC object with passwd as key
+#===============================================================================
+sub create_ciphering {
+    my ($passwd) = @_;
+    $passwd = substr(md5_hex("$passwd") x 32, 0, 32);
+    my $iv = substr(md5_hex('GONICUS GmbH'),0, 16);
+
+    #daemon_log("iv: $iv", 7);
+    #daemon_log("key: $passwd", 7);
+    my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC());
+    $my_cipher->set_iv($iv);
+    return $my_cipher;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  send_msg_hash2address
+#   PARAMETERS:  msg_hash - hash - xml_hash created with function create_xml_hash
+#                PeerAddr string - socket address to send msg
+#                PeerPort string - socket port, if not included in socket address
+#      RETURNS:  nothing
+#  DESCRIPTION:  ????
+#===============================================================================
+sub send_msg_hash2address {
+    my ($msg_hash, $address, $passwd) = @_ ;
+
+    # fetch header for logging
+    my $header = &get_content_from_xml_hash($msg_hash, "header");
+    
+    # generate xml string
+    my $msg_xml = &create_xml_string($msg_hash);
+    
+    # fetch the appropriated passwd from hash 
+    if(not defined $passwd) {
+        if(exists $known_daemons->{$address}) {
+            $passwd = $known_daemons->{$address}->{passwd};
+        } elsif(exists $known_clients->{$address}) {
+            $passwd = $known_clients->{$address}->{passwd};
+            
+        } else {
+            daemon_log("$address not known, neither as server nor as client", 1);
+            return;
+        }
+    }
+    
+    # create ciphering object
+    my $act_cipher = &create_ciphering($passwd);
+    
+    # encrypt xml msg
+    my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher);
+    
+    # opensocket
+    my $socket = &open_socket($address);
+    if(not defined $socket){
+        daemon_log( "cannot send '$header'-msg to $address , server not reachable", 5);
+
+        if (exists $known_clients->{$address}) {
+            if ($known_clients->{$address}->{status} eq "down") {
+                # if status of not reachable client is already 'down', then delete client from known_clients
+                &clean_up_known_clients($address);
+
+            } else {
+                # update status to 'down'
+                &update_known_clients(hostname=>$address, status=>"down");        
+
+            }
+        }
+        return;
+    }
+    
+    # send xml msg
+    print $socket $crypted_msg."\n";
+    
+    close $socket;
+
+    daemon_log("send '$header'-msg to $address", 1);
+
+    daemon_log("$msg_xml", 5);
+
+    #daemon_log("crypted message:",7);
+    #daemon_log("\t$crypted_msg", 7);
+
+    # update status of client in known_clients with last send msg
+    if(exists $known_daemons->{$address}) {
+        #&update_known_daemons();
+    } elsif(exists $known_clients->{$address}) {
+        &update_known_clients(hostname=>$address, status=>$header);
+    }
+
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  send_msg_hash2bus
+#   PARAMETERS:  msg_hash - hash - xml_hash created with function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  ????
+#===============================================================================
+sub send_msg_hash2bus {
+    my($msg_hash) = @_;
+
+    # fetch header for logging
+    my $header = &get_content_from_xml_hash($msg_hash, "header");    
+
+    # generate xml string
+    my $msg_xml = &create_xml_string($msg_hash);
+
+    # encrypt xml msg 
+    my $crypted_msg = &encrypt_msg($msg_xml, $bus_cipher);
+
+    # open socket
+    my $socket = &open_socket($bus_address);
+    if(not defined $socket){
+        daemon_log( "cannot send '$header'-msg to $bus_address , bus not reachable", 5);
+        return;
+    }
+    
+    # send xml msg
+    print $socket $crypted_msg."\n";
+    
+    close $socket;
+   
+
+    daemon_log("send '$header'-msg to bus", 1);
+    daemon_log("$msg_xml", 5);
+    #daemon_log("crypted msg:",7);
+    #daemon_log("\t$crypted_msg", 7);
+
+    return;
+}
+
+
+
+
+
+
+
+##===  FUNCTION  ================================================================
+##         NAME:  new_passwd
+##   PARAMETERS:  msg_hash - ref - hash from function create_xml_hash
+##      RETURNS:  nothing
+##  DESCRIPTION:  process this incoming message
+##===============================================================================
+#sub new_passwd {
+#    my ($msg_hash) = @_;
+#    
+#    my $source = &get_content_from_xml_hash($msg_hash, "source");
+#    my $passwd = (&get_content_from_xml_hash($msg_hash, "new_passwd"))[0];
+#
+#    if (exists $known_daemons->{$source}) {
+#        &add_content2known_daemons(hostname=>$source, status=>"new_passwd", passwd=>$passwd);
+#        $bus_cipher = &create_ciphering($passwd);
+#        my $hash = &create_xml_hash("confirm_new_passwd", "$server_ip:$server_port", "$source");
+#        &send_msg_hash2address($hash, $source);
+#
+#    } elsif (exists $known_clients->{$source}) {
+#        &add_content2known_clients(hostname=>$source, status=>"new_passwd", passwd=>$passwd);
+#
+#    } else {
+#        daemon_log("ERROR: $source not known, neither in known_daemons nor in known_clients", 1)   
+#    }
+#
+#    return;
+#}
+
+
+##===  FUNCTION  ================================================================
+##         NAME:  make ping
+##   PARAMETERS:  address - string - address which should be pinged
+##      RETURNS:  nothing
+##  DESCRIPTION:  send ping message to address
+##===============================================================================
+#sub make_ping {
+#    my ($msg_hash) = @_;
+#
+#    my $source = &get_content_from_xml_hash($msg_hash, "source");
+#    my $target = &get_content_from_xml_hash($msg_hash, "target");
+#    
+#    print "make_ping:$source\n";
+#    my $out_hash = &create_xml_hash("ping", $target, $source);
+#    &send_msg_hash2address($out_hash, $source);
+#    return;
+#}
+
+
+##===  FUNCTION  ================================================================
+##         NAME:  got_ping
+##   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+##      RETURNS:  nothing
+##  DESCRIPTION:  process this incoming message
+##===============================================================================
+#sub got_ping {
+#    my ($msg_hash) = @_;
+#    
+#    my $source = &get_content_from_xml_hash($msg_hash, 'source');
+#    my $target = &get_content_from_xml_hash($msg_hash, 'target');
+#    my $header = &get_content_from_xml_hash($msg_hash, 'header');    
+#    
+#    if(exists $known_daemons->{$source}) {
+#        &add_content2known_daemons(hostname=>$source, status=>$header);
+#    } else {
+#        &add_content2known_clients(hostname=>$source, status=>$header);
+#    }
+#    
+#    return;
+#}
+
+
+##===  FUNCTION  ================================================================
+##         NAME:  here_i_am
+##   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+##      RETURNS:  nothing
+##  DESCRIPTION:  process this incoming message
+##===============================================================================
+#sub here_i_am {
+#    my ($msg_hash) = @_;
+#
+#    my $source = &get_content_from_xml_hash($msg_hash, "source");
+#    my $mac_address = (&get_content_from_xml_hash($msg_hash, "mac_address"))[0]; 
+#    my $out_hash;
+#
+#    # number of known clients
+#    my $nu_clients = keys %$known_clients;
+#
+#    # check wether client address or mac address is already known
+#    if (exists $known_clients->{$source}) {
+#        daemon_log("WARNING: $source is already known as a client", 1);
+#        daemon_log("WARNING: values for $source are being overwritten", 1);   
+#        $nu_clients --;
+#    }
+#
+#    # number of actual activ clients
+#    my $act_nu_clients = $nu_clients;
+#
+#    daemon_log("number of actual activ clients: $act_nu_clients", 5);
+#    daemon_log("number of maximal allowed clients: $max_clients", 5);
+#
+#    if($max_clients <= $act_nu_clients) {
+#        my $out_hash = &create_xml_hash("denied", $server_address, $source);
+#        &add_content2xml_hash($out_hash, "denied", "I_cannot_take_any_more_clients!");
+#        my $passwd = (&get_content_from_xml_hash($msg_hash, "new_passwd"))[0];
+#        &send_msg_hash2address($out_hash, $source, $passwd);
+#        return;
+#    }
+#    
+#    # new client accepted
+#    my $new_passwd = (&get_content_from_xml_hash($msg_hash, "new_passwd"))[0];
+#
+#    # create known_daemons entry
+#    my $events = (&get_content_from_xml_hash($msg_hash, "events"))[0];
+#    &create_known_client($source);
+#    &add_content2known_clients(hostname=>$source, events=>$events, mac_address=>$mac_address, 
+#                                status=>"registered", passwd=>$new_passwd);
+#
+#    # return acknowledgement to client
+#    $out_hash = &create_xml_hash("registered", $server_address, $source);
+#    &send_msg_hash2address($out_hash, $source);
+#
+#    # notify registered client to bus
+#    $out_hash = &create_xml_hash("new_client", $server_address, $bus_address, $source);
+#    &send_msg_hash2bus($out_hash);
+#
+#    # give the new client his ldap config
+#    &new_ldap_config($source);
+#
+#    return;
+#}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  who_has
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing 
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+#sub who_has {
+#    my ($msg_hash) = @_ ;
+#    
+#    # what is your search pattern
+#    my $search_pattern = (&get_content_from_xml_hash($msg_hash, "who_has"))[0];
+#    my $search_element = (&get_content_from_xml_hash($msg_hash, $search_pattern))[0];
+#    daemon_log("who_has-msg looking for $search_pattern $search_element", 7);
+#
+#    # scanning known_clients for search_pattern
+#    my @host_addresses = keys %$known_clients;
+#    my $known_clients_entries = length @host_addresses;
+#    my $host_address;
+#    foreach my $host (@host_addresses) {
+#        my $client_element = $known_clients->{$host}->{$search_pattern};
+#        if ($search_element eq $client_element) {
+#            $host_address = $host;
+#            last;
+#        }
+#    }
+#        
+#    # search was successful
+#    if (defined $host_address) {
+#        my $source = @{$msg_hash->{source}}[0];
+#        my $out_msg = &create_xml_hash("who_has_i_do", $server_address, $source, "mac_address");
+#        &add_content2xml_hash($out_msg, "mac_address", $search_element);
+#        &send_msg_hash2address($out_msg, $bus_address);
+#    }
+#    return;
+#}
+
+
+#sub who_has_i_do {
+#    my ($msg_hash) = @_ ;
+#    my $header = &get_content_from_xml_hash($msg_hash, "header");
+#    my $source = &get_content_from_xml_hash($msg_hash, "source");
+#    my $search_param = (&get_content_from_xml_hash($msg_hash, $header))[0];
+#    my $search_value = (&get_content_from_xml_hash($msg_hash, $search_param))[0];
+#    print "\ngot msg $header:\nserver $source has client with $search_param $search_value\n";
+#}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  update_status
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+#sub update_status {
+#    my ($msg_hash) = @_;
+#    my $header = &get_content_from_xml_hash($msg_hash, "header");
+#    my $source = &get_content_from_xml_hash($msg_hash, "source");
+#    my $new_status = (&get_content_from_xml_hash($msg_hash, "update_status"))[0];
+#    
+#    # find the source
+#    my $act_known_hash;
+#    if (exists $known_daemons->{$source}) {
+#        
+#        &add_content2known_daemons(hostname=>$source, status=>$new_status);
+#    } elsif (exists $known_clients->{$source}) {
+#        &update_known_clients(hostname=>$source, status=>$new_status);
+#        #&add_content2known_clients(hostname=>$source, status=>$new_status);
+#    } else {
+#        daemon_log("ERROR: got $header-msg, but cannot find $source in my hashes, unable to update status", 1);
+#        return;
+#    }
+#
+#   return;
+#}
+
+
+##===  FUNCTION  ================================================================
+##         NAME:  new_ldap_config
+##   PARAMETERS:  address - string - ip address and port of a host
+##      RETURNS:  nothing
+##  DESCRIPTION:  send to address the ldap configuration found for dn gotoLdapServer
+##===============================================================================
+#sub new_ldap_config {
+#    my ($address) = @_ ;
+#    
+#    if (not exists $known_clients->{$address}) {
+#        daemon_log("ERROR: $address does not exist in known_clients, cannot send him his ldap config", 1);
+#        return;
+#    }
+#    
+#    my $mac_address = $known_clients->{$address}->{"mac_address"};
+#    if (not defined $mac_address) {
+#        daemon_log("ERROR: no mac address found for client $address", 1);
+#        return;
+#    }
+#
+#    # fetch dn
+#    my $goHard_cmd = "ldapsearch -x '(&(objectClass=goHard)(macAddress=00:11:22:33:44:57))' dn gotoLdapServer";
+#    my $dn;
+#    my @gotoLdapServer;
+#    open (PIPE, "$goHard_cmd 2>&1 |");
+#    while(<PIPE>) {
+#        chomp $_;
+#        # If it's a comment, goto next
+#        if ($_ =~ m/^[#]/) { next;}
+#        if ($_ =~ m/^dn: ([\S]+?)$/) {
+#            $dn = $1;
+#        } elsif ($_ =~ m/^gotoLdapServer: ([\S]+?)$/) {
+#            push(@gotoLdapServer, $1);
+#        }
+#    }
+#    close(PIPE);
+#    
+#    # no dn found
+#    if (not defined $dn) {
+#        daemon_log("ERROR: no dn arose from command: $goHard_cmd", 1);
+#        return;
+#    }
+#    
+#    # no gotoLdapServer found
+#    my $gosaGroupOfNames_cmd = "ldapsearch -x '(&(objectClass=gosaGroupOfNames)(member=$dn))' gotoLdapServer";
+#    if (@gotoLdapServer == 0) {
+#        open (PIPE, "$gosaGroupOfNames_cmd 2>&1 |");
+#        while(<PIPE>) {
+#            chomp $_;
+#            if ($_ =~ m/^[#]/) { next; }
+#            if ($_ =~ m/^gotoLdapServer: ([\S]+?)$/) {
+#                push(@gotoLdapServer, $1);
+#            }
+#        }
+#        close(PIPE);
+#    }
+#
+#    # still no gotoLdapServer found
+#    if (@gotoLdapServer == 0) {
+#        daemon_log("ERROR: cannot find gotoLdapServer entry in command: $gosaGroupOfNames_cmd", 1);
+#        return;
+#    }
+#
+#    # sort @gotoLdapServer and then split of ranking
+#    my @sorted_gotoLdapServer = sort(@gotoLdapServer);
+#    @gotoLdapServer = reverse(@sorted_gotoLdapServer);
+#    foreach (@gotoLdapServer) {
+#        $_ =~ s/^\d://;
+#    }
+#
+#    my $t = join(" ", @gotoLdapServer);
+# 
+#    my $out_hash = &create_xml_hash("new_ldap_config", $server_address, $address);
+#    map(&add_content2xml_hash($out_hash, "new_ldap_config", $_), @gotoLdapServer);
+#    &send_msg_hash2address($out_hash, $address);
+#
+#    return;
+#}
+
+
+##===  FUNCTION  ================================================================
+##         NAME:  execute_actions
+##   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+##      RETURNS:  nothing
+##  DESCRIPTION:  invokes the script specified in msg_hash which is located under
+##                /etc/gosad/actions
+##===============================================================================
+#sub execute_actions {
+#    my ($msg_hash) = @_ ;
+#    my $configdir= '/etc/gosad/actions/';
+#    my $result;
+#
+#    my $header = &get_content_from_xml_hash($msg_hash, 'header');
+#    my $source = &get_content_from_xml_hash($msg_hash, 'source');
+#    my $target = &get_content_from_xml_hash($msg_hash, 'target');
+#
+#
+#    if((not defined $source)
+#            && (not defined $target)
+#            && (not defined $header)) {
+#        daemon_log("ERROR: Entries missing in XML msg for gosad actions under /etc/gosad/actions");
+#    } else {
+#        my $parameters="";
+#        my @params = &get_content_from_xml_hash($msg_hash, $header);
+#        my $params = join(", ", @params);
+#        daemon_log("execute_actions: got parameters: $params", 5);
+#
+#        if (@params) {
+#            foreach my $param (@params) {
+#                my $param_value = (&get_content_from_xml_hash($msg_hash, $param))[0];
+#                daemon_log("execute_actions: parameter -> value: $param -> $param_value", 7);
+#                $parameters.= " ".$param_value;
+#            }
+#        }
+#
+#        my $cmd= $configdir.$header."$parameters";
+#        daemon_log("execute_actions: executing cmd: $cmd", 7);
+#        $result= "";
+#        open(PIPE, "$cmd 2>&1 |");
+#        while(<PIPE>) {
+#            $result.=$_;
+#        }
+#        close(PIPE);
+#    }
+#
+#    # process the event result
+#
+#
+#    return;
+#}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  print_known_daemons
+#   PARAMETERS:  nothing
+#      RETURNS:  nothing
+#  DESCRIPTION:  nomen est omen
+#===============================================================================
+sub print_known_daemons {
+    my ($tmp) = @_ ;
+    print "####################################\n";
+    print "# status of known_daemons\n";
+    $shmda->shlock(LOCK_EX);
+    my @hosts = keys %$known_daemons;
+    foreach my $host (@hosts) {
+        my $status = $known_daemons->{$host}->{status} ;
+        my $passwd = $known_daemons->{$host}->{passwd};
+        my $timestamp = $known_daemons->{$host}->{timestamp};
+        print "$host\n";
+        print "\tstatus:    $status\n";
+        print "\tpasswd:    $passwd\n";
+        print "\ttimestamp: $timestamp\n";
+    }
+    $shmda->shunlock(LOCK_EX);
+    print "####################################\n";
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_known_daemon
+#   PARAMETERS:  hostname - string - key for the hash known_daemons
+#      RETURNS:  nothing
+#  DESCRIPTION:  creates a dummy entry for hostname in known_daemons
+#===============================================================================
+sub create_known_daemon {
+    my ($hostname) = @_;
+    $shmda->shlock(LOCK_EX);
+    $known_daemons->{$hostname} = {};
+    $known_daemons->{$hostname}->{status} = "none";
+    $known_daemons->{$hostname}->{passwd} = "none";
+    $known_daemons->{$hostname}->{timestamp} = "none";
+    $shmda->shunlock(LOCK_EX); 
+    return;  
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  add_content2known_daemons
+#   PARAMETERS:  hostname - string - ip address and port of host (required)
+#                status - string - (optional)
+#                passwd - string - (optional)
+#                mac_address - string - mac address of host (optional)
+#      RETURNS:  nothing
+#  DESCRIPTION:  nome est omen and updates each time the timestamp of hostname
+#===============================================================================
+sub add_content2known_daemons {
+    my $arg = {
+        hostname => undef, status => undef, passwd => undef,
+        mac_address => undef, events => undef, 
+        @_ };
+    my $hostname = $arg->{hostname};
+    my $status = $arg->{status};
+    my $passwd = $arg->{passwd};
+    my $mac_address = $arg->{mac_address};
+    my $events = $arg->{events};
+
+    if (not defined $hostname) {
+        daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1);
+        return;
+    }
+
+    my ($seconds, $minutes, $hours, $monthday, $month,
+    $year, $weekday, $yearday, $sommertime) = localtime(time);
+    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
+    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
+    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
+    $month+=1;
+    $month = $month < 10 ? $month = "0".$month : $month;
+    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
+    $year+=1900;
+    my $t = "$year$month$monthday$hours$minutes$seconds";
+    
+    $shmda->shlock(LOCK_EX);
+    if (defined $status) {
+        $known_daemons->{$hostname}->{status} = $status;
+    }
+    if (defined $passwd) {
+        $known_daemons->{$hostname}->{passwd} = $passwd;
+    }
+    if (defined $mac_address) {
+        $known_daemons->{$hostname}->{mac_address} = $mac_address;
+    }
+    if (defined $events) {
+        $known_daemons->{$hostname}->{events} = $events;
+    }
+    $known_daemons->{$hostname}->{timestamp} = $t;
+    $shmda->shlock(LOCK_EX);
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  update_known_daemons
+#   PARAMETERS:  hostname - string - ip address and port of host (required)
+#                status - string - (optional)
+#                passwd - string - (optional)
+#                client - string - ip address and port of client (optional)
+#      RETURNS:  nothing
+#  DESCRIPTION:  nome est omen and updates each time the timestamp of hostname
+#===============================================================================
+sub update_known_daemons {
+    my $arg = {
+        hostname => undef, status => undef, passwd => undef,
+        @_ };
+    my $hostname = $arg->{hostname};
+    my $status = $arg->{status};
+    my $passwd = $arg->{passwd};
+
+    if (not defined $hostname) {
+        daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1);
+        return;
+    }
+
+    my ($seconds, $minutes, $hours, $monthday, $month,
+    $year, $weekday, $yearday, $sommertime) = localtime(time);
+    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
+    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
+    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
+    $month+=1;
+    $month = $month < 10 ? $month = "0".$month : $month;
+    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
+    $year+=1900;
+    my $t = "$year$month$monthday$hours$minutes$seconds";
+
+    $shmda->shlock(LOCK_EX);
+    if (defined $status) {
+        $known_daemons->{$hostname}->{status} = $status;
+    }
+    if (defined $passwd) {
+        $known_daemons->{$hostname}->{passwd} = $passwd;
+    }
+    $known_daemons->{$hostname}->{timestamp} = $t;
+    $shmda->shunlock(LOCK_EX);
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  print_known_clients 
+#   PARAMETERS:  nothing
+#      RETURNS:  nothing
+#  DESCRIPTION:  nomen est omen
+#===============================================================================
+sub print_known_clients {
+
+    print "####################################\n";
+    print "# status of known_clients\n";
+    $shmcl->shlock(LOCK_EX);
+    my @hosts = keys %$known_clients;
+    if (@hosts) {
+        foreach my $host (@hosts) {
+            my $status = $known_clients->{$host}->{status} ;
+            my $passwd = $known_clients->{$host}->{passwd};
+            my $timestamp = $known_clients->{$host}->{timestamp};
+            my $mac_address = $known_clients->{$host}->{mac_address};
+            my $events = $known_clients->{$host}->{events};
+            print "$host\n";
+            print "\tstatus:      $status\n";
+            print "\tpasswd:      $passwd\n";
+            print "\ttimestamp:   $timestamp\n";
+            print "\tmac_address: $mac_address\n";
+            print "\tevents:      $events\n";
+        }
+    }
+    $shmcl->shunlock(LOCK_EX);
+    print "####################################\n";
+    return;
+}
+
+
+
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  create_known_client
+#   PARAMETERS:  hostname - string - key for the hash known_clients
+#      RETURNS:  nothing
+#  DESCRIPTION:  creates a dummy entry for hostname in known_clients
+#===============================================================================
+sub create_known_client {
+    my ($hostname) = @_;
+    $shmcl->shlock(LOCK_EX);
+    $known_clients->{$hostname} = {};
+    $known_clients->{$hostname}->{status} = "none";
+    $known_clients->{$hostname}->{passwd} = "none";
+    $known_clients->{$hostname}->{timestamp} = "none";
+    $known_clients->{$hostname}->{mac_address} = "none";
+    $known_clients->{$hostname}->{events} = "none";
+    $shmcl->shunlock(LOCK_EX); 
+    return;  
+}
+
+
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  add_content2known_clients
+#   PARAMETERS:  hostname - string - ip address and port of host (required)
+#                status - string - (optional)
+#                passwd - string - (optional)
+#                mac_address - string - (optional)
+#                events - string - event of client, executable skripts under /etc/gosac/events
+#      RETURNS:  nothing
+#  DESCRIPTION:  nome est omen and updates each time the timestamp of hostname
+#===============================================================================
+sub add_content2known_clients {
+    my $arg = {
+        hostname => undef, status => undef, passwd => undef,
+        mac_address => undef, events => undef, 
+        @_ };
+    my $hostname = $arg->{hostname};
+    my $status = $arg->{status};
+    my $passwd = $arg->{passwd};
+    my $mac_address = $arg->{mac_address};
+    my $events = $arg->{events};
+
+    if (not defined $hostname) {
+        daemon_log("ERROR: function add_content2known_clients is not invoked with requiered parameter 'hostname'", 1);
+        return;
+    }
+
+    my ($seconds, $minutes, $hours, $monthday, $month,
+    $year, $weekday, $yearday, $sommertime) = localtime(time);
+    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
+    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
+    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
+    $month+=1;
+    $month = $month < 10 ? $month = "0".$month : $month;
+    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
+    $year+=1900;
+    my $t = "$year$month$monthday$hours$minutes$seconds";
+    
+    $shmcl->shlock(LOCK_EX);
+    if (defined $status) {
+        $known_clients->{$hostname}->{status} = $status;
+    }
+    if (defined $passwd) {
+        $known_clients->{$hostname}->{passwd} = $passwd;
+    }
+    if (defined $mac_address) {
+        $known_clients->{$hostname}->{mac_address} = $mac_address;
+    }
+    if (defined $events) {
+        $known_clients->{$hostname}->{events} = $events;
+    }
+    $known_clients->{$hostname}->{timestamp} = $t;
+    $shmcl->shlock(LOCK_EX);
+    return;
+}
+
+#===  FUNCTION  ================================================================
+#         NAME:  
+#   PARAMETERS:  
+#      RETURNS:  
+#  DESCRIPTION:  
+#===============================================================================    
+sub clean_up_known_clients {
+    my ($address) = @_ ;
+    
+    if (not exists $known_clients->{$address}) {
+        daemon_log("cannot prune known_clients from $address, client not known", 5);
+        return;
+    }
+
+    delete $known_clients->{$address};
+
+    # send bus a msg that address was deleted from known_clients
+    my $out_hash = &create_xml_hash('delete_client', $server_address, $bus_address, $address);
+    &send_msg_hash2bus($out_hash);
+
+    daemon_log("client $address deleted from known_clients because of multiple down time", 3);
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  update_known_clients
+#   PARAMETERS:  hostname - string - ip address and port of host (required)
+#                status - string - (optional)
+#                passwd - string - (optional)
+#                client - string - ip address and port of client (optional)
+#      RETURNS:  nothing
+#  DESCRIPTION:  nome est omen and updates each time the timestamp of hostname
+#===============================================================================
+sub update_known_clients {
+    my $arg = {
+        hostname => undef, status => undef, passwd => undef,
+        mac_address => undef, events => undef,
+        @_ };
+    my $hostname = $arg->{hostname};
+    my $status = $arg->{status};
+    my $passwd = $arg->{passwd};
+    my $mac_address = $arg->{mac_address};
+    my $events = $arg->{events};
+
+    if (not defined $hostname) {
+        daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1);
+        return;
+    }
+
+    my ($seconds, $minutes, $hours, $monthday, $month,
+    $year, $weekday, $yearday, $sommertime) = localtime(time);
+    $hours = $hours < 10 ? $hours = "0".$hours : $hours;
+    $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
+    $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
+    $month+=1;
+    $month = $month < 10 ? $month = "0".$month : $month;
+    $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
+    $year+=1900;
+    my $t = "$year$month$monthday$hours$minutes$seconds";
+
+    $shmcl->shlock(LOCK_EX);
+    if (defined $status) {
+        $known_clients->{$hostname}->{status} = $status;
+    }
+    if (defined $passwd) {
+        $known_clients->{$hostname}->{passwd} = $passwd;
+    }
+    if (defined $mac_address) {
+        $known_clients->{$hostname}->{mac_address} = $mac_address; 
+    }
+    if (defined $events) {
+        $known_clients->{$hostname}->{events} = $events;
+    }
+    $known_clients->{$hostname}->{timestamp} = $t;
+    $shmcl->shunlock(LOCK_EX);
+    return;
+}
+
+
+
+
+
+
+
+#==== MAIN = main ==============================================================
+
+#  parse commandline options
+Getopt::Long::Configure( "bundling" );
+GetOptions("h|help" => \&usage,
+        "c|config=s" => \$cfg_file,
+        "f|foreground" => \$foreground,
+        "v|verbose+" => \$verbose,
+        "no-bus+" => \$no_bus,
+        "no-arp+" => \$no_arp,
+           );
+
+#  read and set config parameters
+&check_cmdline_param ;
+&read_configfile;
+&check_pid;
+&import_modules;
+
+$SIG{CHLD} = 'IGNORE';
+
+# restart daemon log file
+if(-e $log_file ) { unlink $log_file }
+daemon_log(" ", 1);
+daemon_log("gosad started!", 1);
+
+# Just fork, if we"re not in foreground mode
+if( ! $foreground ) { $pid = fork(); }
+else { $pid = $$; }
+
+# Do something useful - put our PID into the pid_file
+if( 0 != $pid ) {
+    open( LOCK_FILE, ">$pid_file" );
+    print LOCK_FILE "$pid\n";
+close( LOCK_FILE );
+    if( !$foreground ) { exit( 0 ) };
+}
+
+# detect own ip and mac address
+($server_ip, $server_mac_address) = &get_ip_and_mac(); 
+if (not defined $server_ip) {
+    die "EXIT: ip address of $0 could not be detected";
+}
+daemon_log("server ip address detected: $server_ip", 1);
+daemon_log("server mac address detected: $server_mac_address", 1);
+
+# setup xml parser
+$xml = new XML::Simple();
+
+# create cipher object
+$bus_cipher = &create_ciphering($bus_passwd);
+$bus_address = "$bus_ip:$bus_port";
+
+# create reading and writing vectors
+my $rbits = my $wbits = my $ebits = "";
+
+# open server socket
+$server_address = "$server_ip:$server_port";
+if($server_activ eq "on"){
+    daemon_log(" ", 1);
+    $server = IO::Socket::INET->new(LocalPort => $server_port,
+            Type => SOCK_STREAM,
+            Reuse => 1,
+            Listen => 20,
+            ); 
+    if(not defined $server){
+        daemon_log("cannot be a tcp server at $server_port : $@");
+    } else {
+        daemon_log("start server:", 1);
+        daemon_log("\t$server_ip:$server_port",1) ;
+        vec($rbits, fileno $server, 1) = 1;
+        vec($wbits, fileno $server, 1) = 1;
+    }
+}
+
+# register at bus
+if ($no_bus > 0) {
+    $bus_activ = "off"
+}
+if($bus_activ eq "on") {
+    daemon_log(" ", 1);
+    &register_at_bus();
+}
+
+
+daemon_log(" ", 1);
+
+# start arp fifo
+if ($no_arp > 0) {
+    $arp_activ = "off";
+}
+my $my_fifo;
+if($arp_activ eq "on") {
+    $my_fifo = &open_fifo($arp_fifo_path);
+    if($my_fifo == 0) { die "fifo file disappeared\n" }
+    sysopen($arp_fifo, $arp_fifo_path, O_RDWR) or die "can't read from $arp_fifo: $!" ;
+    
+    vec($rbits, fileno $arp_fifo, 1) = 1;
+}
+
+$gosa_address = "$gosa_ip:$gosa_port";
+# start gosa inferface fifos
+if ($gosa_activ eq "on") {
+    daemon_log(" ",1);
+    $gosa_server = IO::Socket::INET->new(LocalPort => $gosa_port,
+            Type => SOCK_STREAM,
+            Reuse => 1,
+            Listen => 1,
+            );
+    if (not defined $gosa_server) {
+        daemon_log("cannot start tcp server at $gosa_port for communication to gosa: $@", 1);
+    } else {
+        daemon_log("start server at for communication to gosa", 1);
+        daemon_log("\t$server_ip:$gosa_port");
+        vec($rbits, fileno $gosa_server, 1) = 1;
+        
+    }
+
+
+    #&open_fifo($gosa_fifo_in);
+    #sysopen(GOSA_FIFO_IN, $gosa_fifo_in, O_RDWR) or die "can't read from GOSA_FIFO_IN: $!" ;
+    #vec($rbits, fileno GOSA_FIFO_IN, 1) = 1;
+
+    #&open_fifo($gosa_fifo_out);
+    #sysopen(GOSA_FIFO_OUT, $gosa_fifo_out, O_RDWR) or die "can't read from GOSA_FIFO_IN: $!" ;
+    
+}
+
+
+###################################
+#everything ready, okay, lets start
+###################################
+while(1) {
+
+    # add all handles from the childs
+    while ( my ($pid, $child_hash) = each %busy_child ) {
+        
+        # check whether process still exists
+        my $exitus_pid = waitpid($pid, WNOHANG);
+        if($exitus_pid != 0) {
+            delete $busy_child{$pid};
+            next;
+        }
+     
+        # add child fhd to the listener    
+        my $fhd = $$child_hash{'pipe_rd'};
+        vec($rbits, fileno $fhd, 1) = 1;
+    }
+
+    my ($rout, $wout);
+    my $nf = select($rout=$rbits, $wout=$wbits, undef, undef);
+
+    # error handling
+    if($nf < 0 ) {
+    }
+
+    # something is coming in
+    if($server_activ eq "on" && vec($rout, fileno $server, 1)) {
+        daemon_log(" ", 1);
+        my $client = $server->accept();
+        my $other_end = getpeername($client);
+        if(not defined $other_end) {
+            daemon_log("client cannot be identified: $!");
+        } else {
+            my ($port, $iaddr) = unpack_sockaddr_in($other_end);
+            my $actual_ip = inet_ntoa($iaddr);
+            daemon_log("accept client at daemon socket from $actual_ip", 5);
+            my $in_msg = &read_from_socket($client);
+            if(defined $in_msg){
+                chomp($in_msg);
+                &activating_child($in_msg, $actual_ip);
+            } else {
+                daemon_log("cannot read from $actual_ip", 5);
+            }
+        }
+        close($client);
+    }
+
+    if($arp_activ eq "on" && vec($rout, fileno $arp_fifo, 1)) {
+        my $in_msg = <$arp_fifo>;
+        chomp($in_msg);
+        print "arp_activ: msg: $in_msg\n";
+        my $act_passwd = $known_daemons->{$bus_address}->{passwd};
+        print "arp_activ: arp_passwd: $act_passwd\n";
+
+        my $in_msg_hash = $xml->XMLin($in_msg, ForceArray=>1);
+
+        my $target = &get_content_from_xml_hash($in_msg_hash, 'target');
+
+        if ($target eq $server_address) { 
+             print "arp_activ: forward to server\n";
+            my $arp_cipher = &create_ciphering($act_passwd);
+            my $crypted_msg = &encrypt_msg($in_msg, $arp_cipher);
+            &activating_child($crypted_msg, $server_ip);
+        } else {
+            print "arp_activ: send to bus\n";
+            &send_msg_hash2address($in_msg_hash, $bus_address);
+        }
+        print "\n";
+    }
+
+    if($gosa_activ eq "on" && vec($rout, fileno $gosa_server, 1)) {
+        daemon_log(" ", 1);
+        my $client = $gosa_server->accept();
+        my $other_end = getpeername($client);
+        if(not defined $other_end) {
+            daemon_log("client cannot be identified: $!");
+        } else {
+            my ($port, $iaddr) = unpack_sockaddr_in($other_end);
+            my $actual_ip = inet_ntoa($iaddr);
+            daemon_log("accept client at gosa socket from $actual_ip", 5);
+            my $in_msg = <$client>;
+            #my $in_msg = &read_from_socket($client);
+            
+            daemon_log(">>>>>>>>>>> frisch vom socket gelesen\n!$in_msg!\n",1);
+            if(defined $in_msg){
+                chomp($in_msg);
+                &activating_child($in_msg, $actual_ip, $client);
+            } else {
+                daemon_log("cannot read from $actual_ip", 5);
+            }
+        }
+        #close($client);
+    }
+
+    # check all processing childs whether they are finished ('done') or 
+    while ( my ($pid, $child_hash) = each %busy_child ) {
+        my $fhd = $$child_hash{'pipe_rd'};
+
+        if (vec($rout, fileno $fhd, 1) ) {
+            daemon_log("process child $pid is ready to read", 5);
+
+            $fhd->blocking(1);
+            my $in_msg = <$fhd>;
+            $fhd->blocking(0);
+            my $part_in_msg;
+            while ($part_in_msg = <$fhd>) {
+                if (not defined $part_in_msg) {
+                    last;
+                }
+                $in_msg .= $part_in_msg;
+            }
+            chomp($in_msg);
+
+            daemon_log("process child read: $in_msg", 5);
+            if (not defined $in_msg) { 
+                next; 
+            } elsif ($in_msg =~ "done") {
+                delete $busy_child{$pid};
+                $free_child{$pid} = $child_hash;
+            } else {
+                my $act_client = $busy_child{$pid}{client_ref};
+                print $act_client $in_msg."\n";
+                my $act_pipe = $busy_child{$pid}{pipe_rd};
+                sleep(10);
+                close ($act_client);   
+                delete $busy_child{$pid};
+                $free_child{$pid} = $child_hash;
+
+            }
+        }
+    }
+
+
+}
diff --git a/gosa-core/contrib/daemon/gosa-si-server.conf-template b/gosa-core/contrib/daemon/gosa-si-server.conf-template
new file mode 100644 (file)
index 0000000..8a07a63
--- /dev/null
@@ -0,0 +1,30 @@
+[general]
+log_file = /var/log/gosa-si-daemon.log
+pid_file = /var/run/gosa-si-daemon.pid
+child_max = 10
+child_min = 2
+child_timeout = 10
+
+[bus]
+bus_activ = on
+bus_passwd = secret-bus-password
+bus_ip = 127.0.0.1
+bus_port = 20080
+
+[server]
+server_activ = on
+server_port = 20081
+server_passwd = secret-server-password
+max_clients = 5
+
+[arp]
+arp_activ = off
+arp_fifo_path = /var/run/gosa-si/arp-notify
+
+[gosa]
+gosa_activ = on
+gosa_ip = 127.0.0.1
+gosa_port = 20082
+gosa_passwd = secret-gosa-password
+gosa_timeout = 5                   
+
diff --git a/gosa-core/contrib/daemon/modules/GosaPackages.pm b/gosa-core/contrib/daemon/modules/GosaPackages.pm
new file mode 100644 (file)
index 0000000..ab5938d
--- /dev/null
@@ -0,0 +1,108 @@
+package GosaPackages;
+
+use Exporter;
+@ISA = ("Exporter");
+
+# Each module has to have a function 'process_incoming_msg'. This function works as a interface to gosa-sd and recieves the msg hash from gosa-sd. 'process_incoming_function checks, wether it has a function to process the incoming msg and forward the msg to it. 
+
+
+use strict;
+use warnings;
+use GosaSupportDaemon;
+
+BEGIN{}
+
+END{}
+
+
+### START ##########################
+
+# create general settings for this module
+my $gosa_cipher = &create_ciphering($main::gosa_passwd);
+
+sub get_module_tags {
+    
+    # dort stehen drei packettypen, für die sich das modul anmelden kann, gosa-admin-packages, 
+    #   server-packages, client-packages
+    my %tag_hash = (gosa_admin_packages => "yes", 
+                    server_packages => "no", 
+                    client_packages => "no");
+    return \%tag_hash;
+}
+
+
+sub process_incoming_msg {
+    my ($crypted_msg) = @_ ;
+    if(not defined $crypted_msg) {
+        &main::daemon_log("function 'process_incoming_msg': got no msg", 7);
+    }
+    &main::daemon_log("GosaPackages: crypted_msg:$crypted_msg", 7);
+    &main::daemon_log("GosaPackages: crypted_msg len:".length($crypted_msg), 7);
+
+    $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
+    $crypted_msg = $1;
+    my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
+    &main::daemon_log("GosaPackages: crypted_msg:$crypted_msg", 7);
+    &main::daemon_log("GosaPackages: crypted_msg len:".length($crypted_msg), 7);
+
+
+    # collect addresses from possible incoming clients
+    # only gosa is allowd as incoming client
+    &main::daemon_log("GosaPackages: host_key: $host", 7);
+    &main::daemon_log("GosaPackages: key_passwd: $main::gosa_passwd", 7);
+
+    $gosa_cipher = &main::create_ciphering($main::gosa_passwd);
+    # determine the correct passwd for deciphering of the incoming msgs
+    my $msg = "";
+    my $msg_hash;
+    eval{
+        $msg = &main::decrypt_msg($crypted_msg, $gosa_cipher);
+        &main::daemon_log("GosaPackages: decrypted_msg: $msg", 7);
+
+        $msg_hash = $main::xml->XMLin($msg, ForceArray=>1);
+    };
+    if($@) {
+        &main::daemon_log("WARNING: GosaPackages do not understand the message:", 5);
+        &main::daemon_log("$@", 7);
+        return;
+    }
+
+    &main::daemon_log("GosaPackages: msg for daemon from host:", 1);
+    &main::daemon_log("\t$host", 1);
+    &main::daemon_log("GosaPackages: msg to process:", 5);
+    &main::daemon_log("\t$msg", 5);
+    
+    $msg = "gosaPackages hat was bekommen";
+    
+    my $out_cipher = &main::create_ciphering($main::gosa_passwd);
+    my $out_msg = &main::encrypt_msg($msg, $out_cipher);
+    return $out_msg;
+
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  got_ping
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+sub got_ping {
+    my ($msg_hash) = @_;
+    
+    my $source = @{$msg_hash->{source}}[0];
+    my $target = @{$msg_hash->{target}}[0];
+    my $header = @{$msg_hash->{header}}[0];
+    
+    if(exists $main::known_daemons->{$source}) {
+        &main::add_content2known_daemons(hostname=>$source, status=>$header);
+    } else {
+        &main::add_content2known_clients(hostname=>$source, status=>$header);
+    }
+    
+    return;
+}
+
+
+1;
diff --git a/gosa-core/contrib/daemon/modules/ServerPackages.pm b/gosa-core/contrib/daemon/modules/ServerPackages.pm
new file mode 100644 (file)
index 0000000..c2fc7ee
--- /dev/null
@@ -0,0 +1,455 @@
+package ServerPackages;
+
+use Exporter;
+@ISA = ("Exporter");
+
+# Each module has to have a function 'process_incoming_msg'. This function works as a interface to gosa-sd and recieves the msg hash from gosa-sd. 'process_incoming_function checks, wether it has a function to process the incoming msg and forward the msg to it. 
+
+
+use strict;
+use warnings;
+use GosaSupportDaemon;
+
+BEGIN{}
+
+END {}
+
+
+### START ##########
+
+
+
+sub get_module_tags {
+    
+    # lese config file aus dort gibt es eine section Basic
+    # dort stehen drei packettypen, für die sich das modul anmelden kann, gosa-admin-packages, 
+    #   server-packages, client-packages
+    my %tag_hash = (gosa_admin_packages => "yes", 
+                    server_packages => "yes", 
+                    client_packages => "yes",
+                    );
+    return \%tag_hash;
+}
+
+
+sub process_incoming_msg {
+    my ($crypted_msg) = @_ ;
+    if(not defined $crypted_msg) {
+        &main::daemon_log("function 'process_incoming_msg': got no msg", 7);
+    }
+    $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/;
+    $crypted_msg = $1;
+    my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5);
+
+    # collect addresses from possible incoming clients
+    my @valid_keys;
+    my @host_keys = keys %$main::known_daemons;
+    foreach my $host_key (@host_keys) {    
+        if($host_key =~ "^$host") {
+            push(@valid_keys, $host_key);
+        }
+    }
+    my @client_keys = keys %$main::known_clients;
+    foreach my $client_key (@client_keys) {
+        if($client_key =~ "^$host"){
+            push(@valid_keys, $client_key);
+        }
+    }
+    push(@valid_keys, $main::server_address);
+    
+    my $l = @valid_keys;
+    my $msg_hash;
+    my $msg_flag = 0;    
+    my $msg = "";
+
+    # determine the correct passwd for deciphering of the incoming msgs
+    foreach my $host_key (@valid_keys) {
+        eval{
+            &main::daemon_log("ServerPackage: host_key: $host_key", 7);
+            my $key_passwd;
+            if (exists $main::known_daemons->{$host_key}) {
+                $key_passwd = $main::known_daemons->{$host_key}->{passwd};
+            } elsif (exists $main::known_clients->{$host_key}) {
+                $key_passwd = $main::known_clients->{$host_key}->{passwd};
+            } elsif ($host_key eq $main::server_address) {
+                $key_passwd = $main::server_passwd;
+            } 
+            &main::daemon_log("ServerPackage: key_passwd: $key_passwd", 7);
+            my $key_cipher = &create_ciphering($key_passwd);
+            $msg = &decrypt_msg($crypted_msg, $key_cipher);
+            &main::daemon_log("ServerPackages: decrypted msg: $msg", 7);
+            $msg_hash = $main::xml->XMLin($msg, ForceArray=>1);
+            #my $tmp = printf Dumper $msg_hash;
+            #&main::daemon_log("DEBUG: ServerPackages: xml hash: $tmp", 7);
+        };
+        if($@) {
+            &main::daemon_log("ServerPackage: key raise error: $@", 7);
+            $msg_flag += 1;
+        } else {
+            last;
+        }
+    } 
+    
+    if($msg_flag >= $l)  {
+        &main::daemon_log("WARNING: ServerPackage do not understand the message:", 5);
+        &main::daemon_log("$@", 7);
+        return;
+    }
+
+    # process incoming msg
+    my $header = @{$msg_hash->{header}}[0]; 
+    my $source = @{$msg_hash->{source}}[0];
+
+    &main::daemon_log("ServerPackages: msg from host:", 5);
+    &main::daemon_log("\t$host", 5);
+    &main::daemon_log("ServerPackages: header from msg:", 5);
+    &main::daemon_log("\t$header", 5);
+    &main::daemon_log("ServerPackages: msg to process:", 5);
+    &main::daemon_log("\t$msg", 5);
+
+    my @targets = @{$msg_hash->{target}};
+    my $len_targets = @targets;
+    if ($len_targets == 0){     
+        &main::daemon_log("ERROR: ServerPackages: no target specified for msg $header", 1);
+
+    }  elsif ($len_targets == 1){
+        # we have only one target symbol
+
+        my $target = $targets[0];
+        &main::daemon_log("SeverPackages: msg is for:", 7);
+        &main::daemon_log("\t$target", 7);
+
+        if ($target eq $main::server_address) {
+            # msg is for server
+            if ($header eq 'new_passwd'){ &new_passwd($msg_hash)}
+            elsif ($header eq 'here_i_am') { &here_i_am($msg_hash)}
+            elsif ($header eq 'who_has') { &who_has($msg_hash) }
+            elsif ($header eq 'who_has_i_do') { &who_has_i_do($msg_hash)}
+            elsif ($header eq 'update_status') { &update_status($msg_hash) }
+            elsif ($header eq 'got_ping') { &got_ping($msg_hash)}
+            elsif ($header eq 'get_load') { &execute_actions($msg_hash)}
+            else { &main::daemon_log("ERROR: ServerPackages: no function assigned to this msg", 5) }
+
+        
+       } elsif ($target eq "*") {
+            # msg is for all clients
+
+            my @target_addresses = keys(%$main::known_clients);
+            foreach my $target_address (@target_addresses) {
+                if ($target_address eq $source) { next; }
+                $msg_hash->{target} = [$target_address];
+                &send_msg_hash2address($msg_hash, $target_address);
+            }           
+        } else {
+            # msg is for one host
+
+            if (exists $main::known_clients->{$target}) {
+                &send_msg_hash2address($msg_hash, $target);
+            } elsif (exists $main::known_daemons->{$target}) {
+                # target is known
+                &send_msg_hash2address($msg_hash, $target);
+            } else {
+                # target is not known
+                &main::daemon_log("ERROR: ServerPackages: target $target is not known neither in known_clients nor in known_daemons", 1);
+            }
+        }
+    }
+
+    return ;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  got_ping
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+sub got_ping {
+    my ($msg_hash) = @_;
+    
+    my $source = @{$msg_hash->{source}}[0];
+    my $target = @{$msg_hash->{target}}[0];
+    my $header = @{$msg_hash->{header}}[0];
+    
+    if(exists $main::known_daemons->{$source}) {
+        &main::add_content2known_daemons(hostname=>$source, status=>$header);
+    } else {
+        &main::add_content2known_clients(hostname=>$source, status=>$header);
+    }
+    
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  new_passwd
+#   PARAMETERS:  msg_hash - ref - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+sub new_passwd {
+    my ($msg_hash) = @_;
+
+    my $source = @{$msg_hash->{source}}[0];
+    my $passwd = @{$msg_hash->{new_passwd}}[0];
+
+    if (exists $main::known_daemons->{$source}) {
+        &main::add_content2known_daemons(hostname=>$source, status=>"new_passwd", passwd=>$passwd);
+        my $hash = &create_xml_hash("confirm_new_passwd", $main::server_address, $source);
+        &send_msg_hash2address($hash, $source);
+
+    } elsif (exists $main::known_clients->{$source}) {
+        &main::add_content2known_clients(hostname=>$source, status=>"new_passwd", passwd=>$passwd);
+
+    } else {
+        &main::daemon_log("ERROR: $source not known, neither in known_daemons nor in known_clients", 1)   
+    }
+
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  here_i_am
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+sub here_i_am {
+    my ($msg_hash) = @_;
+
+    my $source = @{$msg_hash->{source}}[0];
+    my $mac_address = @{$msg_hash->{mac_address}}[0];
+    my $out_hash;
+
+    # number of known clients
+    my $nu_clients = keys %$main::known_clients;
+
+    # check wether client address or mac address is already known
+    if (exists $main::known_clients->{$source}) {
+        &main::daemon_log("WARNING: $source is already known as a client", 1);
+        &main::daemon_log("WARNING: values for $source are being overwritten", 1);   
+        $nu_clients --;
+    }
+
+    # number of actual activ clients
+    my $act_nu_clients = $nu_clients;
+
+    &main::daemon_log("number of actual activ clients: $act_nu_clients", 5);
+    &main::daemon_log("number of maximal allowed clients: $main::max_clients", 5);
+
+    if($main::max_clients <= $act_nu_clients) {
+        my $out_hash = &create_xml_hash("denied", $main::server_address, $source);
+        &add_content2xml_hash($out_hash, "denied", "I_cannot_take_any_more_clients!");
+        my $passwd = @{$msg_hash->{new_passwd}}[0]; 
+        &send_msg_hash2address($out_hash, $source, $passwd);
+        return;
+    }
+    
+    # new client accepted
+    my $new_passwd = @{$msg_hash->{new_passwd}}[0];
+
+    # create known_daemons entry
+    my $events = @{$msg_hash->{events}}[0];
+    &main::create_known_client($source);
+    &main::add_content2known_clients(hostname=>$source, events=>$events, mac_address=>$mac_address, 
+                                status=>"registered", passwd=>$new_passwd);
+
+    # return acknowledgement to client
+    $out_hash = &create_xml_hash("registered", $main::server_address, $source);
+    &send_msg_hash2address($out_hash, $source);
+
+    # notify registered client to bus
+    $out_hash = &main::create_xml_hash("new_client", $main::server_address, $main::bus_address, $source);
+    &main::send_msg_hash2bus($out_hash);
+
+    # give the new client his ldap config
+    &new_ldap_config($source);
+
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  who_has
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing 
+#  DESCRIPTION:  process this incoming message
+#===============================================================================
+sub who_has {
+    my ($msg_hash) = @_ ;
+    
+    # what is your search pattern
+    my $search_pattern = @{$msg_hash->{who_has}}[0];
+    my $search_element = @{$msg_hash->{$search_pattern}}[0];
+    &main::daemon_log("who_has-msg looking for $search_pattern $search_element", 7);
+
+    # scanning known_clients for search_pattern
+    my @host_addresses = keys %$main::known_clients;
+    my $known_clients_entries = length @host_addresses;
+    my $host_address;
+    foreach my $host (@host_addresses) {
+        my $client_element = $main::known_clients->{$host}->{$search_pattern};
+        if ($search_element eq $client_element) {
+            $host_address = $host;
+            last;
+        }
+    }
+        
+    # search was successful
+    if (defined $host_address) {
+        my $source = @{$msg_hash->{source}}[0];
+        my $out_msg = &main::create_xml_hash("who_has_i_do", $main::server_address, $source, "mac_address");
+        &main::add_content2xml_hash($out_msg, "mac_address", $search_element);
+        &main::send_msg_hash2address($out_msg, $main::bus_address);
+    }
+    return;
+}
+
+
+sub who_has_i_do {
+    my ($msg_hash) = @_ ;
+    my $header = @{$msg_hash->{header}}[0];
+    my $source = @{$msg_hash->{source}}[0];
+    my $search_param = @{$msg_hash->{$header}}[0];
+    my $search_value = @{$msg_hash->{$search_param}}[0];
+    print "\ngot msg $header:\nserver $source has client with $search_param $search_value\n";
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  new_ldap_config
+#   PARAMETERS:  address - string - ip address and port of a host
+#      RETURNS:  nothing
+#  DESCRIPTION:  send to address the ldap configuration found for dn gotoLdapServer
+#===============================================================================
+sub new_ldap_config {
+    my ($address) = @_ ;
+    
+    if (not exists $main::known_clients->{$address}) {
+        &main::daemon_log("ERROR: $address does not exist in known_clients, cannot send him his ldap config", 1);
+        return;
+    }
+    
+    my $mac_address = $main::known_clients->{$address}->{"mac_address"};
+    if (not defined $mac_address) {
+        &main::daemon_log("ERROR: no mac address found for client $address", 1);
+        return;
+    }
+
+    # fetch dn
+    my $goHard_cmd = "ldapsearch -x '(&(objectClass=goHard)(macAddress=00:11:22:33:44:57))' dn gotoLdapServer";
+    my $dn;
+    my @gotoLdapServer;
+    open (PIPE, "$goHard_cmd 2>&1 |");
+#    my $rbits = "";
+#    vec($rbits, fileno PIPE, 1) = 1;
+#    my $rout;
+#    my $nf = select($rout=$rbits, undef, undef, $ldap_timeout);
+    while(<PIPE>) {
+        chomp $_;
+        # If it's a comment, goto next
+        if ($_ =~ m/^[#]/) { next;}
+        if ($_ =~ m/^dn: ([\S]+?)$/) {
+            $dn = $1;
+        } elsif ($_ =~ m/^gotoLdapServer: ([\S]+?)$/) {
+            push(@gotoLdapServer, $1);
+        }
+    }
+    close(PIPE);
+    
+    # no dn found
+    if (not defined $dn) {
+        &main::daemon_log("ERROR: no dn arose from command: $goHard_cmd", 1);
+        return;
+    }
+    
+    # no gotoLdapServer found
+    my $gosaGroupOfNames_cmd = "ldapsearch -x '(&(objectClass=gosaGroupOfNames)(member=$dn))' gotoLdapServer";
+    if (@gotoLdapServer == 0) {
+        open (PIPE, "$gosaGroupOfNames_cmd 2>&1 |");
+        while(<PIPE>) {
+            chomp $_;
+            if ($_ =~ m/^[#]/) { next; }
+            if ($_ =~ m/^gotoLdapServer: ([\S]+?)$/) {
+                push(@gotoLdapServer, $1);
+            }
+        }
+        close(PIPE);
+    }
+
+    # still no gotoLdapServer found
+    if (@gotoLdapServer == 0) {
+        &main::daemon_log("ERROR: cannot find gotoLdapServer entry in command: $gosaGroupOfNames_cmd", 1);
+        return;
+    }
+
+    # sort @gotoLdapServer and then split of ranking
+    my @sorted_gotoLdapServer = sort(@gotoLdapServer);
+    @gotoLdapServer = reverse(@sorted_gotoLdapServer);
+    foreach (@gotoLdapServer) {
+        $_ =~ s/^\d://;
+    }
+
+    my $t = join(" ", @gotoLdapServer);
+    my $out_hash = &main::create_xml_hash("new_ldap_config", $main::server_address, $address);
+    map(&main::add_content2xml_hash($out_hash, "new_ldap_config", $_), @gotoLdapServer);
+    &main::send_msg_hash2address($out_hash, $address);
+
+    return;
+}
+
+
+#===  FUNCTION  ================================================================
+#         NAME:  execute_actions
+#   PARAMETERS:  msg_hash - hash - hash from function create_xml_hash
+#      RETURNS:  nothing
+#  DESCRIPTION:  invokes the script specified in msg_hash which is located under
+#                /etc/gosad/actions
+#===============================================================================
+sub execute_actions {
+    my ($msg_hash) = @_ ;
+    my $configdir= '/etc/gosad/actions/';
+    my $result;
+
+    my $header = @{$msg_hash->{header}}[0];
+    my $source = @{$msg_hash->{source}}[0];
+    my $target = @{$msg_hash->{target}}[0];
+    if((not defined $source)
+            && (not defined $target)
+            && (not defined $header)) {
+        &main::daemon_log("ERROR: Entries missing in XML msg for gosad actions under /etc/gosad/actions");
+    } else {
+        my $parameters="";
+        my @params = @{$msg_hash->{$header}};
+        my $params = join(", ", @params);
+        &main::daemon_log("execute_actions: got parameters: $params", 5);
+
+        if (@params) {
+            foreach my $param (@params) {
+                my $param_value = (&get_content_from_xml_hash($msg_hash, $param))[0];
+                &main::daemon_log("execute_actions: parameter -> value: $param -> $param_value", 7);
+                $parameters.= " ".$param_value;
+            }
+        }
+
+        my $cmd= $configdir.$header."$parameters";
+        &main::daemon_log("execute_actions: executing cmd: $cmd", 7);
+        $result= "";
+        open(PIPE, "$cmd 2>&1 |");
+        while(<PIPE>) {
+            $result.=$_;
+        }
+        close(PIPE);
+    }
+
+    # process the event result
+
+
+    return;
+}
+
+1;
diff --git a/gosa-core/contrib/daemon/tests/testGOsa.pl b/gosa-core/contrib/daemon/tests/testGOsa.pl
new file mode 100644 (file)
index 0000000..9ecb8f3
--- /dev/null
@@ -0,0 +1,107 @@
+#!/usr/bin/perl 
+#===============================================================================
+#
+#         FILE:  testGosa.pl
+#
+#        USAGE:  ./testGosa.pl 
+#
+#  DESCRIPTION:  
+#
+#      OPTIONS:  ---
+# REQUIREMENTS:  ---
+#         BUGS:  ---
+#        NOTES:  ---
+#       AUTHOR:   (), <>
+#      COMPANY:  
+#      VERSION:  1.0
+#      CREATED:  06.12.2007 14:31:37 CET
+#     REVISION:  ---
+#===============================================================================
+
+use strict;
+use warnings;
+use IO::Socket::INET;
+use Digest::MD5  qw(md5 md5_hex md5_base64);
+use Crypt::Rijndael;
+use MIME::Base64;
+
+sub create_ciphering {
+    my ($passwd) = @_;
+
+    $passwd = substr(md5_hex("$passwd") x 32, 0, 32);
+    my $iv = substr(md5_hex('GONICUS GmbH'),0, 16);
+    print "iv: $iv\n";
+    print "key: $passwd\n";
+
+    my $my_cipher = Crypt::Rijndael->new($passwd ,Crypt::Rijndael::MODE_CBC() );
+    $my_cipher->set_iv($iv);
+    return $my_cipher;
+}
+
+sub decrypt_msg {
+    my ($crypted_msg, $my_cipher) = @_ ;
+    $crypted_msg = &decode_base64($crypted_msg);
+    my $msg = $my_cipher->decrypt($crypted_msg); 
+    return $msg;
+}
+
+sub encrypt_msg {
+    my ($msg, $my_cipher) = @_;
+    if(not defined $my_cipher) { print "no cipher object\n"; }
+    $msg = "\0"x(16-length($msg)%16).$msg;
+    my $crypted_msg = $my_cipher->encrypt($msg);
+    chomp($crypted_msg = &encode_base64($crypted_msg));
+    return $crypted_msg;
+}
+
+
+
+my $gosa_server = IO::Socket::INET->new(LocalPort => "9999",
+        Type => SOCK_STREAM,
+        Reuse => 1,
+        Listen => 1,
+        );
+
+
+
+
+
+my $client = $gosa_server->accept();
+my $other_end = getpeername($client);
+if(not defined $other_end) {
+    print "client cannot be identified:";
+} else {
+    my ($port, $iaddr) = unpack_sockaddr_in($other_end);
+    my $actual_ip = inet_ntoa($iaddr);
+    print "accept client at gosa socket from $actual_ip\n";
+    chomp(my $crypted_msg = <$client>);
+    print "crypted msg: <<<$crypted_msg<<<\n";
+
+    my $cipher = &create_ciphering("ferdinand_frost");
+
+    my $msg = &decrypt_msg($crypted_msg, $cipher);
+    print "msg: <<<$msg<<<\n";
+
+    print "\n#################################\n\n";
+
+    my $answer = "gosa answer: $msg";
+
+    print "answer: $answer\n";
+    
+    my $out_cipher = &create_ciphering("ferdinand_frost");
+    my $crypted_answer = &encrypt_msg($answer, $out_cipher);
+    
+    print $client $crypted_answer."\n";
+
+}
+
+sleep(3);
+close($client);
+
+
+
+
+
+
+
+
diff --git a/gosa-core/contrib/demo.ldif b/gosa-core/contrib/demo.ldif
new file mode 100644 (file)
index 0000000..dc2ce2f
--- /dev/null
@@ -0,0 +1,48 @@
+dn: dc=gonicus,dc=de
+objectClass: dcObject
+objectClass: organization
+description: Base object
+dc: gonicus
+o: GONICUS GmbH
+
+dn: cn=terminal-admin,dc=gonicus,dc=de
+objectClass: person
+cn: terminal-admin
+sn: Upload user
+description: GOto Upload Benutzer
+userPassword:: e2tlcmJlcm9zfXRlcm1pbmFsYWRtaW5AR09OSUNVUy5MT0NBTAo=
+
+dn: ou=groups,dc=gonicus,dc=de
+objectClass: organizationalUnit
+ou: groups
+
+dn: ou=people,dc=gonicus,dc=de
+objectClass: organizationalUnit
+ou: people
+
+dn: cn=admin,ou=people,dc=gonicus,dc=de
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+objectClass: gosaAccount
+uid: admin
+cn: admin
+givenName: admin
+sn: GOsa main administrator
+sambaLMPassword: 10974C6EFC0AEE1917306D272A9441BB
+sambaNTPassword: 38F3951141D0F71A039CFA9D1EC06378
+userPassword:: dGVzdGVy
+
+dn: cn=administrators,ou=groups,dc=gonicus,dc=de
+objectClass: gosaObject
+objectClass: posixGroup
+objectClass: top
+gosaSubtreeACL: :all
+cn: administrators
+gidNumber: 999
+memberUid: admin
+
+dn: ou=incoming,dc=gonicus,dc=de
+objectClass: organizationalUnit
+ou: incoming
+
diff --git a/gosa-core/contrib/encodings b/gosa-core/contrib/encodings
new file mode 100755 (executable)
index 0000000..51d6f82
--- /dev/null
@@ -0,0 +1,9 @@
+# Encodings for class_servNfs.inc
+# This file should be placed in /etc/gosa/
+UTF-8=UTF-8
+ISO8859-1=ISO8859-1 (Latin 1)
+ISO8859-2=ISO8859-2 (Latin 2)
+ISO8859-3=ISO8859-3 (Latin 3)
+ISO8859-4=ISO8859-4 (Latin 4)
+ISO8859-5=ISO8859-5 (Latin 5)
+cp850=CP850 (Europe)
diff --git a/gosa-core/contrib/fai/README.fai b/gosa-core/contrib/fai/README.fai
new file mode 100644 (file)
index 0000000..89afff5
--- /dev/null
@@ -0,0 +1,26 @@
+FAI support for GOsa
+====================
+
+Please note, that FAI support is work in progress. Anyway here's a quick
+guide how it works:
+
+1) Preparing FAI
+
+ a) adjust the secrets file to match the password of your terminal-admin
+    ldap user
+ b) build the debian package in goto-fai (i.e. using dpkg-buidpackage)
+ c) add the resulting package to your fai nfs-root
+
+2) Preparing GOsa
+
+ a) use the get-packages.pl script to generate a stripped down list of your
+    packages lists, move them to /etc/gosa/fai/servername/dist/.
+
+ b) use the get-debconf.sh script to extract the debconf templates from
+    your mirror, move the resulting debconf.d directory to
+       /etc/gosa/fai/servername/dist/debconf.d
+
+3) Create classes/etc in GOsa, follow the ordinary fai documentation to
+   get your clients booted
+
+
diff --git a/gosa-core/contrib/fai/get-debconf.sh b/gosa-core/contrib/fai/get-debconf.sh
new file mode 100755 (executable)
index 0000000..dc7d2ed
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Call with:
+# find /path/to/your/debmirror -name \*.deb | xargs ./get-debconf
+# Move result to /etc/gosa/fai/server/debconf.d
+
+[ -d /tmp/debconf.d ] && mkdir /tmp/debconf.d
+for i in $@; do
+    dpkg -e $i /tmp/debconf.d/DEBIAN
+    if [ -f /tmp/debconf.d/DEBIAN/templates ]; then
+       pp=$(basename $i)
+       p=${pp%%_*}
+        echo $p has debconf template
+       mv /tmp/debconf.d/DEBIAN/templates /tmp/debconf.d/$p.templates
+    fi
+done
+
+
diff --git a/gosa-core/contrib/fai/get-packages.pl b/gosa-core/contrib/fai/get-packages.pl
new file mode 100755 (executable)
index 0000000..7df4194
--- /dev/null
@@ -0,0 +1,140 @@
+#!/usr/bin/perl
+
+use strict;
+use File::Path;
+use File::Basename;
+
+# Check for parameters
+if ($ARGV[0] eq ""){
+       die ("Usage: parse-pkg <config-file>\n");
+}
+
+# Generate cache
+gen_cache($ARGV[0]);
+exit 0;
+
+#-----------------------------------------------------------------------------
+
+sub gen_cache
+{
+       my ($conffile)= @_;
+       my $line;
+
+       print "Generating GOsa package cache - this may take some time\n";
+       open(CONFIG, "<$conffile") or die("Failed to open '$conffile' - aborted\n");
+       
+       # Read lines
+       while ($line = <CONFIG>){
+               # Unify
+               chop($line);
+               $line =~ s/^\s+//;
+               $line =~ s/^\s+/ /;
+
+               # Strip comments
+               $line =~ s/#.*$//g;
+
+               # Skip empty lines
+               if ($line =~ /^\s*$/){
+                       next;
+               }
+
+               # Interpret deb line
+               if ($line =~ /^deb [^\s]+\s[^\s]+\s[^\s]+/){
+                       my ($baseurl)  = ($line =~ /^deb\s([^\s]+)/);
+                       my ($dist)     = ($line =~ /^deb\s[^\s]+\s([^\s]+)/);
+                       my ($sections) = ($line =~ /^deb\s[^\s]+\s[^\s]+\s(.*)$/);
+                       
+                       my $section;
+                       foreach $section (split(" ", $sections)){
+                               parse_package_info ("$baseurl", "$dist", "$section");
+                       }
+               }
+       }
+
+       close (CONFIG);
+}
+
+#-----------------------------------------------------------------------------
+
+sub parse_package_info
+{
+       my ($baseurl, $dist, $section)= @_;
+       my ($package, $server);
+
+       foreach $package ("Packages.gz"){
+               print ("* trying to retrieve $baseurl/dists/$dist/$section/binary-i386/$package\n");
+       
+               ($server)= ($baseurl =~ /^[^\/]+\/\/([^\/]+)\/.*$/);
+               get_package("$baseurl/dists/$dist/$section/binary-i386/$package", "/etc/gosa/fai/$server/$dist/$section");
+               parse_package("/etc/gosa/fai/$server/$dist/$section");
+               last;
+       }
+}
+
+#-----------------------------------------------------------------------------
+
+sub get_package
+{
+       my ($url, $dest)= @_;
+
+       # This is ugly, but I've no time to take a look at "how it works in perl"
+       system("wget '$url' -O '$dest'");
+       system("gzip -cd '$dest' > '$dest.in'");
+       system("rm -f '$dest'");
+
+       return 0;
+}
+
+#-----------------------------------------------------------------------------
+
+sub parse_package
+{
+       my ($path)= @_;
+       my ($name, $desc, $vers, $sect, $line);
+
+       my $tpath= dirname($path);
+       -d "$tpath" || mkpath "$tpath";
+
+       open(PACKAGES, "<$path.in") or die("Failed to open '$path.in' - aborted\n");
+       open(OUT, ">$path") or die("Failed to open '$path' - aborted\n");
+       
+       # Read lines
+       while ($line = <PACKAGES>){
+               # Unify
+               chop($line);
+
+               # Use empty lines as a trigger
+               if ($line =~ /^\s*$/){
+                       print OUT "$name|$vers|$sect|$desc\n";
+                       next;
+               }
+
+               # Trigger for package name
+               if ($line =~ /^Package:\s/){
+                       ($name)= ($line =~ /^Package: (.*)$/);
+                       next;
+               }
+
+               # Trigger for version
+               if ($line =~ /^Version:\s/){
+                       ($vers)= ($line =~ /^Version: (.*)$/);
+                       next;
+               }
+
+               # Trigger for description
+               if ($line =~ /^Description:\s/){
+                       ($desc)= ($line =~ /^Description: (.*)$/);
+                       next;
+               }
+
+               # Trigger for description
+               if ($line =~ /^Section:\s/){
+                       ($sect)= ($line =~ /^Section: (.*)$/);
+                       next;
+               }
+       }
+
+       close (OUT);
+       close (PACKAGES);
+}
+
diff --git a/gosa-core/contrib/fai/goto-fai/Makefile b/gosa-core/contrib/fai/goto-fai/Makefile
new file mode 100644 (file)
index 0000000..85756c2
--- /dev/null
@@ -0,0 +1,19 @@
+all:
+       @echo "Nothing to do for all"
+
+install:
+       mkdir -p $(DESTDIR)/usr/sbin
+       mkdir -p $(DESTDIR)/etc/goto
+       mkdir -p $(DESTDIR)/usr/lib/goto
+       mkdir -p $(DESTDIR)/fai/hooks
+       cp secret $(DESTDIR)/etc/goto
+       cp -a get_fai_dir faimond $(DESTDIR)/usr/sbin
+       cp -a goto-support.lib $(DESTDIR)/usr/lib/goto
+       cp -a ldap2fai $(DESTDIR)/usr/sbin
+       cp confdir.DEFAULT.source $(DESTDIR)/fai/hooks
+       chmod go-rwx $(DESTDIR)/etc/goto/secret
+
+       # Install diversions
+       mkdir -p $(DESTDIR)/usr/lib/fai/sbin
+       cp diversions/setup_harddisks $(DESTDIR)/usr/lib/fai/sbin
+
diff --git a/gosa-core/contrib/fai/goto-fai/confdir.DEFAULT.source b/gosa-core/contrib/fai/goto-fai/confdir.DEFAULT.source
new file mode 100755 (executable)
index 0000000..afed2a2
--- /dev/null
@@ -0,0 +1,19 @@
+# undef default shell subroutine get_fai_dir
+# instead the new script get_fai_dir will be used
+
+setterm -cursor off >/dev/tty3
+/usr/sbin/faimond >/dev/tty3 & 
+chvt 3
+unset get_fai_dir
+unset sndmon
+
+sndmon() {
+       # send message to monitor daemon
+       [ "$faimond" -eq 0 ] && return 0
+       if [ "$debug" ];then
+               echo "$sndhostname $*" | nc localhost 4711
+       else
+               echo "$sndhostname $*" | nc localhost 4711 2>/dev/null
+       fi
+       return $?
+}
diff --git a/gosa-core/contrib/fai/goto-fai/debian/README.debian b/gosa-core/contrib/fai/goto-fai/debian/README.debian
new file mode 100644 (file)
index 0000000..584b1da
--- /dev/null
@@ -0,0 +1,6 @@
+goto-fai for Debian
+-------------------
+
+Comments regarding the Package
+
+Cajus Pollmeier <pollmeier@gonicus.de>, Thu, 17 Mar 2005 09:05:17 +0100
diff --git a/gosa-core/contrib/fai/goto-fai/debian/changelog b/gosa-core/contrib/fai/goto-fai/debian/changelog
new file mode 100644 (file)
index 0000000..905c15e
--- /dev/null
@@ -0,0 +1,5 @@
+goto-fai (2.0-1) unstable; urgency=low
+
+  * Initial release.
+
+ -- Cajus Pollmeier <pollmeier@gonicus.de>  Thu, 17 Mar 2005 09:05:17 +0100
diff --git a/gosa-core/contrib/fai/goto-fai/debian/control b/gosa-core/contrib/fai/goto-fai/debian/control
new file mode 100644 (file)
index 0000000..1cf6184
--- /dev/null
@@ -0,0 +1,12 @@
+Source: goto-fai
+Section: lhm/main
+Priority: optional
+Maintainer: Cajus Pollmeier <pollmeier@gonicus.de>
+Standards-Version: 3.6.1
+Build-Depends: debmake
+
+Package: goto-fai
+Architecture: any
+Depends: ${shlibs:Depends}, libnet-ldap-perl, hwdata-knoppix, hwsetup, ddcxinfo-knoppix
+Description: GOto support scripts
+ Support and build scripts for terminal server
diff --git a/gosa-core/contrib/fai/goto-fai/debian/copyright b/gosa-core/contrib/fai/goto-fai/debian/copyright
new file mode 100644 (file)
index 0000000..e18fe19
--- /dev/null
@@ -0,0 +1,8 @@
+This package was debianized by cajus cajus@ots-2.gonicus.local on
+Thu, 17 Mar 2005 09:05:17 +0100.
+
+It was downloaded from <fill in ftp site>
+
+Copyright:
+
+<Must follow here>
diff --git a/gosa-core/contrib/fai/goto-fai/debian/dirs b/gosa-core/contrib/fai/goto-fai/debian/dirs
new file mode 100644 (file)
index 0000000..ca882bb
--- /dev/null
@@ -0,0 +1,2 @@
+usr/bin
+usr/sbin
diff --git a/gosa-core/contrib/fai/goto-fai/debian/postrm b/gosa-core/contrib/fai/goto-fai/debian/postrm
new file mode 100755 (executable)
index 0000000..526aaad
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh -e
+
+#DEBHELPER#
+
+if [ "remove" = "$1" ]; then
+       dpkg-divert --package goto-fai --remove --rename \
+               --divert /usr/lib/fai/sbin/setup_harddisks.goto-fai \
+                       /usr/lib/fai/sbin/setup_harddisks
+fi
+
+exit 0
diff --git a/gosa-core/contrib/fai/goto-fai/debian/preinst b/gosa-core/contrib/fai/goto-fai/debian/preinst
new file mode 100755 (executable)
index 0000000..fa469b9
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh -e
+
+#DEBHELPER#
+#
+if [ ! -e /usr/lib/fai/sbin/setup_harddisks.goto-fai ]; then
+       dpkg-divert --package goto-fai --add --rename \
+               --divert /usr/lib/fai/sbin/setup_harddisks.goto-fai \
+               /usr/lib/fai/sbin/setup_harddisks
+fi
+
+exit 0
diff --git a/gosa-core/contrib/fai/goto-fai/debian/rules b/gosa-core/contrib/fai/goto-fai/debian/rules
new file mode 100755 (executable)
index 0000000..6967ca5
--- /dev/null
@@ -0,0 +1,50 @@
+#!/usr/bin/make -f
+# Made with the aid of debmake, by Christoph Lameter,
+# based on the sample debian/rules file for GNU hello by Ian Jackson.
+
+package=goto
+
+build:
+       $(checkdir)
+       
+       $(MAKE) CFLAGS="-O2 -g -Wall"
+       touch build
+
+clean:
+       $(checkdir)
+       rm -f build
+       -$(MAKE) clean
+       rm -f `find . -name "*~"`
+       rm -rf debian/tmp debian/files* core debian/substvars
+
+binary-indep: checkroot build
+       $(checkdir)
+# There are no architecture-independent files to be uploaded
+# generated by this package.  If there were any they would be
+# made here.
+
+binary-arch: checkroot build
+       $(checkdir)
+       rm -rf debian/tmp
+       install -d debian/tmp
+       cd debian/tmp && install -d `cat ../dirs`
+       $(MAKE) install DESTDIR=`pwd`/debian/tmp
+# Must have debmake installed for this to work. Otherwise please copy
+# /usr/bin/debstd into the debian directory and change debstd to debian/debstd
+       debstd 
+       dpkg-gencontrol -isp
+       chown -R root:root debian/tmp
+       chmod -R go=rX debian/tmp
+       dpkg --build debian/tmp ..
+
+define checkdir
+       test -f debian/rules
+endef
+
+binary: binary-indep binary-arch
+
+checkroot:
+       $(checkdir)
+       test root = "`whoami`"
+
+.PHONY: binary binary-arch binary-indep clean checkroot
diff --git a/gosa-core/contrib/fai/goto-fai/diversions/setup_harddisks b/gosa-core/contrib/fai/goto-fai/diversions/setup_harddisks
new file mode 100755 (executable)
index 0000000..de1427c
--- /dev/null
@@ -0,0 +1,954 @@
+#!/usr/bin/perl
+
+# $Id: setup_harddisks,v 1.41 2005/04/08 10:08:54 lange Exp $
+#*********************************************************************
+#
+# setup_harddisks -- create partitions and filesystems on harddisk
+#
+# This script is part of FAI (Fully Automatic Installation)
+# Copyright (c) 1999, 2000 by ScALE Workgroup, Universitaet zu Koeln
+# Copyright (c) 2000-2005 by Thomas Lange, Uni Koeln
+#
+#*********************************************************************
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING. If not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA.
+#*********************************************************************
+#
+# This program first read the configfiles, partitions and formats the harddisks,
+# produces fstab and FAI-variables-file.  It uses sfdisk, mke2fs, mkswap
+#
+# Parameters:
+# [-X]                     no test, your harddisks will be formated
+#                          default: only test, no real formating
+# [-f<config-filename>]    default: parse classes
+# [-c<class-path>]         default: $FAI/disk_config/
+# [-d]                     default: no DOS alignment
+#
+#---------------------------------------------------
+# Last changes:  31.3.2005 by Thomas Lange add sub mapdisk{}
+# Last changes:  8.11.2004 by Thomas Lange add $devdisklist when calling sfdisk
+# Last changes:   3.2.2004 by Thomas Lange typos
+# Last changes: 14.07.2003 by Thomas Lange add xfs filesystem support
+# Last changes: 23.01.2003 by Thomas Lange print info data to stdout
+# Last changes: 03.12.2002 by Thomas Lange remove ida, cciss stuff. Just match everything
+# Last changes: 27.11.2002 by Thomas Lange allow more that 3 primary partitions
+# Last changes: 14.05.2002 by Thomas Lange use strict
+# Last changes: 04.05.2002 by Thomas Lange use strict
+# Last changes: 29.04.2002 by Thomas Lange add swaplist
+# Last changes: 12.01.2002 by Thomas Lange
+# /dev/ida/ patch 12.01.2002 by Marc Martinez <lastxit+fai@technogeeks.org>
+# Last changes: 9.11.2001 by Thomas Lange
+# reiserfs patch 8.11.2001 by Diane Trout <diane@caltech.edu>
+# Last changes: 25.10.2001 by Thomas Lange
+# Last changes: 09.07.2001 by Thomas Lange
+# Last changes: 04.07.2001 by Thomas Lange
+# Last changes: 06.05.2001 by Thomas Lange
+# Last changes: 09.03.2001 by Thomas Lange
+# Last changes: 05.12.2000 by Thomas Lange
+# Last changes: 03.05.2000 by Thomas Lange
+# Last changes: 03.04.2000 by Mattias Gaertner
+#---------------------------------------------------
+#
+# config-file format:
+#   lines beginning with # are comments
+#
+# "disk_config <device>|first|end"
+#   The disk_config command starts the parsing.
+#   It has to be the first command.
+#    <device> is the harddisk to format in short form like "hda" or "sdc".
+#    if first is used, the first of $ENV{disklist} is used
+#    "end"    = end parsing here
+#   Example: "disk_config hdb"
+#   Example: "disk_config first"
+#
+# Defining one partition:
+# "primary|logical mountpoint|swap|- <size in mb>|preserve<No> [fstab-options][;extraordinary options]"
+#    "primary|logical":
+#      "primary": this are the bootable partitions like the
+#         root directory "/" or the DOS "C:" disk.
+#      "logical": this are all other partitions like a linux
+#         "/var" or a swap partition or a DOS disk.
+#
+#    "mountpoint|swap|-":
+#      "mountpoint": 
+#         This is the mount-point for fstab.
+#         For example "/","/var","/usr". There must not
+#         be a space in the mountpoint.
+#      "swap":
+#         swap-partitions
+#      "-":
+#         do not mount this partition.
+#
+#    "<size in mb>|preserve<No>":
+#      "<size in mb>":
+#        The size of the partition in megabyte
+#         Examples:
+#          "30"     = 30 mb
+#          "10-100" = 10 to 100 mb
+#          "20-"    = minimum of 20 mb
+#          "-500"   = 1 to 500 mb
+#          The megabytes will be rounded up to cylinders.
+#      "preserve<No>":
+#         This is the alternative for the size attribute.
+#         <No> is the partition number. For example
+#         preserve3 for the third partition. If the
+#         <device> was hda then this results in hda3.
+#         The partition will be left unchanged. This
+#         is useful if you have partitions that do not
+#         need re-installation or if you want to have
+#         other operation systems on the device together
+#         with Linux. Extended Partitions can not be preserved.
+#         The bootable flag will not be preserved.
+#         Preserved partitions are mounted readonly during
+#         installation.
+#
+#    "fstab-options":
+#         These options are copied to the fstab-file. The
+#         default is "default"
+#
+#   After the semicolon there could be extra options like:
+#     -i <bytes>   : Bytes per inodes
+#                    (only ext2/3 filesystem)
+#     -m <blocks>% : reserved blocks percentage for superuser
+#                    (only ext2/3 filesystem)
+#     -j          : format in ext3
+#     -c           : check for bad blocks
+#     format       : Always format this partition even if preserve
+#     lazyformat   : Do not format if partition has not moved
+#                    (useful for testing the installation)
+#     boot         : make this partition the boot-partition (the
+#                    linux root filesystem is the default)
+#     ext2         : Extended 2 filesystem (this is the default)
+#     swap         : swap partition
+#     dosfat16     : DOS 16bit FAT file system
+#     winfat32     : Win95 FAT32 file system
+#     writable     : mounts a preserved partition writable
+#     xfs          : xfs
+#     reiser       : reiserfs
+#       -h <hash>  : set reiserfs hash
+#       -v <ver>   : set reiserfs version
+#
+use strict;
+# getopts variables:
+our ($opt_X, $opt_f, $opt_c, $opt_d);
+my $test;
+
+$| = 1;                     # flush always
+
+#****************************************************
+# Variables
+#****************************************************
+
+my $Version = "version 0.35fai";
+
+my $megabyte = 1024 * 1024;    # guess
+# $gigabyte = 1024 * $megabyte;
+my $sectorsize = 512;
+
+# used programs
+my $sfdisk_options = "-q $ENV{sfdisk}";     # be quiet
+my $mke2fs_options = "-q";     # be quiet
+my $mkreiserfs_options = "";
+my $mkxfs_options = "-f";
+my $mkswap_options = "";
+
+# FAI input variables
+my $ClassPath = "$ENV{FAI}/disk_config";# this directory contains the classes
+my $ConfigFileName = "";   # alternative classfile, only for tests
+my $DOS_Alignment = "";    # align partitions for tracks
+
+# FAI output variables
+my $BootPartition = "";    # the boot partition like "hda1"
+my $BOOT_DEVICE = "";      # the root device like "hda" or "sdb"
+my $FAIOutputFile = $ENV{diskvar}; # write output variables to this file
+
+# old partition tables
+my %DiskUnits = ();        # unit size of each disk in sectors
+my %DiskSize = ();         # size of every disk in units
+my %SectorsAlignment = ();  # tracksize in sectors
+my %PartOldBoot = ();      # partition was bootable. "yes"=yes
+my %PartOldStart = ();     # old startunit of partition
+my %PartOldEnd = ();       # old endunit of partition
+my %PartOldStartSec = ();  # old startsector of partition
+my %PartOldEndSec = ();    # old endsector of partition
+my %PartOldID = ();        # old ID of partition
+my %OldNotAligned = (); # "yes" if old partition boundaries are not DOS aligned
+
+# mountpoints  ("/<path>" or "swap<No>" or "no<No>" or "extended<disk>")
+my $NofSwapPart = 0;       # number of swap partitions
+my $NofNotMoPart = 0;      # number of not mountet partitions
+my %DiskMountpoints = ();  # mountpoints of every disk. separated by spaces
+my %MountpointPart = ();   # partition of every mountpoint. e.g. "hda2"
+my %PartMountpoint = ();   # mountpoint of every partition.
+my @swaplist;              # list of all swpa devices
+
+# size of partition/mountpoint
+my %MPMinSize = ();        # minimum size of mountpoint in units
+my %MPMaxSize = ();        # maximum size of mountpoint in units
+my %MPPreserve = ();       # preserve partition: "yes"=yes
+my %MPPrimary = ();        # primary partition: "yes"=yes
+my %MPStart = ();          # start of partition in units
+my %MPSize = ();           # size of partition in units
+my %MPID = ();             # id of partition
+
+# options
+my %MPfstaboptions = ();   # fstab options for every mountpoint
+my %MPOptions = ();        # extra options for every mountpoint
+
+# sfdisk partition tables
+my %sfdiskTables = ();     # partition tables for sfdisk
+
+my $verbose = 0;
+$verbose = $ENV{verbose} if $ENV{verbose};
+
+# Parse command line
+
+use Getopt::Std;
+&getopts('Xf:c:d') || die "
+USAGE: [-X]                     no test, your harddisks will be formated
+                                default: only test, no real formating
+       [-f<config-filename>]    default: parse classes
+       [-c<class-path>]         default: \$FAI/disk_config/
+       [-d]                     default: no DOS alignment
+";
+
+print "setup_harddisks $Version\n";
+if (defined $opt_X){
+    $test = 2;
+} else {
+    print "TEST ONLY - no real formating\n\n";
+    $test = 1;
+}
+$ConfigFileName = $opt_f if $opt_f;# alternative config file
+$ClassPath      = $opt_c if $opt_c;# search classes here
+$DOS_Alignment  = "yes" if $opt_d; # track alignment
+
+# main part
+&GetAllDisks;
+&ParseAllConfigFiles;
+&BuildNewPartTables;
+&PartitionPersfdisk;
+&FormatDisks;
+&WriteFSTab;
+&WriteFAIVariables;
+exit 0;
+#****************************************************
+
+#****************************************************
+# get a partition pathname
+#****************************************************
+sub PartName {
+    my ($disk, $partno) = @_;
+    my $ppath;
+    for ($disk) {
+       /^[a-z]+$/ and $ppath = "${disk}${partno}";
+       /\d$/ and $ppath = "${disk}p${partno}";
+    }
+    return $ppath;
+}
+
+#****************************************************
+# Read all partition tables of this machine
+#****************************************************
+sub GetAllDisks{
+    my $line=""; my $disk=""; my $device=""; my $rest; my $result; my $divi;
+    my $devdisklist="";
+
+    foreach my $device(split(/\s/,$ENV{disklist})){
+      $devdisklist = "$devdisklist /dev/$device";
+    }
+    print "Probing disks: $devdisklist\n";
+    print "Disks found:";
+    $result = `sh -c "LC_ALL=C sfdisk -g -q $devdisklist"`;
+    foreach my $line(split(/\n/,$result)){
+       if($line =~ m'^/dev/(.+?):\s+(\d+)\s+cylinders,\s+(\d+)\s+heads,\s+(\d+)\s+sectors'i){
+           $disk = $1;
+           $DiskUnits{$disk} = $3 * $4;# heads * sectors = cylinder size in sectors
+           $DiskSize{$disk} = $2;      # cylinders
+           ($DOS_Alignment eq "yes") ? ($SectorsAlignment{$disk} = $4) : ($SectorsAlignment{$disk} = 1);
+           print " $disk";
+       }
+    }
+    $result = `sh -c "LC_ALL=C sfdisk -d -q $devdisklist"`;
+    foreach my $line(split(/\n/,$result)){
+#      if($line =~ m'# partition table of /dev/(cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|[a-z]+)'i){
+# now just match all devices
+       if($line =~ m'# partition table of /dev/(\S+)$'i){
+          $disk = $1;
+        }
+       if($line =~ m#^/dev/(.+?)\s*:\s+start=\s*(\d+),\s+size=\s*(\d+),\s+Id=\s*([a-z0-9]+)\b(.*)$#i){
+           $device = $1;
+            # Sectors
+            $PartOldStartSec{$device} = $2;
+            $PartOldEndSec{$device} = $2 + $3 - 1;
+            # DiskUnits
+           $PartOldStart{$device} = int ($2 / $DiskUnits{$disk});
+           $PartOldEnd{$device} = int (($2 + $3 - 1) / $DiskUnits{$disk});
+           $divi = $2 / $SectorsAlignment{$disk};
+           ($divi != int ($divi)) && ($OldNotAligned{$device} = "yes");
+           $divi = $3 / $SectorsAlignment{$disk};
+           ($divi != int ($divi)) && ($OldNotAligned{$device} = "yes");
+           $PartOldID{$device} = $4;
+           $rest = $5;
+           $PartOldBoot{$device} = ($rest =~ /bootable/) ? "yes" : "";
+       }
+    }
+    print "\n\n";
+}
+
+#****************************************************
+# parse config file or all class files
+#****************************************************
+sub ParseAllConfigFiles{
+    my $ConfigFileExists = 0;  # no config file parsed yet
+    if ($ConfigFileName){
+       # Read config filename
+       &ParseConfigFile($ConfigFileName);
+       $ConfigFileExists = 1;
+    } else {
+       # Read classes
+       foreach my $classfile (reverse split(/\s+/,$ENV{"classes"})){
+           my $filename = "$ClassPath/$classfile";
+           if (($classfile) && (-r $filename)) {
+               &ParseConfigFile($filename);
+               $ConfigFileExists = 1;
+            }
+           ($ConfigFileExists) && last;
+       }
+    }
+    ($ConfigFileExists == 0) && die "ERROR: no config file for setup_harddisk found. Please check you classes and files in disk_config.\n";
+}
+
+#****************************************************
+# map "disk_config first" to real disk device
+#****************************************************
+sub mapdisk {
+
+  my ($disk) = @_;
+  my @dlist = split /\s+/,$ENV{disklist};
+
+  if ($disk eq "disk1") {
+    print "Mapping disk name disk1 to $dlist[0]\n";
+    $disk = $dlist[0];
+  }
+  if ($disk eq "disk2") {
+    print "Mapping disk name disk2 to $dlist[1]\n";
+    $disk = $dlist[1];
+  }
+  return $disk;
+}
+
+#****************************************************
+# parse config-file
+#****************************************************
+sub ParseConfigFile{
+    my $size=""; my $mountpoint=""; my $device ="";
+    my $fstaboptions=""; my $options=""; my $disk=""; my $command = "";
+    my $LogPartNo; my $PrimPartNo; my $NoMoreLogicals;
+    my $LastPresPart; my $extmp; my $Min; my $Max;
+    my $filename = shift;
+    open (FILE,"$filename")
+      || die "config file not found: $filename\n";
+    (print "Using config file: $filename\n");
+    $disk = "";
+    my $a = 1, my $paras ="", my $number=0;
+    while (my $line = <FILE>){
+       chomp($line);
+       $a++;
+       next if( $line =~ /^#|^\s*$/ );
+
+       # disk_config - command
+       if ($line =~ /^disk_config(.*)/i){
+           $paras = $1;
+           if ($paras =~ / end/i){
+               $disk = "";
+           } else {
+#              if($paras =~ m# (/dev/)?(cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|[a-z]+)#i){
+# now match all devives
+               if($paras =~ m# (/dev/)?(\S+)#i){
+                   $disk = mapdisk($2);
+                   ($DiskMountpoints{$disk})
+                     && die "ERROR: there are more than one configuration of disk $disk.\n";
+                   ($DiskSize{$disk}) || die "ERROR: could not read device /dev/$disk\n";
+                   ($test != 1) || (print "config: $disk\n");
+                   $DiskMountpoints{$disk} = "";
+                   $MPPrimary{"extended$disk"} = "";
+                   $LogPartNo = 4;
+                   $PrimPartNo = 0;
+                   $NoMoreLogicals = 0;
+                   $LastPresPart = "";
+                   $extmp = "extended$disk";
+               } else {
+                   die "SYNTAX ERROR: in config file line $a, unknown disk_config parameter $paras\n$line\n";
+               }
+           }
+       }
+
+       if ($disk){
+           # primary|partition - command
+           if($line =~ /^\s*(primary|logical)\s+(.*)$/i){
+               $command = $1;
+               # split variables
+               $paras = $2;
+               $options = "";
+               if($paras =~ /(.*?)\s*;\s*(.*)$/){
+                   $paras = $1;
+                   $options = $2;
+               }
+               $size="";
+               $mountpoint ="";
+               $fstaboptions = "";
+               ($mountpoint,$size,$fstaboptions)=split(/\s+/,$paras);
+               # mountpoint
+               ($mountpoint =~ m#^/.*|^swap$|^-$#i)
+                 || die "SYNTAX ERROR in config file line $a, mountpoint: $mountpoint\n$line\n";
+               ($MountpointPart{$mountpoint})
+                 && die "SYNTAX ERROR in config file line $a. Mountpoint $mountpoint redefined.\n$line\n";
+               if($mountpoint eq "/"){
+                   ($BootPartition) || ($BOOT_DEVICE = $disk);
+               }
+               if($mountpoint eq "-"){
+                   $NofNotMoPart++;
+                   $mountpoint = "no$NofNotMoPart";
+               }
+               if($mountpoint eq "swap"){
+                   $NofSwapPart++;
+                   $mountpoint = "swap$NofSwapPart";
+                   ($options !~ /\bswap\b/i) && ($options .= " swap");
+                   ($fstaboptions) || ($fstaboptions = "sw");
+               }
+               if($mountpoint =~ m#^/#){
+                   ($fstaboptions) || ($fstaboptions = "defaults");
+               }
+               if ($command eq "primary") {
+                   ($MPPrimary{$extmp} eq "yes") && ($NoMoreLogicals = 1);
+                   $MPPrimary{$mountpoint} = "yes";
+                   $PrimPartNo++;
+#                  ($PrimPartNo == 3) && ($disk =~ /^sd/) && ($PrimPartNo++);
+                    ($PrimPartNo >4 ) && die "ERROR: Too much primary partitions (max 4).".
+                                " All logicals together need one primary too.\n";
+                   $MountpointPart{$mountpoint} = PartName($disk,$PrimPartNo);
+                   if($options =~ /\bboot\b/i){
+                       ($BootPartition) && die "ERROR: only one partition can be bootable at a time.";
+                       $BootPartition = $MountpointPart{$mountpoint};
+                       $BOOT_DEVICE = $disk;
+                   }
+               } else {
+                   ($NoMoreLogicals != 0) && die "ERROR: the logical partitions must be together.\n";
+                   $MPPrimary{$mountpoint} = "";
+                   $LogPartNo++;
+                   $MountpointPart{$mountpoint} = PartName($disk,$LogPartNo);
+                   if (!$MPPrimary{$extmp}){
+                       $MPPreserve{$extmp} = "";
+                       $MPPrimary{$extmp} = "yes";
+                       $MPMinSize{$extmp} = 0;
+                       $MPMaxSize{$extmp} = 0;
+                       $MPID{$extmp} = 5;
+                       $PrimPartNo++;
+                       ($PrimPartNo == 3) && ($disk =~ /^sd/) && ($PrimPartNo++);
+                        ($PrimPartNo >4 ) 
+                         && die "ERROR: too much primary partitions (max 4).".
+                               " All logicals together need one primary too.\n";
+                       $MountpointPart{$extmp} = PartName($disk,$PrimPartNo);
+                       $DiskMountpoints{$disk} .= " $extmp";
+                   }
+#                  ($options =~ /\bboot\b/i) && die "ERROR: line $a, only primary partitions can be bootable.\n";
+               }
+               $DiskMountpoints{$disk} .= " $mountpoint";
+               # size
+               ($size =~ /^preserve\d+$|^\d+\-?\d*$|^-\d+$/i)
+                   || die "SYNTAX ERROR in config file line $a, size: $size\n$line\n";
+               if($size =~ /^preserve(\d+)$/i){
+                   my $number = $1;
+                   $device = PartName($disk,$number);
+                   ($OldNotAligned{$device} eq "yes")
+                     && die "ERROR: unable to preserve partition /dev/$device. Partition is not DOS aligned.";
+                   ($command eq "primary") && ($number != $PrimPartNo)
+                       && die "NUMERATION ERROR in line $a, the number of the partition can not be preserved:\n$line\n";
+                   ($command eq "logical") && ($number != $LogPartNo)
+                       && die "NUMERATION ERROR in line $a, the number of the partition can not be preserved:\n$line\n";
+                   if ($PartOldEnd{$device}){
+                       (($PartOldID{$device} == 5) || ($PartOldID{$device} == 85)) &&
+                         die "ERROR in config file line $a.".
+                              " Extended partitions can not be preserved. /dev/$device\n$line\n";
+                       $MPPreserve{$mountpoint}="yes";
+                       $MPMinSize{$mountpoint} = $PartOldEnd{$device}-$PartOldStart{$device}+1;
+                       $MPMaxSize{$mountpoint} = $MPMinSize{$mountpoint}; # Max=Min
+                       $MPStart{$mountpoint} = $PartOldStart{$device};
+                       $MPSize{$mountpoint} = $MPMinSize{$mountpoint};
+                       $MPID{$mountpoint} = $PartOldID{$device};
+                   } else {
+                       die "ERROR: cannot preserve partition $device. partition not found.$PartOldEnd{$device}\n";
+                   }
+                   if ($LastPresPart) {
+                       ($PartOldStart{$device} < $PartOldStart{$LastPresPart}) &&
+                         die "ERROR: misordered partitions: cannot preserve partitions $LastPresPart and $device\n".
+                              "       in this order because of their positions on disk.";
+                   }
+                   $LastPresPart = $device;
+                   ($MPMinSize{$mountpoint} < 1)
+                     && die "ERROR: unable to preserve partitions of size 0.\n$line\n ";
+                 } else {
+                   # If not preserve we must know the filesystemtype
+                   ($options !~ /\b(ext2|ext3|auto|swap|dosfat16|winfat32|reiser|xfs)\b/i ) && ($options .= " auto");
+                 }
+               if($size =~ /^(\d*)(\-?)(\d*)$/){
+                   $Min = $1;
+                   $Min||= 1;
+                   $Max = $3;
+                   $MPMinSize{$mountpoint} = int (($Min * $megabyte - 1) / ($DiskUnits{$disk} * $sectorsize)) + 1;
+                   if ($2 eq "-"){
+                       if($Max =~ /\d+/){
+                           $MPMaxSize{$mountpoint} = int (($Max * $megabyte - 1) / ($DiskUnits{$disk} * $sectorsize)) + 1;
+                       } else {
+                           $MPMaxSize{$mountpoint} = $DiskSize{$disk};
+                       }
+                   } else {
+                       $MPMaxSize{$mountpoint} = $MPMinSize{$mountpoint}; # Max=Min
+                   }
+                   ($MPMinSize{$mountpoint} > $DiskSize{$disk})
+                     && die "ERROR in config file line $a: Minsize larger than disk.\n$line\n";
+                   ($MPMinSize{$mountpoint} > $MPMaxSize{$mountpoint}) 
+                       && die "SYNTAX ERROR in config file line $a, MIN-MAX-size: $MPMinSize{$mountpoint}-$MPMaxSize{$mountpoint}\n$line\n";
+                   ($MPMinSize{$mountpoint} < 1)
+                     && die "SYNTAX ERROR in config file line $a. Minsize must be greater than 1.\n$line\n";
+                   $MPPreserve{$mountpoint} = "";
+               }
+               # fstaboptions
+               $MPfstaboptions{$mountpoint} = $fstaboptions;
+               # extra options
+               ($options =~ /\b(ext[23]|auto)\b/i) && ($MPID{$mountpoint} = 83); # Linux native
+               ($options =~ /\bswap\b/i) && ($MPID{$mountpoint} = 82); # Linux swap
+               ($options =~ /\bdosfat16\b/i) && ($MPID{$mountpoint} = 6); # DOS FAT 16bit (>=32MB, will be changed later)
+               ($options =~ /\bwinfat32\b/i) && ($MPID{$mountpoint} = "b"); # Win 95 FAT 32
+               $MPOptions{$mountpoint} = $options;
+               if($test == 1){
+                   print "$mountpoint,$MPMinSize{$mountpoint}-$MPMaxSize{$mountpoint},";
+                   print "$fstaboptions,$options";
+                   ($MPPreserve{$mountpoint} eq "yes") && (print " Preserve: $MountpointPart{$mountpoint}");
+                   print "\n";
+               }
+           }
+       }
+    }
+    close(FILE);
+}
+
+#****************************************************
+# Build all partition tables
+#****************************************************
+sub BuildNewPartTables{
+    my ($disk, $mountpoint, $part, $PrimaryMP, $LogicalMP);
+    ($test != 1) || (print "\nBuilding partition tables:\n");
+    # Build PartMountpoint array
+    foreach $disk(keys %DiskMountpoints) {
+       $DiskMountpoints{$disk} =~ s/\s(\s)/$1/g;
+       $DiskMountpoints{$disk} =~ s/^\s//;
+       $DiskMountpoints{$disk} =~ s/\s$//;
+       foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
+           $PartMountpoint{$MountpointPart{$mountpoint}} = $mountpoint;
+       }
+    }
+    foreach $disk(keys %DiskMountpoints) {
+       &SetPartitionPositions($disk);
+        # change units to sectors
+        foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
+            if($MPPreserve{$mountpoint} eq "yes"){
+               $MPStart{$mountpoint} = $PartOldStartSec{$MountpointPart{$mountpoint}};
+               $MPSize{$mountpoint} = $PartOldEndSec{$MountpointPart{$mountpoint}} - $MPStart{$mountpoint} + 1;
+           } else {
+               $MPStart{$mountpoint} *= $DiskUnits{$disk};
+               $MPSize{$mountpoint} *= $DiskUnits{$disk};
+               # align first partition for mbr
+               if($MPStart{$mountpoint} == 0){
+                   $MPStart{$mountpoint} += $SectorsAlignment{$disk};
+                   $MPSize{$mountpoint} -= $SectorsAlignment{$disk};
+               }
+           }
+       }
+       # align all logical partitions
+        foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
+            next if ($MPPrimary{$mountpoint} eq "yes");
+           if ($MountpointPart{$mountpoint} eq "${disk}5") {
+               # partition with number 5 is first logical partition and start of extended partition
+               $MPStart{"extended$disk"} = $MPStart{$mountpoint};
+                ($MPPreserve{$mountpoint} eq "yes") && ($MPStart{"extended$disk"} -= $SectorsAlignment{$disk});
+           }
+            if ($MPPreserve{$mountpoint} ne "yes") {
+               $MPStart{$mountpoint} += $SectorsAlignment{$disk};
+               $MPSize{$mountpoint} -= $SectorsAlignment{$disk};
+           }
+       }
+        &CalculateExtPartSize($disk);
+        # sort mountpoints of partition number
+        $PrimaryMP = "";
+        $LogicalMP = "";
+        foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
+         ($MPPrimary{$mountpoint} eq "yes") ? ($PrimaryMP .= " $mountpoint") : ($LogicalMP .= " $mountpoint");
+       }
+       $DiskMountpoints{$disk} = "$PrimaryMP$LogicalMP";
+       $DiskMountpoints{$disk} =~ s/^\s//;
+       # print partition table
+        ($test != 1) || (PrintPartitionTable($disk));
+    }
+    if (!$BootPartition){
+        $BootPartition = $MountpointPart{"/"};
+    }
+}
+
+#****************************************************
+# set position for every partition
+#****************************************************
+sub SetPartitionPositions{
+    my $disk = shift;
+    my $mountpoint; my $DynGroup =""; my $StartPos; my $EndPos;
+    # Build groups of unpreserved partitions between
+    # preserved partitions
+    $StartPos = 0;
+    foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
+        if ($MPPreserve{$mountpoint} eq "yes") {
+           $EndPos = $PartOldStart{$MountpointPart{$mountpoint}} - 1;
+            &SetGroupPos($DynGroup,$StartPos,$EndPos);
+           $DynGroup = "";
+           $StartPos = $PartOldEnd{$MountpointPart{$mountpoint}} + 1;
+        } else {
+           $DynGroup .= " $mountpoint";
+       }
+    }
+    $EndPos = $DiskSize{$disk} - 1;
+    &SetGroupPos($DynGroup,$StartPos,$EndPos);
+    foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
+       ($MPOptions{$mountpoint} =~ /\bdosfat16\b/i)
+           && (($MPSize{$mountpoint} * $DiskUnits{$disk} * $sectorsize) < 32 * $megabyte)
+               && ($MPID{$mountpoint} = 4); # DOS 16-bit FAT <32MB
+    }
+}
+
+#****************************************************
+# set position for a group of unpreserved partitions
+# between start and end
+#****************************************************
+sub SetGroupPos{
+    my ($PartGroup,$Start,$End) = @_;
+    $PartGroup =~ s/^ //;
+    ($PartGroup) || return;
+    my $totalsize = $End - $Start + 1;
+    ($totalsize <= 0) && return;
+    my $mountpoint; my $mintotal = 0; my $maxmintotal = 0; my $rest = 0; my $EndUnit = 0;
+    # compute total of MinSizes and difference to MaxSizes
+    foreach $mountpoint (split(/\s/,$PartGroup)) {
+        $mintotal += $MPMinSize{$mountpoint};
+        $maxmintotal += ($MPMaxSize{$mountpoint} - $MPMinSize{$mountpoint});
+        $MPSize{$mountpoint} = $MPMinSize{$mountpoint};
+    }
+    # Test if partitions fit
+    ($mintotal > $totalsize)
+      && die "ERROR: Mountpoints $PartGroup do not fit.\n";
+    # Maximize partitions
+    $rest = $totalsize - $mintotal;
+    ($rest > $maxmintotal) && ($rest = $maxmintotal);
+    if ($rest > 0) {
+        foreach $mountpoint (split(/\s/,$PartGroup)) {
+            $MPSize{$mountpoint} += int ((($MPMaxSize{$mountpoint} - $MPMinSize{$mountpoint}) * $rest) / $maxmintotal);
+        }
+    }
+    # compute rest
+    $rest = $totalsize;
+    foreach $mountpoint (split(/\s/,$PartGroup)) {
+        $rest -= $MPSize{$mountpoint};
+    }
+    # Minimize rest
+    foreach $mountpoint (split(/\s/,$PartGroup)) {
+        if (($rest >0) && ($MPSize{$mountpoint} < $MPMaxSize{$mountpoint})){
+            $MPSize{$mountpoint}++;
+           $rest--;
+       }
+    }
+    # Set start for every partition
+    foreach $mountpoint (split(/\s/,$PartGroup)) {
+        $MPStart{$mountpoint} = $Start;
+       $Start += $MPSize{$mountpoint};
+       $EndUnit = $MPStart{$mountpoint} + $MPSize{$mountpoint} - 1;
+    }
+}
+
+#****************************************************
+# calculate extended partition size
+#****************************************************
+sub CalculateExtPartSize{
+    my ($disk) = @_;
+    my $extmp = "extended$disk";
+    my $mountpoint; my $ExtEnd; my $NewEnd;
+    ($MPPrimary{$extmp}) || return;
+    $ExtEnd = $MPStart{$extmp};
+    foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
+        next if ($MPPrimary{$mountpoint} eq "yes");
+       $NewEnd = $MPStart{$mountpoint} + $MPSize{$mountpoint} - 1;
+       ($NewEnd > $ExtEnd) && ($ExtEnd = $NewEnd);
+    }
+    $MPSize{$extmp} = ($ExtEnd - $MPStart{$extmp} + 1);
+}
+
+#****************************************************
+# Print partition "number - mountpoint" table
+#****************************************************
+sub PrintPartitionTable{
+    my ($disk) = @_;
+    my $part; my $mountpoint; my $mountpointname; my $end;
+    foreach $part (sort %MountpointPart) {
+        next if($part !~ /^$disk/);
+       $mountpoint = $PartMountpoint{$part};
+        if ($mountpoint =~ /^no(.*)/){
+            $mountpointname = "no mountpoint ($1)";
+       } else {
+           $mountpointname = $mountpoint;
+       }
+       $end = $MPStart{$mountpoint} + $MPSize{$mountpoint} - 1;
+       print <<"EOM";
+/dev/$part $mountpointname start=$MPStart{$mountpoint} size=$MPSize{$mountpoint} end=$end id=$MPID{$mountpoint}
+EOM
+      }
+}
+
+#****************************************************
+# build all partition tables for sfdisk
+#****************************************************
+sub PartitionPersfdisk{
+    my ($disk, $mountpoint, $line, $part, $PrimaryNo);
+    my ($command, $result, $filename, $number);
+    print "Creating partition table: ";
+    foreach $disk(keys %DiskMountpoints) {
+        $sfdiskTables{$disk} = "# partition table of device: /dev/$disk\nunit: sectors\n\n";
+       $PrimaryNo = 1;
+        foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
+           $part = $MountpointPart{$mountpoint};
+           $part =~ /(\d+)$/;
+           ($1 < 5) && ($PrimaryNo++);
+           if ( ($1 == 5) && ($PrimaryNo < 5) ){
+               for my $number($PrimaryNo..4) {
+                   $sfdiskTables{$disk} .= BuildsfdiskDumpLine(PartName($disk,$number),0,0,0)."\n";
+               }
+           }
+           $line = BuildsfdiskDumpLine($MountpointPart{$mountpoint},$MPStart{$mountpoint},$MPSize{$mountpoint},$MPID{$mountpoint});
+            ($part eq $BootPartition) && ($line .= ", bootable");
+            $sfdiskTables{$disk} .= "$line\n";
+       }
+#      print $sfdiskTables{$disk};
+       $filename = "$ENV{LOGDIR}/partition." . (($disk=~ m#/#) ? join('_', split('/', $disk)) : $disk);
+       if(($test != 1) && ($filename)){
+           open(FILE, ">$filename") || die "unable to write temporary file $filename\n";
+           print FILE $sfdiskTables{$disk};
+           close(FILE);
+        }
+       $command = "LC_ALL=C sfdisk $sfdisk_options /dev/$disk < $filename";
+       if($test != 1){
+            print "$command\n";
+           $result = `sh -c "$command"`;
+           (($? >> 8) == 0) || (die "\nSFDISK ERROR:\n $result\n");
+       }
+    }
+}
+
+#****************************************************
+# build a sfdisk dump line
+#****************************************************
+sub BuildsfdiskDumpLine{
+
+  sprintf "/dev/%-5s: start=%10s, size=%10s, Id=%3s",@_;
+}
+
+#****************************************************
+# Format all disks
+#****************************************************
+sub FormatDisks{
+    my ($disk, $device, $mountpoint, $mountpointname, $command, $result);
+    print "Creating file systems:\n";
+    foreach $disk(keys %DiskMountpoints) {
+        foreach $mountpoint (split(/\s/,$DiskMountpoints{$disk})) {
+           $device = $MountpointPart{$mountpoint};
+            if ($mountpoint =~ /^no/){
+                $mountpointname = "no mountpoint";
+            } else {
+               $mountpointname = $mountpoint;
+           }
+           # preserved partition
+           if ( ($MPPreserve{$mountpoint} eq "yes") && ($MPOptions{$mountpoint} !~ /\bformat\b/i)){
+               print "Preserve partition $device";
+                if ($mountpoint =~ /^no$1/){
+                    print " with no mountpoint\n";
+                } else {
+                   print " with mountpoint $mountpoint\n";
+               }
+               next;
+           }
+           # lazy format
+           if ( ( $MPOptions{$mountpoint} =~ /\blazyformat\b/i )
+              && ($MPStart{$mountpoint} == $PartOldStartSec{$device})
+              && (($MPStart{$mountpoint} + $MPSize{$mountpoint} - 1) == $PartOldEndSec{$device}) ){
+               print "Lazy format: $device";
+                if ($mountpoint =~ /^no$1/){
+                    print " with no mountpoint";
+                } else {
+                   print " with mountpoint $mountpoint";
+               }
+                print " was neither moved nor formated.\n";
+               next;
+           }
+           # swap
+           if ($mountpoint =~ /^swap/i) {
+#              print "Make swap partition:\n";
+               $command = "mkswap $mkswap_options";
+               ($MPOptions{$mountpoint} =~ /(\-c)\b/i) && ($command .= " $1");
+               push @swaplist, "/dev/$device";
+               $command .= " /dev/$device";
+               print "  $command\n";
+               if($test != 1){
+                   $result = `$command`;
+                   (($? >> 8) == 0) || (die "\nMKSWAP ERROR:\n $result\n");
+               }
+               next;
+           }
+           # Linux Reiser file system
+           if ($MPOptions{$mountpoint} =~ /\breiser\b/i) {
+#              print "Make Reiser Filesystem:\n";
+               $command = "echo y | mkreiserfs $mkreiserfs_options";
+               ($MPOptions{$mountpoint} =~ /(\-h\s*\w+)\b/) && ($command .= " $1");
+               ($MPOptions{$mountpoint} =~ /(\-v\s*\d+)\b/) && ($command .= " $1");
+               $command .= " /dev/$device";
+               print "  $command\n";
+               if ($test != 1){
+                   $result = `$command`;
+                   (($? >> 8) == 0) || die "\nMKREISERFS ERROR:\n $result\n";
+               }
+               next;
+           }
+           # Linux XFS file system
+           if ($MPOptions{$mountpoint} =~ /\bxfs\b/i) {
+#              print "Make XFS Filesystem:\n";
+               $command = "mkfs.xfs $mkxfs_options";
+               $command .= " /dev/$device";
+               print "  $command\n";
+               if ($test != 1){
+                   $result = `$command`;
+                   (($? >> 8) == 0) || die "\nMKFS.XFS ERROR:\n $result\n";
+               }
+               next;
+           }
+           # Linux Extended 2 file system
+           if ($MPOptions{$mountpoint} =~ /\b(ext[23]|auto)\b/i) {
+#              print "Make Extended 2/3 Filesystem:\n";
+               $command = "mke2fs $mke2fs_options";
+               ($MPOptions{$mountpoint} =~ /(\-c)\b/i) && ($command .= " $1");
+               ($MPOptions{$mountpoint} =~ /(\-i\s*\d+)\b/) && ($command .= " $1");
+               ($MPOptions{$mountpoint} =~ /(\-m\s*\d+)\b/) && ($command .= " $1");
+               ($MPOptions{$mountpoint} =~ /(\-j)\b/) && ($command .= " $1");
+               $command .= " /dev/$device";
+               print "  $command\n";
+               if ($test != 1){
+                   $result = `$command`;
+                   (($? >> 8) == 0) || die "\nMKE2FS ERROR:\n $result\n";
+               }
+               next;
+           }
+           # DOS 16bit FAT / Win95 FAT 32
+           if ($MPOptions{$mountpoint} =~ /\b(dosfat16|winfat32)\b/i) {
+               print "Clear first sector for DOS/Windows\n";
+               $command = "dd if=/dev/zero of=/dev/$MountpointPart{$mountpoint} bs=512 count=1";
+               print "  $command\n";
+               if ($test != 1){
+                   $result = `$command`;
+                   (($? >> 8) == 0) || die "\nDD ERROR:\n $result\n";
+               }
+               next;
+           }
+        }
+    }
+}
+
+#****************************************************
+# Build fstab and write it to <root>/etc/fstab
+#****************************************************
+sub WriteFSTab{
+    my ($FileSystemTab, $device, $type, $filename);
+    $FileSystemTab  = << "EOM";
+# /etc/fstab: static file system information.
+#
+#<file sys>          <mount point>     <type>   <options>   <dump>   <pass>
+EOM
+    # 1. /
+    $type = "ext2";
+    ($MPOptions{'/'} =~ /\b(reiser)\b/i) && ($type = "reiserfs");
+    ($MPOptions{'/'} =~ /\b(xfs)\b/i) && ($type = "xfs");
+    ($MPOptions{'/'} =~ /\b(ext3)\b/i) && ($type = "ext3");
+    ($MPOptions{'/'} =~ /\b(ext2)\b/i) && ($type = "ext2");
+    $FileSystemTab .= BuildfstabLine("/dev/$MountpointPart{'/'}","/",$type,$MPfstaboptions{'/'},0,1);
+    # 2. swap partitions
+    foreach my $mountpoint (%PartMountpoint){
+       next if( $mountpoint !~ /^swap/i);
+       $FileSystemTab .= BuildfstabLine("/dev/$MountpointPart{$mountpoint}",
+                           "none","swap",$MPfstaboptions{$mountpoint},0,0);
+    }
+    # 3. /proc
+    $FileSystemTab .= BuildfstabLine("none","/proc","proc","defaults",0,0);
+    # 4. sorted others
+    foreach my $mountpoint (sort %PartMountpoint){
+       next if ( ($mountpoint !~ m#^/#) || ($mountpoint eq "/"));
+       $device = $MountpointPart{$mountpoint};
+       $type = "ext2";
+       ($MPOptions{$mountpoint} =~ /\b(dosfat16|winfat32)\b/i) && ($type = "vfat");
+       ($MPOptions{$mountpoint} =~ /\b(reiser)\b/i) && ($type = "reiserfs");
+       ($MPOptions{$mountpoint} =~ /\b(xfs)\b/i) && ($type = "xfs");
+       ($MPOptions{$mountpoint} =~ /\b(ext3)\b/i) && ($type = "ext3");
+       ($MPOptions{$mountpoint} =~ /\b(ext2)\b/i) && ($type = "ext2");
+       $FileSystemTab .= BuildfstabLine("/dev/$device",$mountpoint,$type,$MPfstaboptions{$mountpoint},0,2);
+    }
+    # write it
+    $filename = "$ENV{LOGDIR}/fstab";
+#    print $FileSystemTab;
+    print "Write fstab to $filename\n" if $verbose;
+    if($test != 1){
+       open(FILE, ">$filename") || die "unable to write fstab $filename\n";
+       print FILE $FileSystemTab;
+       close(FILE);
+    }
+}
+
+#****************************************************
+# Build fstab line
+#****************************************************
+sub BuildfstabLine{
+
+    sprintf "%-10s   %-15s   %-6s  %-8s  %-4s %-4s\n",@_;
+}
+
+#****************************************************
+# Write all FAI variables of this program to file
+#****************************************************
+sub WriteFAIVariables{
+
+  my $swaps;
+
+  print "Write FAI variables to file $FAIOutputFile\n" if $verbose;
+    return if ($test == 1);
+  $swaps = join ' ',@swaplist;
+    open(FILE, ">$FAIOutputFile") || die "Unable to write file $FAIOutputFile\n";
+    print FILE << "EOM";
+BOOT_DEVICE=/dev/$BOOT_DEVICE
+ROOT_PARTITION=/dev/$MountpointPart{'/'}
+BOOT_PARTITION=/dev/$BootPartition
+SWAPLIST="$swaps"
+EOM
+    close(FILE);
+}
diff --git a/gosa-core/contrib/fai/goto-fai/faimond b/gosa-core/contrib/fai/goto-fai/faimond
new file mode 100755 (executable)
index 0000000..3ebdd5d
--- /dev/null
@@ -0,0 +1,93 @@
+#!/usr/bin/perl
+
+# $Id: faimond,v 1.2 2004/06/27 11:18:55 lange Exp $
+#*********************************************************************
+#
+# faimond -- monitor daemon which collects client status info
+#
+# This script is part of FAI (Fully Automatic Installation)
+# (c) 2003-2004 by Thomas Lange, lange@informatik.uni-koeln.de
+# Universitaet zu Koeln
+#
+#*********************************************************************
+
+#use strict;
+use Socket;
+
+$| = 1;
+my $port = 4711;
+
+@tasklist = qw/confdir defclass defvar partition mountdisks extrbase updatebase instsoft configure finish/;
+
+%tasks = (
+confdir => [' ', "Beziehe System-Einstellungen"],
+defclass => [' ',"Definieren von Klassen"],
+defvar => [' ',"Definieren von Variablen"],
+partition => [' ',"Paritionieren der Festplatten"],
+mountdisks => [' ',"Einbinden der Dateisysteme"],
+extrbase => [' ',"Installieren des Basis-Systems"],
+updatebase => [' ',"Aktualisieren des Basis-Systems"],
+instsoft => [' ',"Installieren der Software"],
+configure => [' ',"Abschließende Konfiguration"],
+finish => [' ',"Abschließen der Installation"]
+);
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub server_init() {
+
+  my $proto = getprotobyname('tcp');
+  socket(SERVER, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
+  setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1) or die "setsock: $!";
+
+  my $paddr = sockaddr_in($port, INADDR_ANY);
+
+  bind(SERVER, $paddr) or die "bind: $!";
+  listen(SERVER, SOMAXCONN) or die "listen: $!";
+#  print "FAI monitoring daemon started on port $port\n";
+}
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub big_loop() {
+
+  # accept a connection, print message received and close
+  my ($client_addr,$inp);
+  while ($client_addr = accept(CLIENT, SERVER)) {
+    $inp = <CLIENT>;
+    close CLIENT;
+    ($host,$begend,$task,$ecode) = split /\s+/,$inp;
+    chomp $ecode;
+    $strecode = sprintf "%-3s",$ecode;
+    $sym = ($begend =~ /TASKEND/) ? "   \\Z2OK\\Zn" : "   ->";
+    $tasks{$task}[0] = $ecode ? " \\Z1E$strecode\\Zn" : $sym;
+    showtab();
+
+    # Stop if we've reached faiend
+    if ( $task =~ /faiend/ ){
+       system("dialog --timeout 60 --msgbox '\nDie Installation wurde abgeschlossen. Drücken Sie die Eingabetaste um das System neu zu starten.' 8 60");
+       break;
+    }
+  }
+}
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub showtab() {
+
+# nach taskbeg soll es blinken, bei taskend, X oder error code
+
+  my $pre = '--colors --title " Aktueller Installationsverlauf "';
+  my $s2 = " --infobox \"\n";
+  # show tabular %tasks
+
+  $str = "$pre $s2";
+  foreach (@tasklist) {
+    $x = sprintf "%5s  $tasks{$_}[1]\n", $tasks{$_}[0];
+    $str .= $x;
+  }
+
+  $str .=  "\" 14 50\n";
+#  print $str;
+  system("dialog $str");
+
+}
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+server_init;
+big_loop;
diff --git a/gosa-core/contrib/fai/goto-fai/get_fai_dir b/gosa-core/contrib/fai/goto-fai/get_fai_dir
new file mode 100755 (executable)
index 0000000..5f24697
--- /dev/null
@@ -0,0 +1,128 @@
+#!/bin/sh
+# FAI script for preparing LDAP objects. It calls ldap2fai to generate
+# the config space after everything is done.
+#
+# (C) 2005 Cajus Pollmeier <pollmeier@gonicus.de>
+echo 0 > /proc/sys/kernel/printk
+trap '' INT
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:$PATH
+LANG=C
+
+. /usr/lib/goto/goto-support.lib
+
+#dialog() {
+#      echo $*
+#}
+
+abort() {
+       setterm -cursor off
+       while true; do sleep 60; done
+}
+       
+# Try to figure out which interface is configured, in doubt
+# choose the first one.
+interfaces=$(ifconfig | awk '/^[a-z0-9]/ {print $1}' | grep -v "lo")
+for int in $interfaces; do
+       ip=$(v=`ifconfig $int | awk '/inet addr/ {print $2}'`; echo ${v##*:})
+       mac=$(ifconfig $int | awk '/HWaddr/ {print $5}')
+       [ -n "$ip" ] && break
+done
+
+# Cancel if there's no IP available
+if [ -z "$ip" ]; then
+       dialog --title 'Fehler' --no-shadow --infobox 'Fehler: Das System konnte keine Netzwerk-Adresse ermitteln.\n\nDie Installation kann ohne diese Adresse nicht fortgesetzt werden.' 5 60
+       abort
+fi
+
+# Check if DNS setup is correct and set the hostname
+hostname=$(get_hostname_from_ip $ip)
+if [ "$hostname" == "unknown" ]; then
+       dialog --title 'Fehler' --no-shadow --infobox 'Fehler: Das System konnte keinen Rechner-Namen ermitteln.\n\nDie Installation kann ohne diese Information nicht fortgesetzt werden.' 5 60
+       abort
+fi
+
+echo "* setting hostname: $hostname"
+hostname "$hostname"
+mount -t tmpfs tmpfs /etc/ldap
+
+
+# Look for interesting parameters on kernel commandline
+ldap=""; splash=""
+for v in $(cat /proc/cmdline); do
+   case $v in
+      ldap=*)
+                echo -n "* found LDAP information, adapting configuration: "
+                ldap=$(echo ${v##ldap=}|base64-decode)
+
+               # ldap://hostname:389/basedn
+               LDAP_HOST=$(echo $ldap|sed 's!^[^:][^:]*://\([^:/][^:/]*\).*$!\1!g')
+               LDAP_PORT=$(echo $ldap|sed 's!^[^:]*://[^:][^:]*:\([0-9]*\)/.*$!\1!g')
+               echo -n $ldap_port | grep -q '^[0-9]*$' || LDAP_PORT=389
+               LDAP_BASE=$(echo $ldap|sed 's!^[^:][^:]*://[^/][^/]*/\(.*\)$!\1!g')
+               echo -e "BASE   $LDAP_BASE\nURI     ldap://$LDAP_HOST:$LDAP_PORT\n" > /etc/ldap/ldap.conf
+                echo "ok"
+                ;;
+      splash=*)
+                echo -n "* setting splash mode: "
+                splash=$(echo ${v##splash=})
+                [ $splash == "silent" ] && echo "silent" || echo "normal"
+                ;;
+    esac
+done
+
+[ -z "$ldap" ] && exit 0
+
+# Check if autosetup is needed at this point
+echo -n "* configurator: "
+if ! terminal_has_hardware_profile $mac; then
+    setterm -cursor off
+    echo "not configured yet - please wait, detecting hardware"
+
+    # Switch from bootsplash to normal screen, show dialog
+    [ -f /proc/splash ] && echo "verbose" > /proc/splash
+
+    setterm -blank 60
+    chvt 1
+    dialog --infobox 'Bitte warten, die installierte Hardware wird untersucht...' 3 64
+
+    # Get common config
+    hwsetup
+    terminal_alsa_setup
+    terminal_autofs_setup
+
+    # Save hardware profile
+    terminal_save_hardware_profile $mac
+fi
+
+if ! terminal_activated $mac; then
+    # wait till we get activated
+    setterm -blank 60
+    chvt 1
+    dialog --infobox 'Warte auf Aktivierung durch den Systemadministrator.' 3 60
+
+    while ! terminal_activated $mac; do
+                sleep 2
+    done
+
+    # GOsa writes the GOto entry in three steps. To continue, we check
+    # if XDRIVER is present.
+    dialog --infobox 'System wurde aktiviert. Eintr�e werden nun bernommen.' 3 60
+    while ! terminal_load_hardware_profile $mac &> /dev/null; do
+       cat /etc/sysconfig/GOto | grep -v 'XDRIVER="unknown"' | grep -q 'XDRIVER'
+       sleep 2
+    done
+
+    # Enable splash if it was enabled before
+    [ -f /proc/splash ] && echo "silent" > /proc/splash
+
+    echo -n "* configurator (pass2): "
+    setterm -cursor on
+fi
+
+# Mount configuration space
+[ ! -d /tmp/goto-fai ] && mkdir /tmp/goto-fai
+mount -obind /tmp/goto-fai /fai
+ldap2fai $mac
+
+chvt 3
+exit 0
diff --git a/gosa-core/contrib/fai/goto-fai/goto-support.lib b/gosa-core/contrib/fai/goto-fai/goto-support.lib
new file mode 100644 (file)
index 0000000..c6bdbba
--- /dev/null
@@ -0,0 +1,510 @@
+#!/bin/sh
+###############################################################################
+#                             GOsa agent library                              #
+###############################################################################
+
+SSH='ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile /dev/null" -o "BatchMode yes" '
+
+get_hostname_from_ip() {
+       v=$(host -i $1); w=${v##*[      ]}
+       echo ${w%%.*} | grep -q 'NX'
+       if [ $? -eq 0  ]; then
+               echo "unknown"
+       else
+               echo "$v" | grep -q ';;'
+               if [ $? -eq 0 ]; then
+                       if [ -n "$HOSTNAME" ]; then
+                               echo "$HOSTNAME"
+                       else
+                               echo "unknown"
+                       fi
+               else
+                       echo ${w%%.*}
+               fi
+       fi
+}
+
+get_hostname_from_display()
+{
+        if [ -n "$DISPLAY" ]; then
+
+                HOST=${DISPLAY%%:*}
+                NUMBER=${DISPLAY##*:}
+
+                # IP addresses are not supported here
+                echo $HOST | grep -q '^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$'
+                if [ $? -ne 0 ]; then
+                        echo ${DISPLAY%%.*}
+                               else
+                                       get_hostname_from_ip $HOST
+                               fi
+
+        else
+                echo "unknown"
+        fi
+}
+
+
+kill_user_processes() {
+       # don't let root do this
+       if [ "$USER" == "root" -o $UID -eq 0 ]; then
+               return
+       fi
+
+       # Preset, or load from file
+       candidates="kdeinit\: soffice.bin mozilla-bin"
+       [ -r /etc/goto/kill-process.conf ] && candidates=$(cat /etc/goto/kill-process.conf)
+
+       # kill old existing user processes
+       for process in $candidates; do
+               ps -fu $USER | grep "$process" | grep -v 'kprogress' | awk ' FS=" " { system("kill "$2) } '
+       done
+
+       # kill old existing user processes that didn't left us with SIGTERM
+       for process in $candidates; do
+               ps -fu $USER | grep "$process" | grep -v 'kprogress' | awk ' FS=" " { system("kill "$2) } '
+       done
+}
+
+fix_ldif() {
+        (cat -; echo "bank") | awk '
+/^[a-zA-Z]/     {
+        if(line!=""){
+                print line
+        }
+
+        line    = $0
+}
+/^ /    {
+        line    = line substr($0,2)
+}
+'
+}
+
+
+ldap_init() {
+       if [ $# -ne 2 ]; then
+               for config in /etc/*ldap/ldap.conf /etc/ldap.conf; do
+
+                       # Not readable? Continue
+                       [ ! -r $config ] && continue
+
+                       # Try to read config
+                       touch /tmp/agent.$$
+                       cat $config | while read line; do
+                               echo $line | grep -q '^BASE'
+                               [ $? -eq 0 ] && echo LDAP_BASE="\"$(echo $line|tr '\t' ' '|cut -d\  -f2-)\"" >>/tmp/agent.$$
+                               echo $line | grep -q '^HOST'
+                               [ $? -eq 0 ] && echo LDAP_HOST="$(echo $line|tr '\t' ' '|cut -d\  -f2-)" >>/tmp/agent.$$
+                               echo $line | grep -q '^URI'
+                               [ $? -eq 0 ] && echo LDAP_HOST="$(v=`echo $line|tr '\t' ' '|cut -d\  -f2-`;echo ${v##*://})" >> /tmp/agent.$$
+                       done
+                       eval $(cat /tmp/agent.$$)
+                       rm /tmp/agent.$$
+
+                       # One successful configuration should be enough
+                       break
+               done
+               if [ -z "$LDAP_HOST" -o -z "$LDAP_BASE" ]; then
+                       echo "Critical: no LDAP configuration found!"
+                       exit
+               fi
+       else
+               LDAP_HOST=$1
+               LDAP_BASE=$2
+       fi
+}
+
+
+ldap_count() {
+       ldapsearch -x -LLL -h "$LDAP_HOST" -b "$LDAP_BASE" "$1" dn | grep '^dn:' | wc -l
+}
+
+
+decode_blob() {
+       base64-decode > /tmp/agent-lib-decode.$$
+       file /tmp/agent-lib-decode.$$ 2>/dev/null| grep -qi 'text'
+       [ $? -eq 0 ] && cat /tmp/agent-lib-decode.$$ | recode 'utf8..latin1'
+       [ -f /tmp/agent-lib-decode.$$ ] && rm /tmp/agent-lib-decode.$$
+}
+
+ldap_import() {
+  for v in $(set grep ldap_import_ | cut -d= -f1); do unset $v; done
+  vname_lastrun=""
+  counter=0
+  > /tmp/agent-lib.$$
+  (ldapsearch -x -LLL -h "$LDAP_HOST" -b "$LDAP_BASE" $2 "$1" $3 2> /dev/null) | fix_ldif | sed 's/^\([^:]*\):\(.*\)$/\1="\2"/' | while read line; do
+               vname=$(echo $line|cut -d= -f1)
+               vvalue=$(echo $line|cut -d= -f2-)
+
+               echo $line | grep -q '=": '
+               if [ $? -eq 0 ]; then
+                       vvalue=`echo $line|sed 's/^[^="]*=": //'|decode_blob`
+                       vvalue="$vvalue\""
+               else
+                       vvalue=`echo $line|sed 's/^[^="]*=" //'`
+               fi
+
+               if [ "$vname_lastrun" == "$vname" ]; then
+                       counter=$(( $counter + 1 ));
+               else
+                       counter=0
+                       vname_lastrun=$vname
+               fi
+               
+               echo "ldap_import_$vname[$counter]=\"$vvalue" >> /tmp/agent-lib.$$
+       done
+
+       eval $(cat /tmp/agent-lib.$$)
+       rm /tmp/agent-lib.$$
+}
+
+ldap_cat() {
+   vname_lastrun=""
+   counter=0
+   > /tmp/agent-lib.$$
+   (ldapsearch -x -LLL -h "$LDAP_HOST" -b "$1" -s base 2> /dev/null) | fix_ldif | sed 's/
+^\([^:]*\):\(.*\)$/\1="\2"/' | while read line; do
+               vname=$(echo $line|cut -d= -f1)
+               vvalue=$(echo $line|cut -d= -f2-)
+
+               echo $line | grep -q '=": '
+               if [ $? -eq 0 ]; then
+                       vvalue=`echo $line|sed 's/^[^="]*=": //'|decode_blob`
+                       vvalue="$vvalue\""
+               else
+                       vvalue=`echo $line|sed 's/^[^="]*=" //'`
+               fi
+
+               if [ "$vname_lastrun" == "$vname" ]; then
+                       counter=$(( $counter + 1 ));
+               else
+                       counter=0
+                       vname_lastrun=$vname
+               fi
+
+               echo "ldap_import_$vname[$counter]=\"$vvalue" >> /tmp/agent-lib.$$
+       done
+
+       eval $(cat /tmp/agent-lib.$$)
+       rm /tmp/agent-lib.$$
+ }
+
+
+
+ldap_get_group_membership_of() {
+       ldapsearch -x -LLL -h "$LDAP_HOST" -b "$LDAP_BASE" "(memberUid=$1)" \
+                               cn 2> /dev/null | fix_ldif | awk '/^cn: / {print $2}'
+}
+
+
+ldap_get_applications_of() {
+       ldapsearch -x -LLL "(memberUid=$1)" gosaMemberApplication | fix_ldif | \
+                               awk '/^gosaMemberApplication:/ {print $2}'| sort | uniq
+}
+
+
+ldap_get_appservers() {
+       ldapsearch -x -LLL "(objectclass=goTerminalServer)" cn | fix_ldif | grep -w cn: |cut -d' ' -f 2
+}
+
+
+translate() {
+       # Look for translation
+       while read line; do
+               string="${line%%=*}"
+               if [ "$string" == "$*" ]; then
+                       echo "${line##*=}"
+                       return
+               fi
+       done < /etc/goto/goto-locales.dat
+       echo $*
+}
+
+
+show_progress() {
+       # No translation available
+       echo $PROGRESS $(translate "$*")
+}
+
+
+create_desktop_link() {
+       echo "$gosaApplicationFlags" | grep -q "D"
+       if [ $? -eq 0 ]; then
+               [ $DEBUG -eq 1 ] && echo "goto_setup: creating desktop link for application $application" 1>&2
+               cat << EOF > ~/Desktop/$cn
+[Desktop Entry]
+Comment=$description
+Encoding=UTF-8
+Exec=$gosaApplicationExecute
+Icon=$HOME/.kde/share/icons/${cn}.png
+Name=$gosaApplicationName
+Type=Application
+EOF
+       fi
+}
+
+
+create_menu_entry() {
+       echo "$gosaApplicationFlags" | grep -q "M"
+       if [ $? -eq 0 ]; then
+               [ $DEBUG -eq 1 ] && echo "goto_setup: creating menu link for application $application" 1>&2
+               cat << EOF > ~/.local/share/applications/$cn.desktop
+[Desktop Entry]
+Type=Application
+Encoding=UTF-8
+Exec=$gosaApplicationExecute
+Name=$gosaApplicationName
+GenericName=
+Comment=$description
+Icon=$HOME/.kde/share/icons/${cn}.png
+Terminal=false
+Categories=$appcat;
+EOF
+       fi
+}
+
+delete_all_applinks() {
+       list=`ldapsearch -x "objectClass=gosaApplication" cn | fix_ldif | awk '/^cn: / {print $2}'`
+       for link in $list; do
+               [ -f $HOME/Desktop/$link ] && rm -f $HOME/Desktop/$link
+               [ -f $HOME/.kde/share/applnk/$link.desktop ] && rm -rf $HOME/.kde/share/applnk/$link.desktop
+       done
+}
+
+
+function terminal_load_hardware_profile() {
+       rm -f $RAM/etc/sysconfig/GOto && touch $RAM/etc/sysconfig/GOto
+       ldapsearch -x -LLL -h $LDAP_HOST -b "$LDAP_BASE" -D "cn=terminal-admin,$LDAP_BASE" -w "$(cat /etc/goto/secret)" "(&(objectClass=gotoWorkstation)(macAddress=$1))" 2> /dev/null | fix_ldif | sed -e 's/^\([^:]*\): \(.*\)$/\U\1\E="\2"/' -e 's/^GOTO//g' >> /etc/sysconfig/GOto
+
+       # Get DN and load all parent defaults from tree
+       current=$(grep "^DN=" /etc/sysconfig/GOto|sed 's/\"//g;s/, /,/g;s/^.*,ou=terminals,ou=systems,//g')
+
+       # Load potential object group entries 
+       ldapsearch -x -LLL -h $LDAP_HOST -b "$LDAP_BASE" -D "cn=terminal-admin,$LDAP_BASE" -w "$(cat /etc/goto/secret)" "(&(objectClass=gosaGroupOfNames)(member=$(echo -n $current|sed 's/^DN=//')))" 2> /dev/null | fix_ldif | sed -e 's/^\([^:]*\): \(.*\)$/\U\1\E="\2"/' -e 's/^GOTO//g' >> /etc/sysconfig/GOto
+
+       # get reverse list of potential default entries - for backward compatibility
+       { while true; do
+               # write out current value
+               echo "ou=terminals,ou=systems,$current"
+
+               # prepare next entry
+               echo $current | grep -q ','
+               [ $? -ne 0 ] && break
+               [ "$LDAP_BASE" == "$current" ] && break
+               current=${current#*,}
+       done } | tac | while read line; do
+
+    # Read potential default entries and append
+    # them to sysconfig/GOto
+       ldapsearch -x -LLL -h $LDAP_HOST -D "cn=terminal-admin,$LDAP_BASE" -w "$(cat /etc/goto/secret)" -b $line "(&(objectClass=gotoWorkstation)(cn=wdefault))" 2> /dev/null | fix_ldif | sed -e 's/^\([^:]*\): \(.*\)$/\U\1\E="\2"/' -e 's/^GOTO//g' >> /etc/sysconfig/GOto
+  done
+
+  # Reverse sysconfig/GOto
+  tac /etc/sysconfig/GOto > /etc/sysconfig/GOto.tmp
+  mv /etc/sysconfig/GOto.tmp /etc/sysconfig/GOto
+}
+
+
+terminal_has_hardware_profile() {
+       # Do we have a configuration?
+       terminal_load_hardware_profile $1
+       grep -v "cn=default," /etc/sysconfig/GOto | grep -q "DN="
+}
+
+
+terminal_activated() {
+       # Do we have a configuration?
+       terminal_load_hardware_profile $1
+       grep -v ',ou=incoming,' /etc/sysconfig/GOto | grep -v 'cn=default,' | grep -q "DN="
+}
+
+
+terminal_dump_hwprofile() {
+       # Save mac address
+       mac=$1
+       name=$(hostname)
+       
+       # Source hardware information detected by hwsetup
+       for module in xserver sound netcard mouse; do
+               [ -f /etc/sysconfig/$module ] && . /etc/sysconfig/$module
+       done
+
+       # Get hardware information directly from /proc
+       cpu=$(cat /proc/cpuinfo | awk 'BEGIN { FS=": "; ORS="" } /^vendor_id/ {print $2" / "} /^model name/{print $2" - "} /^cpu MHz/ {print $2" MHz"}')
+       mem=$(cat /proc/meminfo | awk '/^MemTotal:/ {print $2" KB"}')
+       modlist=$(lsmod | sed -e '/^Module/d;/^snd/d;s/^\(\w*\).*$/\1/g')
+       hsync=$(ddcxinfo-knoppix -hsync|tr -d ' ')
+       vsync=$(ddcxinfo-knoppix -vsync|tr -d ' ')
+
+       # USB support?
+       [ -d /proc/bus/usb ] && usb="true" || usb="false"
+
+       # Add floppy/cdrom
+       grep -q 'floppy' /etc/sysconfig/autofs && FLOPPY='YES' || FLOPPY='NO'
+       grep -q 'cdrom' /etc/sysconfig/autofs && CDROM='YES' || CDROM='NO'
+
+       cat << EOF
+dn: cn=$name,ou=incoming,$LDAP_BASE
+objectClass: gotoWorkstation
+objectClass: goHard
+cn: $name
+macAddress: $mac
+gotoMode: locked
+gotoXDriver: $XMODULE
+gotoXMouseType: $XMOUSETYPE
+gotoXMouseport: $DEVICE
+gotoXHsync: $hsync
+gotoXVsync: $vsync
+ghUsbSupport: $usb
+gotoFloppyEnable: $FLOPPY
+gotoCdromEnable: $CDROM
+gotoSndModule: $SNDMODULE
+EOF
+
+       # Insert IDE-Devices
+       for f in /proc/ide/ide?/hd?/model; do
+               [ -f $f ] && echo "ghIdeDev: "$(echo $f | cut -d/ -f5)" ("$(cat $f)")"
+       done
+
+       (cat /proc/scsi/scsi | sed -ne 's/.*Vendor: \([^ ]*\) *Model: \([^ ]*\) *.*$/\1 \2/p') 2> /dev/null|while read line; do
+               echo ghScsiDev: $line
+       done
+
+       # Insert modules
+       for m in $modlist; do
+               echo "gotoModules: $m"
+       done | sort | uniq
+
+       # Add potential swap filesystems
+       [ -f /etc/sysconfig/swap ] && cat /etc/sysconfig/swap | while read line; do
+               echo "gotoFilesystem: $line"
+       done
+
+       # Add autofs devices
+       [ -f /etc/sysconfig/autofs ] && cat /etc/sysconfig/autofs | while read line; do
+               echo "gotoAutoFs: $line"
+       done
+
+       cat << EOF
+ghGfxAdapter: $XDESC
+ghNetNic: `cat /etc/sysconfig/netcard|grep "^FULLNAME"|cut -d= -f2|tr -d "\""`
+ghSoundAdapter: `cat /etc/sysconfig/sound|grep "^FULLNAME"|cut -d= -f2|tr -d "\""`
+ghMemSize: $mem
+ghCpuType: $cpu
+EOF
+}
+
+
+terminal_save_hardware_profile() {
+       # Get hardware ldif and strip out possibly broken entries
+    terminal_dump_hwprofile $1 | grep -v '^[^:]*: *$' &> /tmp/upload.ldif
+
+       # Upload ldif
+       while true; do
+               error=$(ldapadd -x -h "$LDAP_HOST" -D "cn=terminal-admin,$LDAP_BASE" -w "$(cat /etc/goto/secret)" < /tmp/upload.ldif 2>&1)
+               if [ $? -ne 0 ]; then
+                       dialog --msgbox "Das Terminal konnte sich nicht am LDAP anmelden. Bitte prüfen Sie de Einstellungen: $error" 14 60
+               else
+                       break
+               fi
+       done
+}
+
+
+terminal_alsa_setup() {
+       audio=$(lspci -n | awk '/ 0401/ {print $3}' | sed 's/://g' | head -1)
+       KVER=$(uname -r)
+       MODULE=$(cat /lib/modules/$KVER/modules.pcimap | (while read driver vendor device dummy; do
+               if expr $driver : 'snd-.*' > /dev/null; then
+                       printf '%04x%04x %s\n' $vendor $device $driver | grep "^$audio" | cut -d\  -f2
+               fi
+       done))
+       echo "SNDMODULE=\"$MODULE\"" >> /etc/sysconfig/sound
+}
+
+
+terminal_autofs_setup(){
+       wcount=1
+       lcount=1
+
+       # Remove old ones
+       rm -f /etc/sysconfig/autofs /etc/sysconfig/swap
+
+       # Generate autofs entries for removable devices
+       for d in /dev/floppy/?; do
+               [ "$d" == "/dev/floppy/?" ] && break
+               nr=$(echo $d | sed 's/^.*\/\([^/]*$\)/\1/g')
+               echo "floppy$nr -fstype=auto,sync,nodev,nosuid,umask=000,quiet,rw :$d" >> /etc/sysconfig/autofs
+       done
+
+       for d in /dev/cdroms/*; do
+               [ "$d" == "/dev/cdroms/*" ] && break
+               name=`echo $d | sed 's/^.*\/\([^/]*$\)/\1/g'`
+               echo "$name -fstype=iso9660,sync,nodev,nosuid,umask=000,quiet,ro :$d" >> /etc/sysconfig/autofs
+       done
+
+       # Generate autofs entries for fixed drives
+       (sfdisk -qLl | grep "^/" | tr -d '\*') | while read device d1 d2 d3 d4 type d5; do
+        case $type in
+         [4bce])
+               echo "win$wcount -fstype=vfat,sync,nodev,nosuid,umask=000,quiet,rw :$device" >> /etc/sysconfig/autofs
+               wcount=$(( $wcount + 1 ))
+               ;;
+         7)
+               echo "win$wcount -fstype=ntfs,sync,nodev,nosuid,umask=000,quiet,ro :$device" >> /etc/sysconfig/autofs
+               wcount=$(( $wcount + 1 ))
+               ;;
+         83)
+               echo "linux$lcount -fstype=ext3,sync,nodev,nosuid,umask=000,quiet,rw :$device" >> /etc/sysconfig/autofs
+               lcount=$(( $lcount + 1 ))
+               ;;
+      82)
+                echo "$device none swap sw 0 0" >> /etc/sysconfig/swap
+               ;;
+        esac
+       done
+}
+
+
+get_xdmcp_server(){
+       SERVERS=$(ldapsearch -LLL -b "$LDAP_BASE" -H $LDAP_HOST -x '(&(objectclass=goTerminalServer)(goXdmcpIsEnabled=true))'| awk '/^cn/{print $2}' 2> /dev/null)
+
+       # Generate load sorted server list
+       { for s in $SERVERS; do
+               xdmping $s -v -t 1 2> /dev/null | awk '!/contacting/ {print $5"|"$1"|"$2}' | sed 's/[:,]//g'
+       done } | egrep "^[0-9]" | sort -n > /tmp/xservers.tmp
+
+       case $(cat /tmp/xservers.tmp | wc -w | awk '{print $1}') in
+               0)
+                       return
+                       ;;
+               1)
+                       cat /tmp/xservers.tmp | cut -d\| -f2
+                       return
+            ;;
+               *)
+                       AVAILABLE=""
+                       for i in $(cat /tmp/xservers.tmp); do
+                               NEW=$(echo "$i" | awk -F "|" '{if ($1 < 0.5) print $1"|"$2}')
+                               [ -n "$NEW" ] && AVAILABLE="$NEW\n$AVAILABLE"
+                       done
+                       if [ -n "$AVAILABLE" ]; then
+                               echo -e "$AVAILABLE" > /tmp/xservers.tmp
+                               NUM=$(cat /tmp/xservers.tmp | wc -l | awk '{print $1 - 1}')
+                               ROW=$(echo $NUM | awk '{print rand() * $1 + 1 ;}' | cut -d . -f1)
+                               cat /tmp/xservers.tmp | sed -n "${ROW}p" | cut -d\| -f2
+                       else
+                               cat /tmp/xservers.tmp|egrep "^[0-9]"|tr "." ","|sort -n|head -1|cut -d\| -f2
+                       fi
+                       ;;
+       esac
+}
+
+
+get_fontpath() {
+       ldapsearch -x -LLL -h $LDAP_HOST -b "$LDAP_BASE" "(&(objectClass=goTerminalServer)(cn=$1))" |
+               grep "^goFontPath" | cut -d\  -f2- | sed 's!\/!\/!g'
+}
+
diff --git a/gosa-core/contrib/fai/goto-fai/ldap2fai b/gosa-core/contrib/fai/goto-fai/ldap2fai
new file mode 100755 (executable)
index 0000000..50f315d
--- /dev/null
@@ -0,0 +1,630 @@
+#!/usr/bin/perl
+# $Id$
+#*********************************************************************
+#
+# ldap2fai -- read FAI config from LDAP and create config space
+#
+# This script is part of FAI (Fully Automatic Installation)
+# (c) 2005, Thomas Lange <lange@informatik.uni-koeln.de>
+# (c) 2005, Jens Nitschke <jens.nitschke@2int.de>
+# (c) 2005, Jan-Marek Glogowski <glogow@fbihome.de>
+# (c) 2005, Cajus Pollmeier <pollmeier@gonicus.de>
+#
+#*********************************************************************
+
+use strict;
+use Net::LDAP;
+use MIME::Base64;
+use Getopt::Std;
+use File::Path;
+use File::Copy;
+use vars qw/ %opt /;
+
+my $base;
+my $ldapuri;
+my $ldapdir = "/etc/ldap/ldap.conf";
+my $outdir = "/fai";
+my $verbose = 0;
+my $opt_string = 'c:d:hv';
+my $hostname;
+
+getopts( "$opt_string", \%opt ) or usage("Hello");
+usage("Help") if $opt{h};
+
+$verbose = $opt{v} ? 1 : 0;
+$outdir  = $opt{d} ? $opt{d} : $outdir;
+$ldapdir = $opt{c} ? $opt{c} : $ldapdir;
+
+# Get MAC from cmdline
+my $mac = shift @ARGV;
+$mac eq '' && usage("MAC address not specified.");
+
+# Is outdir a directory
+-d "$outdir" || usage("'$outdir' is not a directory.\n");
+
+my @classes=(); # the classes a host belongs to
+
+# initialize ldap
+setup();
+my $ldap = Net::LDAP->new("$ldapuri") or die "$@";
+my $mesg = $ldap->bind;
+
+# create class hooks debconf disk_config package_config scripts files
+my @dirs= qw/class hooks debconf disk_config package_config scripts files/;
+foreach (@dirs) {
+  -d "$outdir/$_" || mkpath "$outdir/$_" 
+    || warn "WARNING: Can't create subdir $outdir/$_ $!\n";
+}
+
+@classes= get_classes($mac);
+prt_scripts();
+prt_package_list();
+prt_debconf();
+prt_templates();
+prt_var();
+prt_hooks();
+prt_disk_config();
+
+# create sources list
+if (!$hostname) {
+  -d "${outdir}/files/etc/apt/sources.list" 
+    || mkpath "${outdir}/files/etc/apt/sources.list";
+  copy ("${outdir}/tmp/apt-sources.list",
+    "${outdir}/files/etc/apt/sources.list/$hostname") ;
+}
+
+$mesg = $ldap->unbind;   # take down session
+exit 0;
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub setup
+{
+  # Read LDAP
+  open (LDAPCONF,"${ldapdir}") 
+    || usage("Can't open LDAP configuration$!\n");
+  my @content=<LDAPCONF>;
+  close(LDAPCONF);
+
+  # Scan LDAP config
+  foreach my $line (@content) {
+    $line =~ /^\s*(#|$)/ && next;
+    chomp($line);
+
+    if ($line =~ /^BASE\s+(.*)$/) {
+      $base= $1;
+      next;
+    }
+    if ($line =~ m#^URI\s+ldaps?://([^/:]+).*$#) {
+      $ldapuri= $1;
+      next;
+    }
+  }
+}
+
+sub usage
+{
+  (@_) && print STDERR "\n@_\n\n";
+
+  print STDERR << "EOF";
+usage: $0 [-hv] [-c config] [-d outdir] <MAC>
+
+-h        : this (help) message
+-c        : LDAP config file (default: ${ldapdir})
+-d        : output dir (default: ${outdir})
+-v        : be verbose
+EOF
+       exit -1;
+}
+#-----------------------------------------------------------------------------------
+
+sub write_file {
+
+       my @opts = @_;
+       my $len = scalar @_;
+       ($len < 2) && return;
+
+       my $filename = shift;
+       my $data = shift;
+
+       open (SCRIPT,">${filename}") || warn "Can't create ${filename}. $!\n";
+       print SCRIPT $data;
+       close(SCRIPT);
+
+  ($opts[2] ne "") && chmod oct($opts[2]),${filename};
+       ($opts[3] ne "") && chown_files(${filename}, $opts[3]);
+}
+
+#-----------------------------------------------------------------------------------
+
+sub chown_files
+{
+  my @owner = split('.',@_[1]);
+  my $filename = @_[0];
+  my ($uid,$gid);
+  $uid = getpwnam(@owner[0]);
+  $gid = getgrnam(@owner[1]);
+  
+  chown $uid, $gid, $filename;
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub get_classes {
+
+       # return list of FAI classes defined for host
+       my $mac = shift;
+       my (@classes,$mesg,$entry);
+
+  $mesg = $ldap->search(
+    base => "ou=systems,$base",
+    filter => "(&(macAddress=$mac)(objectClass=gotoWorkstation))",
+    attrs => [ 'FAIclass', 'cn']);
+  $mesg->code && die $mesg->error;
+  # normally, only one value should be returned
+  if ($mesg->count != 1) {
+      die "LDAP search for client failed. ".$mesg->count." entries have been returned\n";
+    }
+  
+   # this assigns the last value to @classes     
+   $entry= ($mesg->entries)[0];
+   @classes= split /\s+/,$entry->get_value('FAIclass');
+
+  # get hostname
+       my $hname= $entry->get_value('cn');
+  my $dn= $entry->dn;
+  $hostname= $hname;
+
+  # Search for object groups containing this client
+  $mesg = $ldap->search(
+    base => "ou=groups,$base",
+    filter => "(&(objectClass=gosaGroupOfNames)(objectClass=FAIobject)(member=$dn))",
+    attrs => [ 'FAIclass' ]);
+  $mesg->code && die $mesg->error;
+       foreach my $m ($mesg->entries) {
+    push @classes, split /\s+/,$m->get_value('FAIclass');
+  }
+
+       # print all classes to the file with hostname
+       open (FAICLASS,">$outdir/class/$hname") || warn "Can't create $outdir/class/$hname. $!\n";
+  my @newclasses;
+       foreach my $class (@classes) {
+
+    # We need to walk through the list of classes and watch out for
+    # a profile which is named like the class. Replace the profile
+    # name by the names of the included classes.
+    $mesg = $ldap->search(
+      base => "ou=systems,$base",
+      filter => "(&(objectClass=FAIprofile)(cn=$class))",
+      attrs => [ 'FAIclass' ]);
+    $mesg->code && die $mesg->error;
+
+    if ($mesg->count > 0){
+      foreach my $m ($mesg->entries) {
+        foreach my $tc (split /\s+/,$m->get_value('FAIclass')){
+          print FAICLASS "$tc\n";
+          push @newclasses, $tc;
+        }
+      }
+    } else {
+      print FAICLASS "$class\n";
+      push @newclasses, $class;
+    }
+  }
+       close(FAICLASS);
+       print "Host $hname belongs to FAI classes: ",join ' ',@newclasses,"\n" if $verbose;
+       return @newclasses;
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub get_variables {
+       # gets all variables defined for a class
+       # returns a list of lines in bourne shell syntax
+
+   my $class = shift; 
+        my ($mesg,$var_base,$entry,$line,@vars);
+
+        $mesg = $ldap->search(
+                      base => "$base",
+                      filter => "(&(cn=$class)(objectClass=FAIvariable))",
+                      attrs => [ 'cn']);
+        return if ($mesg->count() == 0); # skip if no such object exists              
+        $mesg->code && die $mesg->error;
+
+        $entry=($mesg->entries)[0];
+        $var_base=$entry->dn;
+
+        $mesg = $ldap->search(
+                        base => "$var_base",
+                        filter => "(objectClass=FAIvariableEntry)",
+                        attrs => ['cn', 'FAIvariableContent']);
+        return if ($mesg->count() == 0); # skip if no such object exists
+        $mesg->code && die $mesg->error;
+                        
+
+        foreach $entry ($mesg->entries) {
+                $line= sprintf "%s=\'%s\'\n", $entry->get_value('cn'), 
+                        $entry->get_value('FAIvariableContent');
+                push @vars,$line;
+        }
+        return @vars;
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub prt_var {
+
+       my (@lines, $hname);
+
+       foreach my $class (@classes) {
+               @lines = get_variables($class);
+               next until @lines; # do not create .var file if no variables are defined
+               open (FAIVAR,">$outdir/class/${class}.var") 
+      || warn "Can't create $outdir/class/$hname.var.$!\n";
+               print FAIVAR @lines;
+               close(FAIVAR);
+       }
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub get_disk_config {
+
+       my $class = shift;
+  my ($mesg,$entry,$line,@diskconfig,$partition_base,$dn,%diskline,$xxmesg);
+
+       # Search for partition schema for the specified class
+       $mesg = $ldap->search(
+                     base => "$base",
+                     filter => "(&(cn=$class)(objectClass=FAIpartitionTable))" );
+
+       return if ($mesg->count() == 0); # skip if no such object exists
+       $mesg->code && die $mesg->error;
+
+       $entry=($mesg->entries)[0];
+       $partition_base= $entry->dn;
+       
+       # Search for disks
+       $mesg = $ldap->search(
+                     base => "$partition_base",
+                     filter => "(objectClass=FAIpartitionDisk)" );
+
+       return if ($mesg->code == 32); # skip if no such object exists
+       $mesg->code && die $mesg->error;
+
+       foreach $entry ($mesg->entries) {
+    my $logic_count= 4;
+    my $primary_count= 0;
+               my $dn=$entry->dn;
+               my $disk=$entry->get_value('cn');
+    my $part;
+               undef %diskline;
+               $diskline{0} = "disk_config $disk\n";
+               $xxmesg = $ldap->search(
+                       base => "$dn",
+                       filter => "objectClass=FAIpartitionEntry" );
+               $xxmesg->code && die $xxmesg->error;
+               foreach my $dl ($xxmesg->entries) {
+      if ($dl->get_value('FAIpartitionType') eq 'primary'){
+        $primary_count++;
+      } else {
+        $logic_count++;
+      }
+                       if ($dl->get_value('FAIpartitionFlags') eq 'preserve'){
+        if ($dl->get_value('FAIpartitionType') eq 'primary'){
+          $part= 'preserve'.$primary_count;
+        } else {
+          $part= 'preserve'.$logic_count;
+        }
+                               $line= sprintf "%-7s %-12s %-12s %-10s ; %s\n",
+                                       $dl->get_value('FAIpartitionType'),
+                                       $dl->get_value('FAImountPoint'),
+                                       $part,
+                                       $dl->get_value('FAImountOptions') eq '' 
+                                               ? 'rw' : $dl->get_value('FAImountOptions'),
+                                       $dl->get_value('FAIfsOptions');
+                       }         
+                       elsif ($dl->get_value('FAIfsType') eq 'swap'){
+                               $line= sprintf "%-7s %-12s %-12s %-10s\n",
+                               $dl->get_value('FAIpartitionType'),
+                               $dl->get_value('FAImountPoint'),
+                               $dl->get_value('FAIpartitionSize'),
+                               $dl->get_value('FAImountOptions') eq '' 
+                                       ? 'rw' : $dl->get_value('FAImountOptions');
+                       } 
+                       else {
+                               $line= sprintf "%-7s %-12s %-12s %-10s ; %s %s\n",
+                               $dl->get_value('FAIpartitionType'),
+                               $dl->get_value('FAImountPoint'),
+                               $dl->get_value('FAIpartitionSize'),
+                               $dl->get_value('FAImountOptions') eq '' 
+                                       ? 'rw' : $dl->get_value('FAImountOptions'),
+                               $dl->get_value('FAIfsOptions'),
+                               $dl->get_value('FAIfsType');
+                       }
+
+                       $diskline{$dl->get_value('FAIpartitionNr')}=$line;
+               }
+               foreach my $l (sort {$a <=> $b} keys %diskline) {
+                       push @diskconfig, $diskline{$l};
+               }
+       }
+       return @diskconfig;
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub prt_disk_config {
+
+       # create one disk_config file
+
+       my ($class,@lines);
+
+       foreach $class (reverse @classes) {
+               @lines=get_disk_config($class);
+               next until @lines; # skip if nothing is defined for this class
+
+    print "Generating partition layout for class '${class}'\n." if $verbose;
+               open (FAIVAR,">${outdir}/disk_config/${class}") 
+      || warn "Can't create $outdir/disk_config/$class. $!\n";
+               print FAIVAR join '',@lines;
+               close(FAIVAR);
+               last; # finish when one config file is created
+       }
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub get_packages {
+
+       # gets list of packages defined for a class
+
+       my $class = shift;
+       my ($mesg,$entry,$line,$method,%packlist);
+
+  -d "${outdir}/tmp" || mkpath "${outdir}/tmp"
+    || warn "Can't create ${outdir}/tmp. $!\n";
+  print "Generate sources.list for install\n" if $verbose;
+       open (SOURCES,">>${outdir}/tmp/apt-sources.list") 
+    || warn "Can't create ${outdir}/tmp/apt-sources.list. $!\n";
+
+       $mesg = $ldap->search(
+                       base => "$base",
+                       filter => "(&(cn=$class)(objectClass=FAIpackageList))" ,
+                       attrs => [ 'FAIpackage', 'FAIinstallMethod', 
+                 'FAIdebianMirror', 'FAIdebianRelease', 'FAIdebianSection']);
+
+       $mesg->code && die $mesg->error;
+       # should also return only one value
+
+       undef %packlist;
+       foreach $entry ($mesg->entries) {
+               $method=$entry->get_value('FAIinstallMethod');
+               push @{$packlist{$method}}, $entry->get_value('FAIpackage');
+
+               print SOURCES "deb ".$entry->get_value('FAIdebianMirror')." ".$entry->get_value('FAIdebianRelease')." ";
+    my $section;
+    foreach $section ($entry->get_value('FAIdebianSection')){
+      print SOURCES "$section ";
+    }
+    print SOURCES "\n";
+       }
+
+  close (SOURCES);
+
+       # return a ref to the hash of arrays (key of the hash is the method),
+       # the value is the array of package names for this method
+       return \%packlist;
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub prt_package_list {
+
+       my (@lines,$plist,$method,$value);
+
+       foreach my $class (@classes) {
+               $plist=get_packages($class);
+               # test if hash contains any keys or values
+               unless (keys %{$plist}) {
+                       next;
+               }
+
+    print "Generate package list for class '$class'.\n" if $verbose;
+               open (PACKAGES,">$outdir/package_config/$class") 
+      || warn "Can't create $outdir/package_config/$class. $!\n";
+               while (($method, $value) = each %{$plist}) {
+                       print PACKAGES "PACKAGES $method\n";
+                       print PACKAGES join "\n",@{$value};
+                       print PACKAGES "\n";
+               }
+               close(PACKAGES);
+       }
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub get_templates {
+
+       # get list of template-files defined for a class
+       my $class = shift;
+       my ($mesg,$entry,$str,$pfad,$name,$owner,$mode,$template_base,@template);
+
+       $mesg = $ldap->search(
+                       base => "$base",
+                       filter => "(&(cn=$class)(objectClass=FAItemplate))",
+                       attrs => ['cn']);
+       return if ($mesg->count() == 0); # skip if no such object exists
+       $mesg->code && die $mesg->error;
+
+       $entry=($mesg->entries)[0];
+       $template_base=$entry->dn;
+
+       $mesg = $ldap->search(
+                       base => "$template_base",
+                       filter => "(objectClass=FAItemplateEntry)",
+                       attrs => ['FAItemplateFile', 'FAItemplatePath', 'FAIowner', 'FAImode' ,'cn']);
+       return if ($mesg->count() == 0); # skip if no such object exists
+       $mesg->code && die $mesg->error;
+
+       foreach $entry ($mesg->entries) {
+               $name = $entry->get_value('cn');
+               $owner = $entry->get_value('FAIowner');
+               $owner = $entry->get_value('FAImode');
+               $pfad = $entry->get_value('FAItemplatePath');
+               chomp($pfad);
+               -d "${outdir}/files/${pfad}" || mkpath "${outdir}/files/${pfad}"
+      || warn "WARNING: Can't create subdir ${outdir}/files/${pfad} !$\n";
+    print "Generate template '$pfad' ($name) for class '$class'.\n" if $verbose;
+               write_file( "${outdir}/files/${pfad}/${class}", 
+                       $entry->get_value('FAItemplateFile'),$entry->get_value('FAImode'),$entry->get_value('FAIowner'));
+       }
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub prt_templates {
+       my ($class);
+
+       foreach $class (reverse @classes) {
+               get_templates($class);
+       }
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub get_debconf {
+
+       # gets list of packages defined for a class
+
+       my $class = shift; 
+       my ($mesg,$entry,$str,$debconf_base,@debconf);
+
+       $mesg = $ldap->search(
+                       base => "$base",
+                       filter => "(&(cn=$class)(objectClass=FAIpackageList))",
+                       attrs => ['cn']);
+       return if ($mesg->count() == 0); # skip if no such object exists
+       $mesg->code && die $mesg->error;
+
+       $entry=($mesg->entries)[0];
+       $debconf_base=$entry->dn;
+
+       $mesg = $ldap->search(
+                       base => "$debconf_base",
+                       filter => "(objectClass=FAIdebconfInfo)" ,
+                       attrs => [ 'FAIpackage', 'FAIvariable', 
+                               'FAIvariableType','FAIvariableContent']);
+       $mesg->code && die $mesg->error;
+
+       # undef @debconf;
+       foreach $entry ($mesg->entries) {
+               $str = sprintf "%s %s %s %s\n",
+               $entry->get_value('FAIpackage'),
+               $entry->get_value('FAIvariable'),
+               $entry->get_value('FAIvariableType'),
+               $entry->get_value('FAIvariableContent');
+               push @debconf, $str;
+       }
+       return @debconf;
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub prt_debconf {
+
+       my @lines;
+       my $class;
+
+       foreach $class (@classes) {
+               @lines = get_debconf($class);
+               next until @lines;
+    print "Generate DebConf for class '$class'.\n" if $verbose;
+               open (DEBCONF,">${outdir}/debconf/${class}") || warn "Can't create $outdir/debconf/$class. $!\n";
+               print DEBCONF @lines;
+               close(DEBCONF);
+       }
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub prt_scripts {
+       my ($class,@lines);
+
+       foreach $class (@classes) {
+               get_scripts($class);
+       }
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub get_scripts {
+
+       # gets list of packages defined for a class
+
+       my $class = shift;
+       my ($mesg,$entry,$str,$script_base,$prio,$name,$script);
+
+       $mesg = $ldap->search(
+                       base => "$base",
+                       filter => "(&(cn=$class)(objectClass=FAIscript))",
+                       attrs => ['cn']);
+       return if ($mesg->count() == 0); # skip if no such object exists
+       $mesg->code && die $mesg->error;
+
+       $entry=($mesg->entries)[0];
+       $script_base= $entry->dn;
+
+       $mesg = $ldap->search(
+                       base => "$script_base",
+                       filter => "(objectClass=FAIscriptEntry)",
+                       attrs => ['FAIpriority', 'FAIscript', 'cn']);
+       return if ($mesg->count() == 0); # skip if no such object exists
+       $mesg->code && die $mesg->error;
+       
+       foreach $entry ($mesg->entries) {
+               $name  = $entry->get_value('cn');
+               $prio  = $entry->get_value('FAIpriority');
+               $script= sprintf('%02d-%s', $prio, $name);
+
+    -d "$outdir/scripts/$class" || mkpath "$outdir/scripts/$class" ||
+       warn "WARNING: Can't create subdir $outdir/scripts/$class !$\n";
+
+               write_file("${outdir}/scripts/${class}/${script}",
+                       $entry->get_value('FAIscript'), "0700");
+       }
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub prt_hooks {
+       my ($class,@lines);
+
+       foreach $class (reverse @classes) {
+               get_hooks($class);
+       }
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sub get_hooks {
+
+       # gets list of packages defined for a class
+
+       my $class = shift;
+       my ($mesg,$entry,$str,$hook_base,$prio,$task,$hook,$name);
+
+       $mesg = $ldap->search(
+                       base => "$base",
+                       filter => "(&(cn=$class)(objectClass=FAIhook))",
+                       attrs => ['cn']);
+       return if ($mesg->count() == 0); # skip if no such object exists
+       $mesg->code && die $mesg->error;
+
+       $entry=($mesg->entries)[0];
+       $hook_base= $entry->dn;
+
+       $mesg = $ldap->search(
+                       base => "$hook_base",
+                       filter => "(objectClass=FAIhookEntry)",
+                       attrs => ['FAItask', 'FAIscript', 'cn']);
+       return if ($mesg->count() == 0); # skip if no such object exists
+       $mesg->code && die $mesg->error;
+       
+       foreach $entry ($mesg->entries) {
+               $name = $entry->get_value('cn');
+               $task = $entry->get_value('FAItask');
+               $prio = $entry->get_value('FAIpriority');
+               $hook = sprintf('%s.%s', ${task}, ${class});
+
+               write_file("${outdir}/hooks/${hook}", 
+                       $entry->get_value('FAIscript'), "0700");
+       }
+}
+
+# vim:ts=2:sw=2:expandtab:shiftwidth=2:syntax:paste
diff --git a/gosa-core/contrib/fai/goto-fai/secret b/gosa-core/contrib/fai/goto-fai/secret
new file mode 100644 (file)
index 0000000..7f480a8
--- /dev/null
@@ -0,0 +1 @@
+your secret terminal-admin password
diff --git a/gosa-core/contrib/fix_munged.php b/gosa-core/contrib/fix_munged.php
new file mode 100755 (executable)
index 0000000..405d345
--- /dev/null
@@ -0,0 +1,95 @@
+#!/usr/bin/php
+<?php
+require_once('../include/class_sambaMungedDial.inc');
+
+/*
+       * GOsa: fix_munged.php - Modify existings sambaMungedDial-Entries to work with latest Win2003SP1 
+       *
+       * Authors: Jan Wenzel    <jan.wenzel@GONICUS.de>
+       *
+       * Copyright (C) 2006 GONICUS GmbH
+       *
+       * This program is free software; you can redistribute it and/or modify
+       * it under the terms of the GNU General Public License as published by
+       * the Free Software Foundation; either version 2 of the License, or
+       * (at your option) any later version.
+       *
+       * This program is distributed in the hope that it will be useful,
+       * but WITHOUT ANY WARRANTY; without even the implied warranty of
+       * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       * GNU General Public License for more details.
+       *
+       * You should have received a copy of the GNU General Public License
+       * along with this program; if not, write to the Free Software
+       * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+       * USA
+       *
+       * Contact information: GONICUS GmbH
+       * Moehnestrasse 11-17
+       * D-59755 Arnsberg
+       * Germany
+       * tel: ++49 2932 916 0
+       * fax: ++49 2932 916 230
+       * email: info@GONICUS.de
+       * http://www.GONICUS.de
+       * */
+
+/* Modify these settings to your needs */
+$ldap_host= "localhost";
+$ldap_port= "389";
+$ldap_base= "dc=gonicus,dc=de";
+$ldap_admin= "cn=ldapadmin,".$ldap_base;
+$ldap_password= "tester";
+
+/* Internal Settings */
+$ldap_protocol= "3";
+$filter= "(&(objectClass=sambaSamAccount)(sambaMungedDial=*))";
+$attributes= array("dn","sambaMungedDial");
+
+print("This script will try to convert all ldap entries that have the sambaMungedDial-Attribute set, into the new \n".
+           "format that win2003sp1 and later requires. If an entry is already in the new format, it is not touched. \n".
+                       "BEWARE: This script is not widely tested yet, so use it at your own risk! Be sure to backup your complete LDAP \n".
+                       "before running.\n".
+                       "Do you want to continue (y/n)?\n");
+
+$handle= fopen("php://stdin","r");
+$input=(fgets($handle,16));
+fclose($handle);
+if(substr(strtolower($input),0,1)!="y") {
+       exit(1);
+}
+/* Connect to server */
+$connection= ldap_connect($ldap_host,$ldap_port) 
+       or die ('Could not connect to server '.$ldap_host."\n!");
+ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, $ldap_protocol);
+ldap_bind($connection,$ldap_admin,$ldap_password)
+       or die ('Could not bind to server '.$ldap_host."!\n");
+
+$results= ldap_get_entries($connection, ldap_search($connection, $ldap_base, $filter, $attributes));
+
+$count= 0;
+
+if(array_key_exists('count', $results)) {
+       $count= $results['count'];
+}
+
+if($count > 0) {
+       print('We found '.$count.' matching '.(($count==1)?'entry':'entries').".\n");
+}
+
+for($i=0; $i<$count; $i++) {
+       $entry= $results[$i];
+       print('Converting '.$entry['dn'].'...'); 
+       $mungedDial = new sambaMungedDial();
+       $mungedDial->load($entry['sambamungeddial'][0]);
+       $modify['sambaMungedDial'][0]= $mungedDial->getMunged();
+       if(ldap_modify($connection,$entry['dn'],$modify)) {
+               print("done.\n");
+       } else {
+               print("failed.\n");
+       }
+}
+
+ldap_close($connection);
+?>
+
diff --git a/gosa-core/contrib/gosa.conf b/gosa-core/contrib/gosa.conf
new file mode 100644 (file)
index 0000000..26a9ee2
--- /dev/null
@@ -0,0 +1,571 @@
+{literal}<?xml version="1.0"?>{/literal}
+<conf>
+       <menu>
+               <section name="My account">
+                       <plugin acl="users/generic" class="user" icon="personal.png"
+                               path="plugins/personal/generic" />
+                       <plugin acl="users/posixAccount" class="posixAccount" icon="posix.png"
+                               path="plugins/personal/posix" />
+                       <plugin acl="users/environment" class="environment" icon="env.png"
+{if $cv.optional.kioskpath_active}
+                               kioskpath="{$cv.optional.kioskpath}"
+{/if}
+                               path="plugins/personal/environment" />
+                       <plugin acl="users/mailAccount" class="mailAccount" icon="email.png"
+                               path="plugins/personal/mail" />
+                       <plugin acl="users/sambaAccount" class="sambaAccount" icon="samba.png"
+                               path="plugins/personal/samba" />
+{if $cv.use_netatalk}
+                       <plugin acl="users/netatalk" class="netatalk" icon="netatalk.png"
+                               path="plugins/personal/netatalk" />
+{else}
+<!--
+                       <plugin acl="default" class="netatalk" icon="netatalk.png"
+                               path="plugins/personal/netatalk" />
+-->
+{/if}
+                       <plugin acl="users/connectivity" class="connectivity" icon="proxy.png"
+                               path="plugins/personal/connectivity" />
+                       <plugin acl="users/gofaxAccount" class="gofaxAccount" icon="fax.png"
+                               path="plugins/gofax/faxaccount" />
+                       <plugin acl="users/phoneAccount" class="phoneAccount" icon="phone.png"
+                               path="plugins/gofon/phoneaccount" />
+<!--
+                       <plugin acl="users/nagiosAccount" class="nagiosAccount" icon="monitoring.png"
+                               path="plugins/personal/nagios" />
+-->
+                       <plugin acl="users/password" class="password" icon="password.png"
+                               path="plugins/personal/password" />
+               </section>
+               
+               <section name="Administration">
+                       <plugin acl="users" class="userManagement" icon="user.png"
+                               path="plugins/admin/users" />
+                       <plugin acl="groups" class="groupManagement" icon="group.png"
+                               path="plugins/admin/groups" />
+                       <plugin acl="ogroups" class="ogroupManagement" icon="ogroup.png"
+                               path="plugins/admin/ogroups" />
+                       <plugin acl="department" class="departmentManagement" icon="department.png"
+                               path="plugins/admin/departments" />
+                       <plugin acl="application" class="applicationManagement"
+                               icon="application.png" path="plugins/admin/applications" />
+                       <plugin acl="terminal,workstation,server,phone,printer,component,winworkstation" class="systems" icon="system.png"
+                               path="plugins/admin/systems" />
+{if $cv.enableMimeType}
+                       <plugin acl="mimetypes" class="mimetypeManagement"
+                               icon="mimetypes.png" path="plugins/admin/mimetypes" />
+{else}
+<!--
+                       <plugin acl="mimetype" class="mimetypeManagement"
+                               icon="mimetypes.png" path="plugins/admin/mimetypes" />
+-->
+{/if}
+                       <plugin acl="devices" class="deviceManagement"
+                               icon="devices.png" path="plugins/admin/devices" />
+
+                       <!-- Use 'lock_dn'      for dn
+                               'lock_name'    for name
+                               'lock_type'    for branch/freeze -->
+{if $cv.enableFAI_management}
+                       <plugin acl="fai" class="faiManagement" icon="fai.png" 
+                               path="plugins/admin/fai" />
+{else}
+<!--
+                       <plugin acl="FAIclass" class="faiManagement" icon="fai.png" 
+                               path="plugins/admin/fai" />
+-->
+{/if}
+                       <plugin acl="gofaxlist" class="blocklist" icon="blocklists.png"
+                               path="plugins/gofax/blocklists" />
+                       <plugin acl="gofonmacro" class="goFonMacro" icon="macros.png"
+                               path="plugins/gofon/macro" />
+                       <plugin acl="gofonconference" class="phoneConferenceManagment" icon="conference.png"
+                               path="plugins/gofon/conference" />
+                       <plugin acl="acl" class="acl" icon="acl.png"
+                               path="plugins/admin/acl" />
+               </section>
+
+               <section name="Addons">
+                       <plugin acl="addressbook" class="addressbook" icon="addressbook.png"
+                               path="plugins/addons/addressbook" />
+                       <plugin acl="faxreport" class="faxreport" icon="reports.png"
+                               path="plugins/gofax/faxreports" />
+                       <plugin acl="fonreport" class="fonreport" icon="phonereport.png"
+                               path="plugins/gofon/fonreports" />
+                       <plugin acl="logview" class="logview" icon="logview.png"
+                               path="plugins/addons/logview" />
+                       <plugin acl="mailqueue" class="mailqueue" icon="mailqueue.png"
+                               path="plugins/addons/mailqueue" />
+                       <plugin acl="ldapmanager" class="ldif" icon="ldif.png"
+                               path="plugins/addons/ldapmanager" />
+                       <plugin acl="msgplug" class="msgplug" icon="notifications.png"
+                               path="plugins/addons/notifications" />
+{if $cv.optional.gotomasses_active}
+                       <plugin acl="gotomasses" class="gotomasses" icon="system.png"
+                               storage_file="{$cv.optional.gotomasses_file}"
+                               path="plugins/addons/gotomasses" />
+{else}
+<!--
+                       <plugin acl="gotomasses" class="gotomasses" icon="system.png"
+                               path="plugins/addons/gotomasses" />
+-->
+{/if}
+<!--
+                       <plugin acl="all" class="bugsubmitter" icon="bugsubmitter.png"
+                               path="plugins/addons/bugsubmitter" />
+-->
+               </section>
+       </menu>
+
+       <aclroletab>
+               <tab class="aclRole" name="ACL Role" />
+       </aclroletab>
+
+       <usertabs>
+               <tab class="user" name="Generic" />
+               <tab class="posixAccount" name="Unix" />
+               <tab class="environment" name="Environment" />
+               <tab class="mailAccount" name="Mail" />
+               <tab class="sambaAccount" name="Samba" />
+{if $cv.use_netatalk}
+               <tab class="netatalk" name="Netatalk" />
+{else}
+<!--
+               <tab class="netatalk" name="Netatalk" />
+-->
+{/if}
+               <tab class="connectivity" name="Connectivity" />
+               <tab class="gofaxAccount" name="Fax" />
+               <tab class="phoneAccount" name="Phone" />
+<!--
+               <tab class="scalixAccount" name="Scalix" />
+-->
+<!--            
+               <tab class="nagiosAccount" name="Nagios" /> 
+-->
+       </usertabs>
+
+       <faxblocktabs>
+               <tab class="blocklistGeneric" name="Generic" />
+       </faxblocktabs>
+
+       <mimetabs>
+               <tab class="mimetype" name="Generic" />
+       </mimetabs>
+
+       <devicetabs>
+               <tab class="deviceGeneric" name="Generic" />
+       </devicetabs>
+
+
+       <grouptabs>
+               <tab class="group" name="Generic" />
+               <tab class="environment" name="Environment" />
+               <tab class="appgroup" name="Applications" />
+               <tab class="mailgroup" name="Mail" />
+       </grouptabs>
+
+       <appstabs>
+               <tab class="application" name="Generic" />
+               <tab class="applicationParameters" name="Options" />
+       </appstabs>
+
+       <conferencetabs>
+               <tab class="conference" name="Generic" />
+       </conferencetabs>
+
+       <macrotabs>
+               <tab class="macro" name="Generic" />
+               <tab class="macroParameter" name="Parameter" />
+       </macrotabs>
+
+       <termtabs>
+               <tab class="termgeneric" name="Generic" />
+               <tab class="termstartup" name="Startup" />
+               <tab class="termservice" name="Devices" />
+               <tab class="printgeneric" name="Printer" />
+               <tab class="terminfo" name="Information" 
+                       snmpcommunity="{$cv.optional.snmpcommunity}" />
+               <tab class="glpiAccount" name="Inventory" />
+       </termtabs>
+
+       <servtabs>
+               <tab class="servgeneric" name="Generic" />
+               <tab class="workstartup" name="Startup" />
+               <tab class="ServerService" name="Services" />
+{if $cv.enableFAI_management}
+           <tab class="faiSummaryTab" name="FAI summary" />
+{else}
+<!--    <tab class="faiSummaryTab" name="FAI summary" /> -->
+{/if}
+               <tab class="terminfo" name="Information" 
+                       snmpcommunity="{$cv.optional.snmpcommunity}" />
+               <tab class="glpiAccount" name="Inventory" />
+       </servtabs>
+
+       <worktabs>
+               <tab class="workgeneric" name="Generic" />
+               <tab class="workstartup" name="Startup" />
+               <tab class="workservice" name="Devices" />
+               <tab class="printgeneric" name="Printer" />
+               <tab class="terminfo" name="Information" 
+                       snmpcommunity="{$cv.optional.snmpcommunity}" />
+{if $cv.enableFAI_management}
+           <tab class="faiSummaryTab" name="FAI summary" />
+{else}
+<!--    <tab class="faiSummaryTab" name="FAI summary" /> -->
+{/if}
+               <tab class="glpiAccount" name="Inventory" />
+       </worktabs>
+
+       <printtabs>
+               <tab class="printgeneric" name="Generic" />
+               <tab class="glpiPrinterAccount" name="Inventory" />
+       </printtabs>
+
+       <phonetabs>
+               <tab class="phoneGeneric" name="Generic" />
+               <tab class="glpiAccount" name="Inventory" />
+       </phonetabs>
+
+       <componenttabs>
+               <tab class="componentGeneric" name="Generic" />
+               <tab class="glpiAccount" name="Inventory" />
+       </componenttabs>
+
+       <wintabs>
+               <tab class="wingeneric" name="Generic" />
+               <tab class="glpiAccount" name="Inventory" />
+       </wintabs>
+
+       <serverservice>
+               <tab class="goMailServer" />
+{if $cv.mail == "kolab"}
+               <tab class="servkolab" />
+{/if}
+               <tab class="goNtpServer" />
+               <tab class="servrepository" />
+               <tab class="goImapServer" />
+               <tab class="goKrbServer" />
+               <tab class="goFaxServer" />
+               <tab class="goFonServer" />
+               <tab class="goLogDBServer" />
+               <tab class="goGlpiServer" />
+               <tab class="goCupsServer" />
+               <tab class="goKioskService" />
+               <tab class="goSyslogServer" />
+               <tab class="goTerminalServer" />
+               <tab class="goLdapServer" />
+               <tab class="goShareServer" />
+{if $cv.generic_settings.enableDHCP}
+               <tab class="servdhcp" />
+{/if}
+{if $cv.generic_settings.enableDNS}
+               <tab class="servdns" />
+{/if}
+               <tab class="gosaLogServer" />
+       </serverservice>
+
+       <deptabs>
+               <tab class="department" name="Generic" />
+       </deptabs>
+
+       <ogrouptabs>
+               <tab class="ogroup" name="Generic" />
+       </ogrouptabs>
+
+       <connectivity>
+{if $cv.mail == "kolab"}
+               <tab class='kolabAccount' /> 
+{/if}
+               <tab class="proxyAccount" />
+               <tab class="pureftpdAccount" />
+               <tab class="webdavAccount" />
+               <tab class="phpgwAccount" />
+               <tab class="intranetAccount" />
+               <tab class="opengwAccount"
+                       username="OGo"
+                       password=""
+                       database="OGo"
+                       datahost="localhost" />
+<!--   
+               <tab class="pptpAccount" /> 
+               <tab class="phpscheduleitAccount" /> 
+-->
+       </connectivity>
+
+       <ldiftab>
+               <tab class="ldifexport" name="Export" />
+               <tab class="xlsexport" name="Excel Export" />
+               <tab class="ldifimport" name="Import" />
+               <tab class="csvimport" name="CSV Import" />
+       </ldiftab>
+
+{if $cv.enableFAI_management}
+       <faipartitiontabs>
+               <tab class="faiPartitionTable" name="Partitions" />
+       </faipartitiontabs>
+
+       <faiscripttabs>
+               <tab class="faiScript" name="Script" />
+       </faiscripttabs>
+
+       <faihooktabs>
+               <tab class="faiHook" name="Hooks" />
+       </faihooktabs>
+
+       <faivariabletabs>
+               <tab class="faiVariable" name="Variables" />
+       </faivariabletabs>
+
+       <faitemplatetabs>
+               <tab class="faiTemplate" name="Templates" />
+       </faitemplatetabs>
+
+       <faiprofiletabs>
+               <tab class="faiProfile" name="Profiles" />
+               <tab class="faiSummaryTab" name="Summary" />
+       </faiprofiletabs>
+
+       <faipackagetabs>
+               <tab class="faiPackage" name="Packages" />
+       </faipackagetabs>
+{else}
+<!-- 
+       <faipartitiontabs>
+               <tab class="faiPartitionTable" name="Partitions" />
+       </faipartitiontabs>
+
+       <faiscripttabs>
+               <tab class="faiScript" name="Script" />
+       </faiscripttabs>
+
+       <faihooktabs>
+               <tab class="faiHook" name="Hooks" />
+       </faihooktabs>
+
+       <faivariabletabs>
+               <tab class="faiVariable" name="Variables" />
+       </faivariabletabs>
+
+       <faitemplatetabs>
+               <tab class="faiTemplate" name="Templates" />
+       </faitemplatetabs>
+
+       <faiprofiletabs>
+               <tab class="faiProfile" name="Profiles" />
+               <tab class="faiSummaryTab" name="Summary" />
+       </faiprofiletabs>
+
+       <faipackagetabs>
+               <tab class="faiPackage" name="Packages" />
+       </faipackagetabs>
+-->
+{/if}
+
+       <logtabs>
+                       <tab class="logview" name="System logs" />
+                       <tab class="gosa_logview" name="GOsa logs" />
+       </logtabs>
+       
+       <main default="{$cv.location}"
+{if $cv.optional.list_summary}
+               list_summary="true"
+{else}
+               list_summary="false"
+{/if}
+{if $cv.pwd_rules.pwminlen_active}
+               pwminlen="{$cv.pwd_rules.pwminlen}"
+{/if}
+{if $cv.pwd_rules.pwdiffer_active}
+               pwdiffer="{$cv.pwd_rules.pwdiffer}"
+{/if}
+{if $cv.pwd_rules.externalpwdhook_active}
+               externalpwdhook="{$cv.pwd_rules.externalpwdhook}"
+{/if}
+{if $cv.errorlvl}
+               displayerrors="true"
+{else}
+               displayerrors="false"
+{/if}
+{if $cv.enable_schema_check}
+               schema_check="true"
+{else}
+               schema_check="false"
+{/if}
+{if $cv.generic_settings.enableCopyPaste}
+               enableCopyPaste="true"
+{else}
+               enableCopyPaste="false"
+{/if}
+{if $cv.optional.forceglobals}
+               forceglobals="true"
+{else}
+               forceglobals="false"
+{/if}
+{if $cv.optional.forcessl}
+               forcessl="true"
+{else}
+               forcessl="false"
+{/if}
+{if $cv.optional.ldapstats}
+               ldapstats="true"
+{else}
+               ldapstats="false"
+{/if}
+{if $cv.optional.warnssl}
+               warnssl="true"
+{else}
+               warnssl="false"
+{/if}
+{if $cv.optional.ppd_path_active}
+               ppd_path="{$cv.optional.ppd_path}"
+{/if}
+{if $cv.optional.max_ldap_query_time_active}   
+               max_ldap_query_time="{$cv.optional.max_ldap_query_time}"
+{/if}
+{if $cv.optional.noprimarygroup}
+               noprimarygroup="true"
+{/if}
+{if $cv.optional.mailQueueScriptPath_active}
+               mailQueueScriptPath="{$cv.optional.mailQueueScriptPath}"
+{/if}
+{if $cv.optional.auto_network_hook_active}
+               auto_network_hook="{$cv.optional.auto_network_hook} "
+{/if}
+{if $cv.optional.user_filter_cookie}
+               save_filter="true"
+{else}
+               save_filter="false"
+{/if}
+{if $cv.compressed}
+               compressed="true"
+{else}
+               compressed="false"
+{/if}
+{if $cv.optional.uniq_identifier_active }
+               uniq_identifier="{$cv.optional.uniq_identifier}"
+{else}
+               uniq_identifier=""
+{/if}
+               lang="{$cv.lang_selected}"
+               theme="{$cv.theme}"
+               session_lifetime="{$cv.optional.session_lifetime}"
+               compile="{$cv.optional.compile}"
+               debuglevel="{$cv.optional.debuglevel}"
+               smbhash='{$cv.samba_settings.smbhash}'
+               >
+
+               <location name="{$cv.location}"
+                       hash="{$cv.encryption}"
+                       dnmode="{$cv.peopledn}"
+                       server="{$cv.connection}"
+                       people="{$cv.peopleou}"
+                       groups="{$cv.groupou}"
+                       gidbase="{$cv.uidbase}"
+                       uidbase="{$cv.uidbase}"
+{if $cv.optional.login_attribute}
+                       login_attribute="{$cv.optional.login_attribute}"
+{else}
+                       login_attribute="uid"
+{/if}
+{if $cv.timezone}
+                       timezone="{$cv.timezone}"
+{/if}
+{if $cv.optional.strict_units}
+                       strict_units="true"
+{else}
+                       strict_units="false"
+{/if}
+{if $cv.krbsasl}
+                       krbsasl="true"
+{else}
+                       krbsasl="false"
+{/if}
+{if $cv.rfc2307bis}
+                       rfc2307bis="true"
+{else}
+                       rfc2307bis="false"
+{/if}
+{if $cv.include_personal_title}
+                       include_personal_title="true"
+{else}
+                       include_personal_title="false"
+{/if}
+{if $cv.optional.notifydir_active }
+                       notifydir="{$cv.optional.notifydir}"
+{/if}
+{if $cv.base_hook_active}
+                       base_hook="{$cv.base_hook}"
+{/if}
+{if $cv.generic_settings.wws_ou_active}
+                       winstations="{$cv.generic_settings.wws_ou}"
+{/if}
+{if $cv.id_settings.idgen_active}
+                       idgen="{$cv.id_settings.idgen}"
+{/if}
+{if $cv.strict}
+                       strict="yes"
+{else}
+                       strict="no"
+{/if}
+{if $cv.id_settings.minid_active}
+                       minid="{$cv.id_settings.minid}"
+{/if}
+{if $cv.mail != "disabled"}
+                       mailMethod="{$cv.mail}"
+{if $cv.cyrusunixstyle}
+                       cyrusunixstyle="true"
+{else}
+                       cyrusunixstyle="false"
+{/if}
+{if $cv.mail_settings.vacationdir_active}
+                       vacationdir="{$cv.mail_settings.vacationdir}"
+{/if}
+{/if}
+{if $cv.tls}
+                       tls="true"
+{/if}
+{if $cv.governmentmode}
+                       governmentmode="true"
+{else}
+                       governmentmode="false"
+{/if}
+{if $cv.sambaidmapping}
+                       sambaidmapping="true"
+{/if}
+{if $cv.account_expiration}
+                       account_expiration="true"
+{/if}
+{if $cv.samba_settings.samba_sid_active}
+                       SID="{$cv.samba_settings.samba_sid}"
+{/if}
+{if $cv.samba_settings.samba_rid_active}
+                       RIDBASE="{$cv.samba_settings.samba_rid_active}"
+{/if}
+{if $cv.generic_settings.snapshot_active}      
+                       enable_snapshot="true"
+{if $cv.generic_settings.snapshot_base != ""}
+                       snapshot_base="{$cv.generic_settings.snapshot_base}"
+{/if}
+{if $cv.generic_settings.snapshot_user != ""}
+                       snapshot_user="{$cv.generic_settings.snapshot_user}"
+{/if}
+{if $cv.generic_settings.snapshot_password != ""}
+                       snapshot_password="{$cv.generic_settings.snapshot_password}"
+{/if}
+{if $cv.generic_settings.snapshot_server != ""}
+                       snapshot_server="{$cv.generic_settings.snapshot_server}"
+{/if}
+{/if}
+{if $cv.samba_version != 0}
+                       sambaversion="{$cv.samba_version}"
+{/if}
+                       config="ou=gosa,ou=configs,ou=systems,{$cv.base}">
+
+                       <referral url="{$cv.connection}/{$cv.base}"
+                               admin="{$cv.admin}"
+                               password="{$cv.password}" />
+               </location>
+       </main>
+</conf>
diff --git a/gosa-core/contrib/gosa.spec b/gosa-core/contrib/gosa.spec
new file mode 100644 (file)
index 0000000..a737bfa
--- /dev/null
@@ -0,0 +1,324 @@
+# Some sort of "detection" of suse
+%{?suse_version:%define suse 1}
+%{!?suse_version:%define suse 0}
+
+# Define Packagename, e.g.:
+# rpmbuild --rebuild --define 'sourcename gosa' gosa.srpm
+%{!?sourcename:%define sourcename %{name}-%{version}}
+
+#
+# Distribution
+#
+Summary:               Web Based LDAP Administration Program 
+Name:                  gosa
+Version:               2.5.99cvs
+Release:               1
+License:               GPL
+Source:                ftp://oss.GONICUS.de/pub/gosa/%{sourcename}.tar.bz2
+URL:                   http://oss.GONICUS.de/project/?group_id=6
+Group:                         System/Administration
+Vendor:                        GONICUS GmbH
+Packager:              Lars Scheiter <lars.scheiter@GONICUS.de>
+Buildarch:             noarch
+%if %{suse}
+Requires:              apache2,apache2-mod_php5,php5,php5-gd,php5-ldap,php5-mcrypt,php5-mysql,php5-imap,php5-iconv,php5-mbstring,php5-gettext,php5-session,ImageMagick
+%else
+Requires:              httpd,php,php-ldap,php-imap,php-snmp,php-mysql,php-mbstring,ImageMagick
+%endif
+BuildRoot:             %{_tmppath}/%{name}-%{version}-root
+BuildArch:             noarch
+
+%define confdir        /etc/%{name}
+
+%if %{suse}
+       %{echo:Building SuSE rpm}
+       %define apacheuser wwwrun
+       %define apachegroup root
+       %define webconf /etc/apache2/conf.d/
+       %define docdir /usr/share/doc/packages/gosa
+%else
+       %{echo:Building other rpm}
+       %define apacheuser apache 
+       %define apachegroup apache 
+       %define webconf /etc/httpd/conf.d/      
+       %define docdir /usr/share/doc/gosa-%{version}
+%endif
+
+%description
+GOsa is a combination of system-administrator and end-user web
+interface, designed to handle LDAP based setups.
+Provided is access to posix, shadow, samba, proxy, fax, and kerberos
+accounts. It is able to manage the postfix/cyrus server combination
+and can write user adapted sieve scripts.
+
+%package schema
+Group:                         System/Administration
+Summary:               Schema Definitions for the GOSA package
+%if %{suse}
+Requires:              openldap2 >= 2.1.22
+%else
+Requires:              openldap-servers >= 2.2.0
+%endif
+Obsoletes:             gosa-ldap
+
+%description schema
+Contains the Schema definition files for the GOSA admin package.
+
+%package mkntpasswd
+Group:                         System/Administration
+Summary:               Schema Definitions for the GOSA package
+%if %{suse}
+Requires:              perl-Crypt-SmbHash
+%else
+Requires:              perl-Crypt-SmbHash >= 0.02
+%endif
+
+%description mkntpasswd
+Wrapper Script around perl to create Samba Hashes on the fly, added for completeness only.
+If in doubt use sambas "native" mkntpwd tool to generate hashes for GOsa.
+
+%package help-en
+Group:                         System/Administration
+Summary:               English online manual for GOSA package
+Requires:              gosa >= %{version}
+
+%description help-en
+English online manual page for GOSA package
+
+%package help-de
+Group:                         System/Administration
+Summary:               German localized online manual for GOSA package
+Requires:              gosa >= %{version}
+
+%description help-de
+German localized online manual page for GOSA package
+
+%package help-fr
+Group:                         System/Administration
+Summary:               French localized online manual for GOSA package
+Requires:              gosa >= %{version}
+
+%description help-fr
+French localized online manual page for GOSA package
+
+%package help-nl
+Group:                         System/Administration
+Summary:               Dutch localized online manual for GOSA package
+Requires:              gosa >= %{version}
+
+%description help-nl
+Dutch localized online manual page for GOSA package
+
+%prep
+%setup -q -n %{sourcename}
+find . -depth -name CVS -type d | xargs rm -rf
+
+%build
+
+
+%install
+# Create buildroot
+mkdir -p %{buildroot}/usr/share/gosa
+
+# Copy
+DIRS="doc ihtml plugins html include locale setup"
+for i in $DIRS; do \
+  cp -ua $i %{buildroot}/usr/share/gosa/$i ; \
+done
+mkdir %{buildroot}/usr/bin
+cp bin/mkntpasswd %{buildroot}/usr/bin/
+
+# Create files for temporary stuff
+for i in compile config cache; do \
+  mkdir -p %{buildroot}/var/spool/gosa/$i ; \
+done
+
+# Cleanup manual dirs
+for i in admin devel; do \
+  rm -rf %{buildroot}/usr/share/gosa/doc/guide/$i ; \
+done
+
+# Remove (some) unneeded files
+for i in gen_locale.sh gen_online_help.sh gen_function_list.php update.sh; do \
+ rm -rf %{buildroot}/usr/share/gosa/$i ; \
+done
+
+# Cleanup lyx warnings
+find %{buildroot}/usr/share/gosa -name WARNINGS |xargs rm
+
+
+# Cleanup guide
+rm -rf %{buildroot}/usr/share/gosa/doc/guide/user/*/lyx-source
+
+
+# Copy default config
+mkdir -p %{buildroot}%{confdir}
+mkdir -p %{buildroot}%{webconf}
+
+cat > %{buildroot}%{webconf}/gosa_include.conf <<EOF
+# Just to be sure
+<Directory "/usr/share/gosa/html">
+       Options None
+       AllowOverride None
+       Order allow,deny
+       Allow from all
+</Directory>
+# Set alias to gosa
+Alias /gosa /usr/share/gosa/html
+EOF
+
+mkdir -p %{buildroot}/etc/openldap/schema/gosa
+mv contrib/openldap/*.schema %{buildroot}/etc/openldap/schema/gosa
+sed 's%"CONFIG_TEMPLATE_DIR", "../contrib/"%"CONFIG_TEMPLATE_DIR", "%{docdir}/"%g' %{buildroot}/usr/share/gosa/include/functions.inc > %{buildroot}/usr/share/gosa/include/functions.inc.new
+mv -f %{buildroot}/usr/share/gosa/include/functions.inc.new %{buildroot}/usr/share/gosa/include/functions.inc
+
+mv -f doc manual
+mkdir -p %{buildroot}/etc/gosa/vacation
+mv -f %{buildroot}/usr/share/gosa/plugins/personal/mail/sieve-*.txt %{buildroot}/etc/gosa
+mkdir -p %{buildroot}/usr/share/doc/gosa-%{version}
+rm -rf %{buildroot}/usr/share/gosa/contrib
+#rm -rf %{buildroot}/usr/share/gosa/doc
+#rmdir contrib/openldap
+bzip2 -9 contrib/opensides/goSamba.pl
+
+%clean
+rm -rf %{buildroot}
+
+%post
+# Add shells file to /etc/gosa 
+/bin/cp /etc/shells /etc/gosa
+
+%pre
+# Cleanup compile dir on updates, always exit cleanly even on errors
+[ -d /var/spool/gosa ] && rm -rf /var/spool/gosa/* ; exit 0
+
+%postun
+# Remove temporary files, just to be sure
+[ -d /var/spool/gosa ] && rm -rf /var/spool/gosa/* ; exit 0
+
+%files
+%defattr(-,%{apacheuser},%{apachegroup})
+%doc %attr(-,root,root) AUTHORS TODO README README.safemode Changelog COPYING INSTALL FAQ
+%doc %attr(-,root,root) contrib/altlinux contrib/fix_config.sh contrib/gosa.conf contrib/mysql contrib/opensides
+%doc %attr(-,root,root) contrib/patches contrib/scripts contrib/vacation_example.txt contrib/demo.ldif contrib/openldap
+
+%config(noreplace) %attr(0600,%{apacheuser},%{apachegroup}) %{webconf}/gosa_include.conf
+%config(noreplace) %attr(0700,%{apacheuser},%{apachegroup}) /etc/gosa
+%attr(0700, %{apacheuser}, %{apachegroup}) /var/spool/gosa
+%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/html
+%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/ihtml
+%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/include
+%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/locale
+%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/setup
+%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/plugins
+%attr(0744, %{apacheuser}, %{apachegroup}) /usr/share/gosa/doc/guide.xml
+
+%files schema
+%defattr(-,root,root)
+%doc COPYING AUTHORS README contrib/demo.ldif contrib/openldap
+/etc/openldap/schema/gosa
+
+%files mkntpasswd
+%defattr(-,root,root)
+/usr/bin/mkntpasswd
+
+%files help-en
+%defattr(-,root,root)
+/usr/share/gosa/doc/guide/user/en
+
+%files help-de
+%defattr(-,root,root)
+/usr/share/gosa/doc/guide/user/de
+
+%files help-fr
+%defattr(-,root,root)
+/usr/share/gosa/doc/guide/user/fr
+
+%files help-nl
+%defattr(-,root,root)
+/usr/share/gosa/doc/guide/user/nl
+
+%changelog
+* Mon May 7 2007 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.99cvs
+- Changed packageversion to reflect CVS status of resulting build
+
+* Wed Apr 11 2007 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.10
+- New upstream
+- Added new subpackage mkntpasswd
+- Remove perl dependencies off of GOsa main package
+
+* Tue Mar 6 2007 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.9
+- New upstream
+- fixed typo in updateprocess
+
+* Mon Jan 15 2007 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.8
+- New upstream release with security fixes
+
+* Wed Dec 20 2006 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.7
+- New upstream
+- %pre and %postun always end successfully now, even on errors
+
+* Fri Nov 17 2006 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.6
+- New upstream
+- Cleanup temporary dir after package removal
+- Cleanup temporary dir before update
+
+* Thu Sep 28 2006 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.4
+- New upstream version
+- Downgraded SuSE dependencies to php4
+
+* Wed Jun 21 2006 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5.1
+- New upstream version
+
+* Tue May 30 2006 Lars Scheiter <lars.scheiter@GONICUS.de> 2.5
+- Updated RedHat dependencies
+- New upstream version
+- Spelling errors fixed ;)
+- Seperation of online manual
+
+* Mon Dec 19 2005 Lars Scheiter <lars.scheiter@GONICUS.de> 2.4-2
+- Updated SuSE dependencies to php5
+
+* Mon Nov 21 2005 Lars Scheiter <lars.scheiter@GONICUS.de> 2.4
+- New upstream version
+- Removed %doc for postgresql and openexchange
+
+* Wed Jun 01 2005 Lars Scheiter <lars.scheiter@GONICUS.de> 2.4beta1
+- New upstream version
+- Added gosa.conf to contrib dir
+- Rearranged documentation stuff
+- Updated dependencies
+- compress some files
+
+* Mon Feb 21 2005 Lars Scheiter <lars.scheiter@GONICUS.de> 2.3
+- Update version to 2.3 (upstream)
+
+* Mon Dec 13 2004 Lars Scheiter <lars.scheiter@GONICUS.de> 2.2-2
+- Optionally allow different sourcenames
+
+* Mon Nov 22 2004 Lars Scheiter <lars.scheiter@GONICUS.de> 2.2
+- Update to 2.2 (upstream)
+- reintroduction of suse detection
+- small fixes
+- Corrected URL
+- Synchronize schema package name with debian
+
+* Mon May 19 2004 Levente Farkas <lfarkas@lfarkas.org> 2.1.1
+- update to 2.1.1
+
+* Mon Apr 19 2004 Levente Farkas <lfarkas@lfarkas.org> 2.1
+- update to 2.1
+
+* Fri Apr 16 2004 Levente Farkas <lfarkas@lfarkas.org> 2.1
+- minor fixes
+- update to 2.1rc2
+
+* Tue Jan 24 2004 Henning P. Schmiedehausen <hps@intermeta.de> 2.1-2t
+- bumped to 2.1beta2
+- first INTERMETA internal build
+
+* Mon Oct 20 2003 Lars Scheiter <lars.scheiter@GONICUS.de>
+- Update to new upstream release (2.0rc1)
+
+* Fri Oct 17 2003 Lars Scheiter <lars.scheiter@GONICUS.de>
+- First build of GOsa as an RPM, should work on SuSE and RedHat
diff --git a/gosa-core/contrib/keyboardLayouts b/gosa-core/contrib/keyboardLayouts
new file mode 100644 (file)
index 0000000..ca28248
--- /dev/null
@@ -0,0 +1,7 @@
+# Left side will be saved in ldap attribute
+# Right side will be displayed in the selectbox
+# (Terminal Workstation -> Services -> Keyboard )
+a:1
+b:2
+c:3
+d:4
diff --git a/gosa-core/contrib/latex2html b/gosa-core/contrib/latex2html
new file mode 100755 (executable)
index 0000000..5b4e3f7
--- /dev/null
@@ -0,0 +1,17413 @@
+#! /usr/bin/perl
+#
+# $Id: latex2html.pin,v 1.71 2004/01/06 23:49:54 RRM Exp $
+#
+# Comprises patches and revisions by various authors:
+#   See Changes, the log file of LaTeX2HTML.
+#
+# Original Copyright notice:
+#
+# LaTeX2HTML by Nikos Drakos <nikos@cbl.leeds.ac.uk>
+
+# ****************************************************************
+# LaTeX To HTML Translation **************************************
+# ****************************************************************
+# LaTeX2HTML is a Perl program that translates LaTeX source
+# files into HTML (HyperText Markup Language). For each source
+# file given as an argument the translator will create a
+# directory containing the corresponding HTML files.
+#
+# The man page for this program is included at the end of this file
+# and can be viewed using "perldoc latex2html"
+#
+# For more information on this program and some examples of its
+# capabilities visit 
+#
+#          http://www.latex2html.org/
+#
+# or see the accompanying documentation in the docs/  directory
+#
+# or
+#
+#    http://www-texdev.ics.mq.edu.au/l2h/docs/manual/
+#
+# or
+#
+#    http://www.cbl.leeds.ac.uk/nikos/tex2html/doc/latex2html/
+#
+# Original code written by Nikos Drakos, July 1993.
+#
+# Address: Computer Based Learning Unit
+#          University of Leeds
+#          Leeds,  LS2 9JT
+#
+# Copyright (c) 1993-95. All rights reserved.
+#
+#
+# Extensively modified by Ross Moore, Herb Swan and others
+#
+# Address: Mathematics Department
+#          Macquarie University
+#          Sydney, Australia, 2109 
+#
+# Copyright (c) 1996-2001. All rights reserved.
+#
+# See general license in the LICENSE file.
+#
+##########################################################################
+
+use 5.003; # refuse to work with old and buggy perl version
+#use strict;
+#use diagnostics;
+
+# include some perl packages; these come with the standard distribution
+use Getopt::Long;
+use Fcntl;
+use AnyDBM_File;
+
+# The following are global variables that also appear in some modules
+use vars qw($LATEX2HTMLDIR $LATEX2HTMLPLATDIR $SCRIPT
+            %Month %used_icons $inside_tabbing $TABLE_attribs
+            %mathentities $date_name $outer_math $TABLE__CELLPADDING_rx);
+
+BEGIN {
+  # print "scanning for l2hdir\n";
+  if($ENV{'LATEX2HTMLDIR'}) {
+    $LATEX2HTMLDIR = $ENV{'LATEX2HTMLDIR'};
+  } else {
+    $ENV{'LATEX2HTMLDIR'} = $LATEX2HTMLDIR = '/usr/share/latex2html';
+  }
+
+  if($ENV{'LATEX2HTMLPLATDIR'}) {
+    $LATEX2HTMLPLATDIR = $ENV{'LATEX2HTMLPLATDIR'};
+  } else {
+    $LATEX2HTMLPLATDIR = '/usr/share/latex2html'||$LATEX2HTMLDIR;
+    $ENV{'LATEX2HTMLPLATDIR'} = $LATEX2HTMLPLATDIR;
+  }
+  if(-d $LATEX2HTMLPLATDIR) {
+    push(@INC,$LATEX2HTMLPLATDIR);
+  }
+
+  if(-d $LATEX2HTMLDIR) {
+    push(@INC,$LATEX2HTMLDIR);
+  } else {
+    die qq{Fatal: Directory "$LATEX2HTMLDIR" does not exist.\n};
+  }
+}
+
+use L2hos; # Operating system dependent routines
+
+# $^W = 1; # turn on warnings
+
+my $RELEASE = '2002-2-1';
+my ($REVISION) = q$Revision: 1.71 $ =~ /:\s*(\S+)/;
+
+# The key, which delimts expressions defined in the environment
+# depends on the operating system. 
+$envkey = L2hos->pathd();
+
+# $dd is the directory delimiter character
+$dd = L2hos->dd();
+
+# make sure the $LATEX2HTMLDIR is on the search-path for forked processes
+if($ENV{'PERL5LIB'}) {
+  $ENV{'PERL5LIB'} .= "$envkey$LATEX2HTMLDIR"
+    unless($ENV{'PERL5LIB'} =~ m|\Q$LATEX2HTMLDIR\E|o);
+} else {
+  $ENV{'PERL5LIB'} = $LATEX2HTMLDIR;
+}
+
+# Local configuration, read at runtime
+# Read the $CONFIG_FILE  (usually l2hconf.pm )
+if($ENV{'L2HCONFIG'}) {
+  require $ENV{'L2HCONFIG'} ||
+    die "Fatal (require $ENV{'L2HCONFIG'}): $!";
+} else {
+  eval 'use l2hconf';
+  if($@) {
+    die "Fatal (use l2hconf): $@\n";
+  }
+}
+
+# MRO: Changed this to global value in config/config.pl
+# change these whenever you do a patch to this program and then
+# name the resulting patch file accordingly
+# $TVERSION = "2002-2-1";
+#$TPATCHLEVEL = " beta";
+#$TPATCHLEVEL = " release";
+#$RELDATE = "(March 30, 1999)";
+#$TEX2HTMLV_SHORT = $TVERSION . $TPATCHLEVEL;
+
+$TEX2HTMLV_SHORT = $RELEASE;
+$TEX2HTMLVERSION = "$TEX2HTMLV_SHORT ($REVISION)";
+$TEX2HTMLADDRESS = "http://www.latex2html.org/";
+$AUTHORADDRESS = "http://cbl.leeds.ac.uk/nikos/personal.html";
+#$AUTHORADDRESS2 = "http://www-math.mpce.mq.edu.au/%7Eross/";
+$AUTHORADDRESS2 = "http://www.maths.mq.edu.au/&#126;ross/";
+
+# Set $HOME to what the system considers the home directory
+$HOME = L2hos->home();
+push(@INC,$HOME);
+
+# flush stdout with every print -- gives better feedback during
+# long computations
+$| = 1;
+
+# set Perl's subscript separator to LaTeX's illegal character.
+# (quite defensive but why not)
+$; = "\000";
+
+# No arguments!!
+unless(@ARGV) {
+  die "Error: No files to process!\n";
+}
+
+# Image prefix
+$IMAGE_PREFIX = '_image';
+
+# Partition prefix 
+$PARTITION_PREFIX = 'part_' unless $PARTITION_PREFIX;
+
+# Author address
+@address_data = &address_data('ISO');
+$ADDRESS = "$address_data[0]\n$address_data[1]";
+
+# ensure non-zero defaults
+$MAX_SPLIT_DEPTH = 4 unless ($MAX_SPLIT_DEPTH);
+$MAX_LINK_DEPTH = 4 unless ($MAX_LINK_DEPTH);
+$TOC_DEPTH = 4 unless ($TOC_DEPTH);
+
+# A global value may already be set in the $CONFIG_FILE
+$INIT_FILE_NAME = $ENV{'L2HINIT_NAME'} || '.latex2html-init'
+   unless $INIT_FILE_NAME;
+
+# Read the $HOME/$INIT_FILE_NAME if one is found
+if (-f "$HOME$dd$INIT_FILE_NAME" && -r _) {
+    print "Note: Loading $HOME$dd$INIT_FILE_NAME\n";
+    require("$HOME$dd$INIT_FILE_NAME");
+    $INIT_FILE = "$HOME$dd$INIT_FILE_NAME";
+    # _MRO_TODO_: Introduce a version to be checked?
+    die "Error: You have an out-of-date " . $HOME .
+       "$dd$INIT_FILE_NAME file.\nPlease update or delete it.\n"
+       if ($DESTDIR eq '.');
+}
+
+# Read the $INIT_FILE_NAME file if one is found in current directory
+if ( L2hos->Cwd() ne $HOME && -f ".$dd$INIT_FILE_NAME" && -r _) {
+    print "Note: Loading .$dd$INIT_FILE_NAME\n";
+    require(".$dd$INIT_FILE_NAME");
+    $INIT_FILE = "$INIT_FILE_NAME";
+}
+die "Error: '.' is an incorrect setting for DESTDIR.\n" .
+    "Please check your $INIT_FILE_NAME file.\n"
+    if ($DESTDIR eq '.');
+
+# User home substitutions
+$LATEX2HTMLSTYLES =~ s/~([$dd$dd$envkey]|$)/$HOME$1/go;
+# the next line fails utterly on non-UNIX systems
+$LATEX2HTMLSTYLES =~ s/~([^$dd$dd$envkey]+)/L2hos->home($1)/geo;
+
+#absolutise the paths
+$LATEX2HTMLSTYLES = join($envkey,
+                        map(L2hos->Make_directory_absolute($_),
+                                split(/$envkey/o, $LATEX2HTMLSTYLES)));
+
+#HWS:  That was the last reference to HOME.  Now set HOME to $LATEX2HTMLDIR,
+#      to enable dvips to see that version of .dvipsrc!  But only if we
+#      have DVIPS_MODE not set - yes - this is a horrible nasty kludge
+# MRO: The file has to be updated by configure _MRO_TODO_
+
+if ($PK_GENERATION && ! $DVIPS_MODE) {
+    $ENV{HOME} =  $LATEX2HTMLDIR;
+    delete $ENV{PRINTER}; # Overrides .dvipsrc
+}
+
+# language of the DTD specified in the <DOCTYPE...> tag
+$ISO_LANGUAGE = 'EN' unless $ISO_LANGUAGE;
+
+# Save the command line arguments, quote where necessary
+$argv = join(' ', map {/[\s#*!\$%]/ ? "'$_'" : $_ } @ARGV);
+
+# Pre-process the command line for backward compatibility
+foreach(@ARGV) {
+  s/^--?no_/-no/; # replace e.g. no_fork by nofork
+  # s/^[+](\d+)$/$1/; # remove + in front of integers
+}
+
+# Process command line options
+my %opt;
+unless(GetOptions(\%opt, # all non-linked options go into %opt
+        # option                linkage (optional)
+        'help|h',
+        'version|V',
+        'split=s',
+        'link=s',
+        'toc_depth=i',          \$TOC_DEPTH,
+        'toc_stars!',           \$TOC_STARS,
+        'short_extn!',          \$SHORTEXTN,
+        'iso_language=s',       \$ISO_LANGUAGE,
+        'validate!',            \$HTML_VALIDATE,
+        'latex!',
+        'djgpp!',               \$DJGPP,
+        'fork!',                \$CAN_FORK,
+        'external_images!',     \$EXTERNAL_IMAGES,
+        'ascii_mode!',          \$ASCII_MODE,
+        'lcase_tags!',          \$LOWER_CASE_TAGS,
+        'ps_images!',           \$PS_IMAGES,
+        'font_size=s',          \$FONT_SIZE,
+        'tex_defs!',            \$TEXDEFS,
+        'navigation!',
+        'top_navigation!',      \$TOP_NAVIGATION,
+        'bottom_navigation!',   \$BOTTOM_NAVIGATION,
+        'auto_navigation!',     \$AUTO_NAVIGATION,
+        'index_in_navigation!', \$INDEX_IN_NAVIGATION,
+        'contents_in_navigation!', \$CONTENTS_IN_NAVIGATION,
+        'next_page_in_navigation!', \$NEXT_PAGE_IN_NAVIGATION,
+        'previous_page_in_navigation!', \$PREVIOUS_PAGE_IN_NAVIGATION,
+        'footnode!',
+        'numbered_footnotes!',  \$NUMBERED_FOOTNOTES,
+        'prefix=s',             \$PREFIX,
+        'auto_prefix!',         \$AUTO_PREFIX,
+        'long_titles=i',        \$LONG_TITLES,
+        'custom_titles!',       \$CUSTOM_TITLES,
+        'title|t=s',            \$TITLE,
+        'rooted!',              \$ROOTED,
+        'rootdir=s',
+        'dir=s',                \$FIXEDDIR,
+        'mkdir',                \$MKDIR,
+        'address=s',            \$ADDRESS,
+        'noaddress',
+        'subdir!',
+        'info=s',               \$INFO,
+        'noinfo',
+        'auto_link!',
+        'reuse=i',              \$REUSE,
+        'noreuse',
+        'antialias_text!',      \$ANTI_ALIAS_TEXT,
+        'antialias!',           \$ANTI_ALIAS,
+        'transparent!',         \$TRANSPARENT_FIGURES,
+        'white!',               \$WHITE_BACKGROUND,
+        'discard!',             \$DISCARD_PS,
+        'image_type=s',         \$IMAGE_TYPE,
+        'images!',
+        'accent_images=s',      \$ACCENT_IMAGES,
+        'noaccent_images',
+        'style=s',              \$STYLESHEET,
+        'parbox_images!',
+        'math!',
+        'math_parsing!',
+        'latin!',
+        'entities!',            \$USE_ENTITY_NAMES,
+        'local_icons!',         \$LOCAL_ICONS,
+        'scalable_fonts!',      \$SCALABLE_FONTS,
+        'images_only!',         \$IMAGES_ONLY,
+        'show_section_numbers!',\$SHOW_SECTION_NUMBERS,
+        'show_init!',           \$SHOW_INIT_FILE,
+        'init_file=s',          \$INIT_FILE,
+        'up_url=s',             \$EXTERNAL_UP_LINK,
+        'up_title=s',           \$EXTERNAL_UP_TITLE,
+        'down_url=s',           \$EXTERNAL_DOWN_LINK,
+        'down_title=s',         \$EXTERNAL_DOWN_TITLE,
+        'prev_url=s',           \$EXTERNAL_PREV_LINK,
+        'prev_title=s',         \$EXTERNAL_PREV_TITLE,
+        'index=s',              \$EXTERNAL_INDEX,
+        'biblio=s',             \$EXTERNAL_BIBLIO,
+        'contents=s',           \$EXTERNAL_CONTENTS,
+        'external_file=s',      \$EXTERNAL_FILE,
+        'short_index!',         \$SHORT_INDEX,
+        'unsegment!',           \$UNSEGMENT,
+        'debug!',               \$DEBUG,
+        'tmp=s',                \$TMP,
+        'ldump!',               \$LATEX_DUMP,
+        'timing!',              \$TIMING,
+        'verbosity=i',          \$VERBOSITY,
+        'html_version=s',       \$HTML_VERSION,
+        'strict!',              \$STRICT_HTML,
+        'xbit!',                \$XBIT_HACK,
+        'ssi!',                 \$ALLOW_SSI,
+        'php!',                 \$ALLOW_PHP,
+        'test_mode!' # undocumented switch
+       )) {
+    &usage();
+    exit 1;
+}
+
+# interpret options, check option consistency
+if(defined $opt{'split'}) {
+    if ($opt{'split'} =~ /^(\+?)(\d+)$/) {
+        $MAX_SPLIT_DEPTH = $2;
+        if ($1) { $MAX_SPLIT_DEPTH *= -1; $REL_DEPTH = 1; }
+    } else { 
+        &usage;
+        die "Error: Unrecognised value for -split: $opt{'split'}\n";
+    }
+}
+if(defined $opt{'link'}) {
+    if ($opt{'link'} =~ /^(\+?)(\d+)$/) {
+        $MAX_LINK_DEPTH = $2;
+        if ($1) { $MAX_LINK_DEPTH *= -1 }
+    } else { 
+        &usage;
+        die "Error: Unrecognised value for -link: $opt{'link'}\n";
+    }
+}
+unless ($ISO_LANGUAGE =~ /^[A-Z.]+$/) {
+    die "Error: Language (-iso_language) must be uppercase and dots only: $ISO_LANGUAGE\n";
+}
+if ($HTML_VALIDATE && !$HTML_VALIDATOR) {
+    die "Error: Need a HTML_VALIDATOR when -validate is specified.\n";
+}
+&set_if_false($NOLATEX,$opt{latex}); # negate the option...
+if ($ASCII_MODE || $PS_IMAGES) {
+    $EXTERNAL_IMAGES = 1;
+}
+if ($FONT_SIZE && $FONT_SIZE !~ /^\d+pt$/) {
+    die "Error: Font size (-font_size) must end with 'pt': $FONT_SIZE\n"
+}
+&set_if_false($NO_NAVIGATION,$opt{navigation});
+&set_if_false($NO_FOOTNODE,$opt{footnode});
+if (defined $TITLE && !length($TITLE)) {
+    die "Error: Empty title (-title).\n";
+}
+if ($opt{rootdir}) {
+    $ROOTED = 1;
+    $FIXEDDIR = $opt{rootdir};
+}
+if ($FIXEDDIR && !-d $FIXEDDIR) {
+    if ($MKDIR) {
+       print "\n *** creating directory: $FIXEDDIR ";
+       die "Failed: $!\n" unless (mkdir($FIXEDDIR, 0755));
+        # _TODO_ use File::Path to create a series of directories
+    } else {
+       &usage;
+       die "Error: Specified directory (-rootdir, -dir) does not exist.\n";
+    }
+}
+&set_if_false($NO_SUBDIR, $opt{subdir});
+&set_if_false($NO_AUTO_LINK, $opt{auto_link});
+if ($opt{noreuse}) {
+    $REUSE = 0;
+}
+unless(grep(/^\Q$IMAGE_TYPE\E$/o, @IMAGE_TYPES)) {
+    die <<"EOF";
+Error: No such image type '$IMAGE_TYPE'.
+       This installation supports (first is default): @IMAGE_TYPES
+EOF
+}
+&set_if_false($NO_IMAGES, $opt{images});
+if ($opt{noaccent_images}) {
+    $ACCENT_IMAGES = '';
+}
+if($opt{noaddress}) {
+    $ADDRESS = '';
+}
+if($opt{noinfo}) {
+    $INFO = 0;
+}
+if($ACCENT_IMAGES && $ACCENT_IMAGES !~ /^[a-zA-Z,]+$/) {
+    die "Error: Single word or comma-list of style words needed for -accent_images, not: $_\n";
+}
+&set_if_false($NO_PARBOX_IMAGES, $opt{parbox_images});
+&set_if_false($NO_SIMPLE_MATH, $opt{math});
+if (defined $opt{math_parsing}) {
+    $NO_MATH_PARSING = !$opt{math_parsing};
+    $NO_SIMPLE_MATH = !$opt{math_parsing} unless(defined $opt{math});
+}
+&set_if_false($NO_ISOLATIN, $opt{latin});
+if ($INIT_FILE) {
+    if (-f $INIT_FILE && -r _) {
+        print "Note: Initialising with file: $INIT_FILE\n"
+            if ($DEBUG || $VERBOSITY);
+        require($INIT_FILE);
+    } else {
+        die "Error: Could not find file (-init_file): $INIT_FILE\n";
+    }
+}
+foreach($EXTERNAL_UP_LINK, $EXTERNAL_DOWN_LINK, $EXTERNAL_PREV_LINK,
+        $EXTERNAL_INDEX, $EXTERNAL_BIBLIO, $EXTERNAL_CONTENTS) {
+    $_ ||= ''; # initialize
+    s/~/&#126;/g; # protect `~'
+}
+if($TMP && !(-d $TMP && -w _)) {
+    die "Error: '$TMP' not usable as temporary directory.\n";
+}
+if ($opt{help}) {
+    L2hos->perldoc($SCRIPT);
+    exit 0;
+}
+if ($opt{version}) {
+    &banner();
+    exit 0;
+}
+if ($opt{test_mode}) {
+    return; # make /usr/bin/latex2html non-exploitable
+    $TITLE = 'LaTeX2HTML Test Document';
+    $TEXEXPAND = "$PERL /build/buildd/latex2html-2002-2-1-20050114${dd}texexpand";
+    $PSTOIMG   = "$PERL /build/buildd/latex2html-2002-2-1-20050114${dd}pstoimg";
+    $ICONSERVER = L2hos->path2URL("/build/buildd/latex2html-2002-2-1-20050114${dd}icons");
+    $TEST_MODE  = 1;
+    $RGBCOLORFILE = "/build/buildd/latex2html-2002-2-1-20050114${dd}styles${dd}rgb.txt";
+    $CRAYOLAFILE = "/build/buildd/latex2html-2002-2-1-20050114${dd}styles${dd}crayola.txt";
+}
+if($DEBUG) {
+    # make the OS-dependent functions more chatty, too
+    $L2hos::Verbose = 1;
+}
+
+undef %opt; # not needed any more
+
+
+$FIXEDDIR = $FIXEDDIR || $DESTDIR || '';  # for backward compatibility
+
+if ($EXTERNAL_UP_TITLE xor $EXTERNAL_UP_LINK) {
+    warn "Warning (-up_url, -up_title): Need to specify both a parent URL and a parent title!\n";
+    $EXTERNAL_UP_TITLE = $EXTERNAL_UP_LINK = "";
+}
+
+if ($EXTERNAL_DOWN_TITLE xor $EXTERNAL_DOWN_LINK) {
+    warn "Warning (-down_url, -down_title): Need to specify both a parent URL and a parent title!\n";
+    $EXTERNAL_DOWN_TITLE = $EXTERNAL_DOWN_LINK = "";
+}
+
+# $NO_NAVIGATION = 1 unless $MAX_SPLIT_DEPTH;  #  Martin Wilck
+
+if ($MAX_SPLIT_DEPTH && $MAX_SPLIT_DEPTH < 0) {
+    $MAX_SPLIT_DEPTH *= -1; $REL_DEPTH = 1;
+}
+if ($MAX_LINK_DEPTH && $MAX_LINK_DEPTH < 0) {
+    $MAX_LINK_DEPTH *= -1; $LEAF_LINKS = 1;
+}
+
+$FOOT_FILENAME = 'footnode' unless ($FOOT_FILENAME);
+$NO_FOOTNODE = 1 unless ($MAX_SPLIT_DEPTH || $NO_FOOTNODE);
+$NO_SPLIT = 1 unless $MAX_SPLIT_DEPTH; # _MRO_TODO_: is this needed at all?
+$SEGMENT = $SEGMENTED = 0;
+$NO_MATH_MARKUP = 1;
+
+# specify the filename extension to use with the generated HTML files
+if ($SHORTEXTN) { $EXTN = ".htm"; }    # for HTML files on CDROM
+elsif ($ALLOW_PHP) { $EXTN = ".php"; }  # has PHP dynamic includes
+       # with server-side includes (SSI) :
+elsif ($ALLOW_SSI && !$XBIT_HACK) { $EXTN = ".shtml"; }
+       # ordinary names, valid also for SSI with XBit hack :
+else { $EXTN = ".html"; }
+
+$NODE_NAME = 'node' unless (defined $NODE_NAME);
+
+# space for temporary files
+# different to the $TMPDIR for image-generation
+# MRO: No directory should end with $dd!
+$TMP_ = "TMP";
+
+$TMP_PREFIX = "l2h" unless ($TMP_PREFIX);
+
+# This can be set to 1 when using a version of dvips that is safe
+# from the "dot-in-name" bug.
+# _TODO_ this should be determined by configure
+$DVIPS_SAFE = 1;
+
+$CHARSET = $charset || 'iso-8859-1';
+
+####################################################################
+#
+# If possible, use icons of the same type as generated images
+#
+if ($IMAGE_TYPE && defined %{"icons_$IMAGE_TYPE"}) {
+    %icons = %{"icons_$IMAGE_TYPE"};
+}
+
+####################################################################
+#
+# Figure out what options we need to pass to DVIPS and store that in
+# the $DVIPSOPT variable.  Also, scaling is taken care of at the
+# dvips level if PK_GENERATION is set to 1, so adjust SCALE_FACTORs
+# accordingly.
+#
+if ($SCALABLE_FONTS) {
+    $PK_GENERATION = 0;
+    $DVIPS_MODE = '';
+}
+
+if ($PK_GENERATION) {
+    if ($MATH_SCALE_FACTOR <= 0) { $MATH_SCALE_FACTOR = 2; }
+    if ($FIGURE_SCALE_FACTOR <= 0) { $FIGURE_SCALE_FACTOR = 2; }
+    my $saveMSF = $MATH_SCALE_FACTOR;
+    my $saveFSF = $FIGURE_SCALE_FACTOR;
+    my $desired_dpi = int($MATH_SCALE_FACTOR*75);
+    $FIGURE_SCALE_FACTOR = ($METAFONT_DPI / 72) *
+       ($FIGURE_SCALE_FACTOR / $MATH_SCALE_FACTOR) ;
+    $MATH_SCALE_FACTOR = $METAFONT_DPI / 72;
+    $dvi_mag = int(1000 * $desired_dpi / $METAFONT_DPI);
+    if ($dvi_mag > 1000) {
+       &write_warnings(
+           "WARNING: Your SCALE FACTOR is too large for PK_GENERATION.\n" .
+           "         See $CONFIG_FILE for more information.\n");
+    }
+
+    # RRM: over-sized scaling, using dvi-magnification
+    if ($EXTRA_IMAGE_SCALE) {
+       print "\n *** Images at $EXTRA_IMAGE_SCALE times resolution of displayed size ***\n";
+       $desired_dpi = int($EXTRA_IMAGE_SCALE * $desired_dpi+.5);
+       print "    desired_dpi = $desired_dpi  METAFONT_DPI = $METAFONT_DPI\n"
+            if $DEBUG;
+       $dvi_mag = int(1000 * $desired_dpi / $METAFONT_DPI);
+       $MATH_SCALE_FACTOR = $saveMSF;
+       $FIGURE_SCALE_FACTOR = $saveFSF;
+    }
+    # no space after "-y", "-D", "-e" --- required by DVIPS under DOS !
+    my $mode_switch = "-mode $DVIPS_MODE" if $DVIPS_MODE;
+    $DVIPSOPT .= " -y$dvi_mag -D$METAFONT_DPI $mode_switch -e5 ";
+} else { # no PK_GENERATION
+#    if ($EXTRA_IMAGE_SCALE) {
+#      &write_warnings(
+#         "the \$EXTRA_IMAGE_SCALE feature requires either \$PK_GENERATION=1"
+#                      . " or the '-scalable_fonts' option");
+#      $EXTRA_IMAGE_SCALE = '';
+#    }
+    # MRO: shifted to l2hconf
+    #$DVIPSOPT .= ' -M';
+} # end PK_GENERATION
+
+# The mapping from numbers to accents.
+# These are required to process the \accent command, which is found in
+# tables of contents whenever there is an accented character in a
+# caption or section title.  Processing the \accent command makes
+# $encoded_*_number work properly (see &extract_captions) with
+# captions that contain accented characters.
+# I got the numbers from the plain.tex file, version 3.141.
+
+# Missing entries should be looked up by a native speaker.
+# Have a look at generate_accent_commands and $iso_8859_1_character_map.
+
+# MEH: added more accent types
+# MRO: only uppercase needed!
+%accent_type = (
+   '18' => 'grave',            # \`
+   '19' => 'acute',            # `'
+   '20' => 'caron',            # \v
+   '21' => 'breve',            # \u
+   '22' => 'macr',             # \=
+   '23' => 'ring',             #
+   '24' => 'cedil',            # \c
+   '94' => 'circ',             # \^
+   '95' => 'dot',              # \.
+   '7D' => 'dblac',            # \H
+   '7E' => 'tilde',            # \~
+   '7F' => 'uml',              # \"
+);
+
+&driver;
+
+exit 0; # clean exit, no errors
+
+############################ Subroutines ##################################
+
+#check that $TMP is writable, if so create a subdirectory
+sub make_tmp_dir {
+    &close_dbm_database if $DJGPP; # to save file-handles
+
+    # determine a suitable temporary path
+    #
+    $TMPDIR = '';
+    my @tmp_try = ();
+    push(@tmp_try, $TMP) if($TMP);
+    push(@tmp_try, "$DESTDIR$dd$TMP_") if($TMP_);
+    push(@tmp_try, $DESTDIR) if($DESTDIR);
+    push(@tmp_try, L2hos->Cwd());
+
+    my $try;
+    TempTry: foreach $try (@tmp_try) {
+      next unless(-d $try && -w _);
+      my $tmp = "$try$dd$TMP_PREFIX$$";
+      if(mkdir($tmp,0755)) {
+        $TMPDIR=$tmp;
+       last TempTry;
+      } else {
+        warn "Warning: Cannot create temporary directory '$tmp': $!\n";
+      }
+    }
+
+    $dvips_warning = <<"EOF";
+
+Warning: There is a '.' in \$TMPDIR, $DVIPS will probably fail.
+Set \$TMP to use a /tmp directory, or rename the working directory.
+EOF
+    die ($dvips_warning . "\n\$TMPDIR=$TMPDIR  ***\n\n")
+       if ($TMPDIR =~ /\./ && $DVIPS =~ /dvips/ && !$DVIPS_SAFE);
+
+    &open_dbm_database if $DJGPP;
+}
+
+# MRO: set first parameter to the opposite of the second if second parameter is defined
+sub set_if_false {
+    $_[0] = !$_[1] if(defined $_[1]);
+}
+
+sub check_for_dots {
+    local($file) = @_;
+    if ($file =~ /\.[^.]*\./ && !$DVIPS_SAFE) {
+       die "\n\n\n *** Fatal Error --- but easy to fix ***\n"
+           . "\nCannot have '.' in file-name prefix, else dvips fails on images"
+           . "\nChange the name from  $file  and try again.\n\n";
+    }
+}
+
+# Process each file ...
+sub driver {
+    local($FILE, $orig_cwd, %unknown_commands, %dependent, %depends_on
+         , %styleID, %env_style, $bbl_cnt, $dbg, %numbered_section);
+    # MRO: $texfilepath has to be global!
+    local(%styles_loaded);
+    $orig_cwd = L2hos->Cwd();
+
+    print "\n *** initialise *** " if ($VERBOSITY > 1);
+    &initialise;               # Initialise some global variables
+
+    print "\n *** check modes *** " if ($VERBOSITY > 1);
+    &ascii_mode if $ASCII_MODE;        # Must come after initialization
+    &titles_language($TITLES_LANGUAGE);
+    &make_numbered_footnotes if ($NUMBERED_FOOTNOTES);
+    $dbg = $DEBUG ? "-debug" : "";
+    $dbg .= (($VERBOSITY>2) ? " -verbose" : "");
+
+    #use the same hashes for all files in a batch
+    local(%cached_env_img, %id_map, %symbolic_labels, %latex_labels)
+       if ($FIXEDDIR && $NO_SUBDIR);
+
+    local($MULTIPLE_FILES,$THIS_FILE);
+    $MULTIPLE_FILES = 1+$#ARGV if $ROOTED;
+    print "\n *** $MULTIPLE_FILES file".($MULTIPLE_FILES ? 's: ' : ': ')
+       . join(',',@ARGV) . " *** " if ($VERBOSITY > 1);
+
+    local(%section_info, %toc_section_info, %cite_info, %ref_files);
+    
+    foreach $FILE (@ARGV) {
+       &check_for_dots($FILE) unless $DVIPS_SAFE;
+       ++$THIS_FILE if $MULTIPLE_FILES;
+       do {
+           %section_info = ();
+           %toc_section_info = ();
+           %cite_info = ();
+           %ref_files = ();
+       } unless $MULTIPLE_FILES;
+       local($bbl_nr) = 1;
+
+       # The number of reused images and those in images.tex
+       local($global_page_num) = (0) unless($FIXEDDIR && $NO_SUBDIR);
+       # The number of images in images.tex
+       local($new_page_num) = (0); # unless($FIXEDDIR && $NO_SUBDIR);
+       local($pid, $sections_rx,
+           , $outermost_level, %latex_body, $latex_body
+           , %encoded_section_number
+           , %verbatim, %new_command, %new_environment
+           , %provide_command, %renew_command, %new_theorem
+           , $preamble, $aux_preamble, $prelatex, @preamble);
+
+       # must retain these when all files are in the same directory
+       # else the images.pl and labels.pl files get clobbered
+       unless ($FIXEDDIR && $NO_SUBDIR) {
+           print "\nResetting image-cache" if ($#ARGV);
+           local(%cached_env_img, %id_map, %symbolic_labels, %latex_labels)
+       }
+
+## AYS: Allow extension other than .tex and make it optional
+       ($EXT = $FILE) =~ s/.*\.([^\.]*)$/$1/;
+       if ( $EXT eq $FILE ) {
+           $EXT = "tex";
+           $FILE =~ s/$/.tex/;
+       }
+
+       #RRM: allow user-customisation, dependent on file-name
+       # e.g. add directories to $TEXINPUTS named for the file
+       # --- idea due to Fred Drake <fdrake@acm.org>
+       &custom_driver_hook($FILE) if (defined &custom_driver_hook);
+
+# JCL(jcl-dir)
+# We need absolute paths for TEXINPUTS here, because
+# we change the directory
+       if ($orig_cwd eq $texfilepath) {
+           &deal_with_texinputs($orig_cwd);
+       } else {
+           &deal_with_texinputs($orig_cwd, $texfilepath);
+       }
+
+       ($texfilepath, $FILE) = &get_full_path($FILE);
+       $texfilepath = '.' unless($texfilepath);
+
+       die "Cannot read $texfilepath$dd$FILE \n"
+           unless (-f "$texfilepath$dd$FILE");
+
+
+# Tell texexpand which files we *don't* want to look at.
+       $ENV{'TEXE_DONT_INCLUDE'} = $DONT_INCLUDE if $DONT_INCLUDE;
+# Tell texexpand which files we *do* want to look at, e.g.
+# home-brew style files
+       $ENV{'TEXE_DO_INCLUDE'} = $DO_INCLUDE if $DO_INCLUDE;
+
+       $FILE =~ s/\.[^\.]*$//; ## AYS
+       $DESTDIR = ''; # start at empty
+       if ($FIXEDDIR) {
+           $DESTDIR = $FIXEDDIR unless ($FIXEDDIR eq '.');
+           if (($ROOTED)&&!($texfilepath eq $orig_cwd)) {
+               $DESTDIR .= $dd . $FILE unless $NO_SUBDIR;
+           };
+       } elsif ($texfilepath eq $orig_cwd) {
+           $DESTDIR = ($NO_SUBDIR ? '.' : $FILE);
+       } else {
+           $DESTDIR = $ROOTED ? '.' : $texfilepath;
+           $DESTDIR .= $dd . $FILE unless $NO_SUBDIR;
+       }
+       $PREFIX  = "$FILE-" if $AUTO_PREFIX;
+
+       print "\nOPENING $texfilepath$dd$FILE.$EXT \n"; ## AYS
+
+       next unless (&new_dir($DESTDIR,''));
+        # establish absolute path to $DESTDIR
+       $DESTDIR = L2hos->Make_directory_absolute($DESTDIR);
+        &make_tmp_dir;
+        print "\nNote: Working directory is $DESTDIR\n";
+        print "Note: Images will be generated in $TMPDIR\n\n";
+
+# Need to clean up a bit in case there's garbage left
+# from former runs.
+       if ($DESTDIR) { chdir($DESTDIR) || die "$!\n"; }
+       if (opendir (TMP,$TMP_)) {
+           foreach (readdir TMP) {
+               L2hos->Unlink("TMP_$dd$_") unless (/^\.\.?$/);
+           }
+           closedir TMP; 
+       }
+       &cleanup(1);
+       unless(-d $TMP_) {
+           mkdir($TMP_, 0755) ||
+             die "Cannot create directory '$TMP_': $!\n";
+       }
+       chdir($orig_cwd);
+
+# RRM 14/5/98  moved this to occur earlier
+## JCL(jcl-dir)
+## We need absolute paths for TEXINPUTS here, because
+## we change the directory
+#      if ($orig_cwd eq $texfilepath) {
+#          &deal_with_texinputs($orig_cwd);
+#      } else {
+#          &deal_with_texinputs($orig_cwd, $texfilepath);
+#      }
+
+
+# This needs $DESTDIR to have been created ...
+       print " *** calling  `texexpand' ***" if ($VERBOSITY > 1);
+       local($unseg) = ($UNSEGMENT ? "-unsegment " : "");
+
+# does DOS need to check these here ?
+#      die "File $TEXEXPAND does not exist or is not executable\n"
+#          unless (-x $TEXEXPAND);
+       L2hos->syswait("$TEXEXPAND $dbg -auto_exclude $unseg"
+                . "-save_styles $DESTDIR$dd$TMP_${dd}styles "
+                . ($TEXINPUTS ? "-texinputs $TEXINPUTS " : '' )
+                . (($VERBOSITY >2) ? "-verbose " : '' )
+                . "-out $DESTDIR$dd$TMP_$dd$FILE "
+                . "$texfilepath$dd$FILE.$EXT")
+           && die " texexpand  failed: $!\n";
+       print STDOUT "\n ***  `texexpand' done ***\n" if ($VERBOSITY > 1);
+
+       chdir($DESTDIR) if $DESTDIR;
+       $SIG{'INT'} = 'handler';
+
+       &open_dbm_database;
+       &initialise_sections;
+       print STDOUT "\n ***  database open ***\n" if ($VERBOSITY > 1);
+
+       if ($IMAGES_ONLY) {
+           &make_off_line_images;
+       } else {
+           &rename_image_files;
+           &load_style_file_translations;
+           &make_language_rx;
+           &make_raw_arg_cmd_rx;
+#          &make_isolatin1_rx unless ($NO_ISOLATIN);
+           &translate_titles;
+           &make_sections_rx;
+           print "\nReading ...";
+           if ($SHORT_FILENAME) {
+               L2hos->Rename ("$TMP_$dd$FILE" ,"$TMP_$dd$SHORT_FILENAME" );
+               &slurp_input_and_partition_and_pre_process(
+                     "$TMP_$dd$SHORT_FILENAME");
+           } else {
+               &slurp_input_and_partition_and_pre_process("$TMP_$dd$FILE");
+           }
+           &add_preamble_head;
+           # Create a regular expressions
+           &set_depth_levels;
+           &make_sections_rx;
+           &make_order_sensitive_rx;
+           &add_document_info_page if ($INFO && !(/\\htmlinfo/));
+           &add_bbl_and_idx_dummy_commands;
+           &translate; # Destructive!
+       }
+       &style_sheet;
+       &close_dbm_database;
+       &cleanup();
+
+#JCL: read warnings from file to $warnings
+       local($warnings) = &get_warnings;
+       print "\n\n*********** WARNINGS ***********  \n$warnings"
+           if ($warnings || $NO_IMAGES || $IMAGES_ONLY);
+       &image_cache_message if ($NO_IMAGES || $IMAGES_ONLY);
+       &image_message if ($warnings =~ /Failed to convert/io);
+       undef $warnings;
+
+# JCL - generate directory index entry.
+# Yet, a hard link, cause Perl lacks symlink() on some systems.
+       do {
+           local($EXTN) = $EXTN;
+           $EXTN =~ s/_\w+(\.html?)/$1/ if ($frame_main_name);
+           local($from,$to) = (eval($LINKPOINT),eval($LINKNAME));
+           if (length($from) && length($to) && ($from ne $to)) {
+               #frames may have altered $EXTN
+               $from =~ s/$frame_main_name(\.html?)/$1/ if ($frame_main_name);
+               $to =~ s/$frame_main_name(\.html?)/$1/ if ($frame_main_name);
+               L2hos->Unlink($to);
+               L2hos->Link($from,$to);
+           }
+       } unless ($NO_AUTO_LINK || !($LINKPOINT) || !($LINKNAME));
+
+       &html_validate if ($HTML_VALIDATE && $HTML_VALIDATOR);
+
+# Go back to the source directory
+       chdir($orig_cwd);
+        $TEST_MODE = $DESTDIR if($TEST_MODE); # save path
+       $DESTDIR = '';
+       $OUT_NODE = 0 unless $FIXEDDIR;
+       $STYLESHEET = '' if ($STYLESHEET =~ /^\Q$FILE./);
+    }
+    print "\nUnknown commands: ". join(" ",keys %unknown_commands)
+       if %unknown_commands;
+###MEH -- math support
+    print "\nMath commands outside math: " .
+       join(" ",keys %commands_outside_math) .
+           "\n  Output may look weird or may be faulty!\n"
+               if %commands_outside_math;
+    print "\nDone.\n";
+    if($TEST_MODE) {
+      $TEST_MODE =~ s:[$dd$dd]+$::;
+      print "\nTo view the results, point your browser at:\n",
+        L2hos->path2URL(L2hos->Make_directory_absolute($TEST_MODE).$dd.
+        "index$EXTN"),"\n";
+    }
+    $end_time = time; 
+    $total_time = $end_time - $start_time;
+    print STDOUT join(' ',"Timing:",$total_time,"seconds\n")
+       if ($TIMING||$DEBUG||($VERBOSITY > 2));
+    $_;
+}
+
+sub open_dbm_database {
+    # These are DBM (unix DataBase Management) arrays which are actually
+    # stored in external files. They are used for communication between
+    # the main process and forked child processes;
+    print STDOUT "\n"; # this mysteriously prevents a core dump !
+
+    dbmopen(%verb, "$TMP_${dd}verb",0755);
+#    dbmopen(%verbatim, "$TMP_${dd}verbatim",0755);
+    dbmopen(%verb_delim, "$TMP_${dd}verb_delim",0755);
+    dbmopen(%expanded,"$TMP_${dd}expanded",0755);
+# Holds max_id, verb_counter, verbatim_counter, eqn_number
+    dbmopen(%global, "$TMP_${dd}global",0755);
+# Hold style sheet information
+    dbmopen(%env_style, "$TMP_${dd}envstyles",0755);
+    dbmopen(%txt_style, "$TMP_${dd}txtstyles",0755);
+    dbmopen(%styleID, "$TMP_${dd}styleIDs",0755);
+
+# These next two are used during off-line image conversion
+# %new_id_map maps image id's to page_numbers of the images in images.tex
+# %image_params maps image_ids to conversion parameters for that image
+    dbmopen(%new_id_map, "$TMP_${dd}ID_MAP",0755);
+    dbmopen(%img_params, "$TMP_${dd}IMG_PARAMS",0755);
+    dbmopen(%orig_name_map, "$TMP_${dd}ORIG_MAP",0755);
+
+    $global{'max_id'} = ($global{'max_id'} | 0);
+    &read_mydb(\%verbatim, "verbatim");
+    $global{'verb_counter'} = ($global{'verb_counter'} | 0);
+    $global{'verbatim_counter'} = ($global{'verbatim_counter'} | 0);
+
+    &read_mydb(\%new_command, "new_command");
+    &read_mydb(\%renew_command, "renew_command");
+    &read_mydb(\%provide_command, "provide_command");
+    &read_mydb(\%new_theorem, "new_theorem");
+    &read_mydb(\%new_environment, "new_environment");
+    &read_mydb(\%dependent, "dependent");
+#    &read_mydb(\%env_style, "env_style");
+#    &read_mydb(\%styleID, "styleID");
+    # MRO: Why should we use read_mydb instead of catfile?
+    $preamble = &catfile(&_dbname("preamble"),1) || '';
+    $prelatex = &catfile(&_dbname("prelatex"),1) || '';
+    $aux_preamble = &catfile(&_dbname("aux_preamble"),1) || '';
+    &restore_critical_variables;
+}
+
+sub close_dbm_database {
+    &save_critical_variables;
+    dbmclose(%verb); undef %verb;
+#    dbmclose(%verbatim); undef %verbatim;
+    dbmclose(%verb_delim); undef %verb_delim;
+    dbmclose(%expanded); undef %expanded;
+    dbmclose(%global); undef %global;
+    dbmclose(%env_style); undef %env_style;
+    dbmclose(%style_id); undef %style_id;
+    dbmclose(%new_id_map); undef %new_id_map;
+    dbmclose(%img_params); undef %img_params;
+    dbmclose(%orig_name_map); undef %orig_name_map;
+    dbmclose(%txt_style); undef %txt_style;
+    dbmclose(%styleID); undef %styleID;
+}
+
+sub clear_images_dbm_database {
+    # <Added calls to dbmclose dprhws>
+    # %new_id_map will be used by the off-line image conversion process
+    #
+    dbmclose(%new_id_map);
+    dbmclose(%img_params);
+    dbmclose(%orig_name_map);
+    undef %new_id_map;
+    undef %img_params;
+    undef %orig_name_map;
+    dbmopen(%new_id_map, "$TMP_${dd}ID_MAP",0755);
+    dbmopen(%img_params, "$TMP_${dd}IMG_PARAMS",0755);
+    dbmopen(%orig_name_map, "$TMP_${dd}ORIG_MAP",0755);
+}
+
+sub initialise_sections {
+    local($key);
+    foreach $key (keys %numbered_section) {
+       $global{$key} = $numbered_section{$key}}
+}
+
+sub save_critical_variables {
+    $global{'math_markup'} = $NO_MATH_MARKUP;
+    $global{'charset'} = $CHARSET;
+    $global{'charenc'} = $charset;
+    $global{'language'} = $default_language;
+    $global{'isolatin'} = $ISOLATIN_CHARS;
+    $global{'unicode'} = $UNICODE_CHARS;
+    if ($UNFINISHED_ENV) {
+       $global{'unfinished_env'} = $UNFINISHED_ENV;
+       $global{'replace_end_env'} = $REPLACE_END_ENV;
+    }
+    $global{'unfinished_comment'} = $UNFINISHED_COMMENT;
+    if (@UNMATCHED_OPENING) {
+       $global{'unmatched'} = join(',',@UNMATCHED_OPENING);
+    }
+}
+
+sub restore_critical_variables {
+    $NO_MATH_MARKUP = ($global{'math_markup'}|
+       (defined $NO_MATH_MARKUP ? $NO_MATH_MARKUP:1));
+    $CHARSET = ($global{'charset'}| $CHARSET);
+    $charset = ($global{'charenc'}| $charset);
+    $default_language = ($global{'language'}|
+       (defined $default_language ? $default_language:'english'));
+    $ISOLATIN_CHARS = ($global{'isolatin'}|
+       (defined $ISOLATIN_CHARS ? $ISOLATIN_CHARS:0));
+    $UNICODE_CHARS = ($global{'unicode'}|
+       (defined $UNICODE_CHARS ? $UNICODE_CHARS:0));
+    if ($global{'unfinished_env'}) {
+       $UNFINISHED_ENV = $global{'unfinished_env'};
+       $REPLACE_END_ENV = $global{'replace_end_env'};
+    }
+    $UNFINISHED_COMMENT = $global{'unfinished_comment'};
+    if ($global{'unmatched'}) {
+       @UNMATCHED_OPENING = split(',',$global{'unmatched'});
+    }
+
+    # undef any renewed-commands...
+    # so the new defs are read from %new_command
+    local($cmd,$key,$code);
+    foreach $key (keys %renew_command) {
+       $cmd = "do_cmd_$key";
+       $code = "undef \&$cmd"; eval($code) if (defined &$cmd);
+       if ($@) { print "\nundef \&do_cmd_$cmd failed"}
+    }
+}
+
+#JCL: The warnings should have been handled within the DBM database.
+# Unfortunately if the contents of an array are more than ~900 (system
+# dependent) chars long then dbm cannot handle it and gives error messages.
+sub write_warnings { #clean
+    my ($str) = @_;
+    $str .= "\n" unless($str =~ /\n$/);
+    print STDOUT "\n *** Warning: $str" if ($VERBOSITY > 1);
+    my $warnings = '';
+    if(-f 'WARNINGS') {
+        $warnings = &catfile('WARNINGS') || '';
+    }
+    return () if ($warnings =~ /\Q$str\E/);
+    if(open(OUT,">>WARNINGS")) {
+        print OUT $str;
+        close OUT;
+    } else {
+        print "\nError: Cannot append to 'WARNINGS': $!\n";
+    }
+}
+
+sub get_warnings {
+    return &catfile('WARNINGS',1) || '';
+}
+
+# MRO: Standardizing
+sub catfile {
+    my ($file,$ignore) = @_;
+    unless(open(CATFILE,"<$file")) {
+        print "\nError: Cannot read '$file': $!\n"
+            unless($ignore);
+        return undef;
+    }
+    local($/) = undef; # slurp in whole file
+    my $contents = <CATFILE>;
+    close(CATFILE);
+    $contents;
+}
+
+
+sub html_validate {
+    my ($extn) = $EXTN;
+    if ($EXTN !~ /^\.html?$/i) {
+       $extn =~ s/^[^\.]*(\.html?)$/$1/;
+    }
+    print "\n *** Validating ***\n";
+    my @htmls = glob("*$extn");
+    my $file;
+    foreach $file (@htmls) {
+      system("$HTML_VALIDATOR $file");
+    }
+}
+
+sub lost_argument {
+    local($cmd) = @_;
+    &write_warnings("\nincomplete argument to command: \\$cmd");
+}
+
+
+# These subroutines should have been handled within the DBM database.
+# Unfortunately if the contents of an array are more than ~900 (system
+# dependent) chars long then dbm cannot handle it and gives error messages.
+# So here we save and then read the contents explicitly.
+sub write_mydb {
+    my ($db, $key, $str) = @_;
+    &write_mydb_simple($db, "\n$mydb_mark#$key#$str");
+}
+
+# generate the DB file name from the DB name
+sub _dbname {
+    "$TMP_$dd$_[0]";
+}
+
+sub write_mydb_simple {
+    my ($db, $str) = @_;
+    my $file = &_dbname($db);
+    if(open(DB,">>$file")) {
+        print DB $str;
+        close DB;
+    } else {
+        print "\nError: Cannot append to '$file': $!\n";
+    }
+}
+
+sub clear_mydb {
+    my ($db) = @_;
+    my $file = &_dbname($db);
+    if(open(DB,">$file")) {
+        close DB;
+    } else {
+        print "\nError: Cannot clear '$file': $!\n";
+    }
+}
+
+# Assumes the existence of a DB file which contains
+# sequences of e.g. verbatim counters and verbatim contents.
+sub read_mydb {
+    my ($dbref,$name) = @_;
+    my $contents = &catfile(&_dbname($name),1);
+    return '' unless(defined $contents);
+    my @tmp = split(/\n$mydb_mark#([^#]*)#/, $contents);
+    my $i = 1; # Ignore the first element at 0
+    print "\nDBM: $name open..." if ($VERBOSITY > 2);
+    while ($i < scalar(@tmp)) {
+       my $tmp1 = $tmp[$i];
+        my $tmp2 = $tmp[++$i];
+       $$dbref{$tmp1} = defined $tmp2 ? $tmp2 : '';
+       ++$i;
+    };
+    $contents;
+}
+
+
+# Reads in a latex generated file (e.g. .bbl or .aux)
+# It returns success or failure
+# ****** and binds $_ in the caller as a side-effect ******
+sub process_ext_file {
+    local($ext) = @_;
+    local($found, $extfile,$dum,$texpath);
+    $extfile =  $EXTERNAL_FILE||$FILE;
+    local($file) = &fulltexpath("$extfile.$ext");
+    $found = 0;
+    &write_warnings(
+           "\n$extfile.$EXT is newer than $extfile.$ext: Please rerun latex" . ## AYS
+           (($ext =~ /bbl/) ? " and bibtex.\n" : ".\n"))
+       if ( ($found = (-f $file)) &&
+           &newer(&fulltexpath("$extfile.$EXT"), $file)); ## AYS
+    if ((!$found)&&($extfile =~ /\.$EXT$/)) {
+       $file = &fulltexpath("$extfile");
+       &write_warnings(
+           "\n$extfile is newer than $extfile: Please rerun latex" . ## AYS
+           (($ext =~ /bbl/) ? " and bibtex.\n" : ".\n"))
+           if ( ($found = (-f $file)) &&
+               &newer(&fulltexpath("$extfile"), $file)); ## AYS
+    }
+
+    # check in other directories on the $TEXINPUTS paths
+    if (!$found) {
+       foreach $texpath (split /$envkey/, $TEXINPUTS ) {
+           $file = "$texpath$dd$extfile.$ext";
+           last if ($found = (-f $file));
+       }
+    }
+    if ( $found ) {
+       print "\nReading $ext file: $file ...";
+       # must allow @ within control-sequence names
+       $dum = &do_cmd_makeatletter();
+       &slurp_input($file);
+       if ($ext =~ /bbl/) {
+           # remove the \newcommand{\etalchar}{...} since not needed
+           s/^\\newcommand{\\etalchar}[^\n\r]*[\n\r]+//s;
+       }
+       &pre_process;
+       &substitute_meta_cmds if (%new_command || %new_environment);
+       if ($ext eq "aux") {
+            my $latex_pathname = L2hos->path2latex($file);
+           $aux_preamble .=
+               "\\AtBeginDocument{\\makeatletter\n\\input $latex_pathname\n\\makeatother\n}\n";
+           local(@extlines) = split ("\n", $_);
+           print " translating ".(0+@extlines). " lines " if ($VERBOSITY >1);
+           local($eline,$skip_to); #$_ = '';
+           foreach $eline (@extlines) {
+               if ($skip_to) { next unless ($eline =~ s/$O$skip_to$C//) }
+               $skip_to = '';
+               # skip lines added for pdfTeX/hyperref compatibility
+               next if ($eline =~ /^\\(ifx|else|fi|global \\let|gdef|AtEndDocument|let )/);
+               # remove \index and \label commands, else invalid links may result
+               $eline =~ s/\\(index|label)\s*($O\d+$C).*\2//g;
+               if ($eline =~ /\\(old)?contentsline/) {
+                   do { local($_,$save_AUX) = ($eline,$AUX_FILE);
+                   $AUX_FILE = 0;
+                   &wrap_shorthand_environments;
+                   #footnote markers upset the numbering
+                   s/\\footnote(mark|text)?//g;
+                   $eline = &translate_environments($_);
+                   $AUX_FILE = $save_AUX;
+                   undef $_ };
+               } elsif ($eline =~ s/^\\\@input//) {
+                   &do_cmd__at_input($eline);
+                   $eline = '';
+               } elsif ($eline =~ s/^\\\@setckpt$O(\d+)$C//) {
+                   $skip_to = $1; next;
+               }
+#          $eline =~ s/$image_mark#([^#]+)#/print "\nIMAGE:",$img_params{$1},"\n";''/e;
+#              $_ .= &translate_commands(&translate_environments($eline));
+               $_ .= &translate_commands($eline) if $eline;
+           }
+           undef @extlines;
+       } elsif ($ext =~ /$caption_suffixes/) {
+           local(@extlines) = split ("\n", $_);
+           print " translating ".(0+@extlines). " lines "if ($VERBOSITY >1);
+           local($eline); $_ = '';
+           foreach $eline (@extlines) {
+               # remove \index and \label commands, else invalid links may result
+               $eline =~ s/\\(index|label)\s*($O\d+$C).*\2//gso;
+                if ($eline =~ /\\(old)?contentsline/) {
+                   do { local($_,$save_PREAMBLE) = ($eline,$PREAMBLE);
+                   $PREAMBLE = 0;
+                    &wrap_shorthand_environments;
+                    $eline = &translate_environments($_);
+                   $PREAMBLE = $save_PREAMBLE;
+                    undef $_ };
+                }
+               $_ .= &translate_commands($eline);
+           }
+           undef @extlines;
+       } else {
+           print " wrapping " if ($VERBOSITY >1);
+           &wrap_shorthand_environments;
+           $_ = &translate_commands(&translate_environments($_));
+           print " translating " if ($VERBOSITY >1);
+       }
+       print "\n processed size: ".length($_)."\n" if($VERBOSITY>1);
+       $dum = &do_cmd_makeatother();
+    } else { 
+       print "\n*** Could not find file: $file ***\n" if ($DEBUG)
+    };
+    $found;
+}
+
+sub deal_with_texinputs {
+# The dot precedes all, this let's local files override always.
+# The dirs we want are given as parameter list.
+    if(!$TEXINPUTS) { $TEXINPUTS = '.' }
+    elsif ($TEXINPUTS =~ /^$envkey/) {
+       $TEXINPUTS = '.'.$TEXINPUTS
+    };
+    if ($ROOTED) {$TEXINPUTS .= "$envkey$FIXEDDIR"}
+    $TEXINPUTS = &absolutize_path($TEXINPUTS);
+    $ENV{'TEXINPUTS'} = join($envkey,".",@_,$TEXINPUTS,$ENV{'TEXINPUTS'});
+}
+
+# provided by Fred Drake
+sub absolutize_path {
+    my ($path) = @_;
+    my $npath = '';
+    foreach $dir (split /$envkey/o, $path) {
+        $npath .= L2hos->Make_directory_absolute($dir) . $envkey;
+    }
+    $npath =~ s/$envkey$//;
+    $npath;
+}
+
+sub add_document_info_page {
+    # Uses $outermost_level
+    # Nasty race conditions if the next two are done in parallel
+    local($X) = ++$global{'max_id'};
+    local($Y) = ++$global{'max_id'};
+    ###MEH -- changed for math support: no underscores in commandnames
+    $_ = join('', $_
+             , (($MAX_SPLIT_DEPTH <= $section_commands{$outermost_level})?
+                "\n<HR>\n" : '')
+             , "\\$outermost_level", "*"
+             , "$O$X$C$O$Y$C\\infopagename$O$Y$C$O$X$C\n",
+             , " \\textohtmlinfopage");
+}
+
+
+# For each style file name in TMP_styles (generated by texexpand) look for a
+# perl file in $LATEX2HTMLDIR/styles and load it.
+sub load_style_file_translations {
+    local($_, $style, $options, $dir);
+    print "\n";
+    if ($TEXDEFS) {
+       foreach $dir (split(/$envkey/,$LATEX2HTMLSTYLES)) {
+           if (-f ($_ = "$dir${dd}texdefs.perl")) {
+               print "\nLoading $_...";
+               require ($_);
+               $styles_loaded{'texdefs'} = 1;
+               last;
+           }
+       }
+    }
+
+    # packages automatically implemented
+    local($auto_styles) = $AUTO_STYLES;
+    $auto_styles .= 'array|' if ($HTML_VERSION > 3.1);
+    $auto_styles .= 'tabularx|' if ($HTML_VERSION > 3.1);
+    $auto_styles .= 'theorem|';
+
+    # these are not packages, but can appear as if class-options
+    $auto_styles .= 'psamsfonts|';
+    $auto_styles .= 'noamsfonts|';
+
+    $auto_styles =~ s/\|$//;
+
+    if(open(STYLES, "<$TMP_${dd}styles")) {
+        while(<STYLES>) {
+            if(s/^\s*(\S+)\s*(.*)$/$style = $1; $options = $2;/eo) {
+                &do_require_package($style);
+               $_ = $DONT_INCLUDE;
+               s/:/|/g;
+               &write_warnings("No implementation found for style \`$style\'\n")
+                   unless ($styles_loaded{$style} || $style =~ /^($_)$/
+                       || $style =~ /$auto_styles/);
+
+                # MRO: Process options for packages
+                &do_package_options($style,$options) if($options);
+            }
+        }
+        close(STYLES);
+    } else {
+        print "\nError: Cannot read '$TMP_${dd}styles': $!\n";
+    }
+}
+
+################## Weird Special case ##################
+
+# The new texexpand can be told to leave in \input and \include
+# commands which contain code that the translator should simply pass
+# to latex, such as the psfig stuff.  These should still be seen by
+# TeX, so we add them to the preamble ...
+
+sub do_include_lines {
+    while (s/$include_line_rx//o) {
+       local($include_line) = &revert_to_raw_tex($&);
+       &add_to_preamble ('include', $include_line);
+    }
+}
+
+########################## Preprocessing ############################
+
+# JCL(jcl-verb)
+# The \verb declaration and the verbatim environment contain simulated
+# typed text and should not be processed. Characters such as $,\,{,and }
+# loose their special meanings and should not be considered when marking
+# brackets etc. To achieve this \verb declarations and the contents of
+# verbatim environments are replaced by markers. At the end the original
+# text is put back into the document.
+# The markers for verb and verbatim are different so that these commands
+# can be restored to what the raw input was just in case they need to
+# be passed to latex.
+
+sub pre_process {
+    # Modifies $_;
+    #JKR: We need support for some special environments.
+    # This has to be here, because  they might contain
+    # structuring commands like \section etc.
+    local(%comments);
+    &pre_pre_process if (defined &pre_pre_process);
+    s/\\\\/\\\\ /go;           # Makes it unnecessary to look for escaped cmds
+    &replace_html_special_chars;
+    # Remove fake environment which should be invisible to LaTeX2HTML.
+    s/\001//m;
+    s/[%]end\s*{latexonly}/\001/gom;
+    s/[%]begin\s*{latexonly}([^\001]*)\001/%/gos;
+    s/\001//m;
+
+    &preprocess_alltt if defined(&preprocess_alltt);
+
+    $KEEP_FILE_MARKERS = 1;
+    if ($KEEP_FILE_MARKERS) {
+#      if (s/%%% TEXEXPAND: \w+ FILE( MARKER)? (\S*).*/
+#          '<tex2html_'.($1?'':'end').'file>'.qq|#$2#|."\n"/em) {
+#          $_ = "<tex2html_file>#$2#\n". $_ };
+       #RRM: ignore \n at end of included file, else \par may result
+       if (s/(\n{1,2})?%%% TEXEXPAND: \w+ FILE( MARKER)? (\S*).*\n?/
+           ($2?$1:"\n").'<tex2html_'.($2?'':'end').'file>'.qq|#$3#|."\n"/em) {
+           $_ = "<tex2html_file>#$3#\n". $_ };
+    } else {
+       s/%%% TEXEXPAND[^\n]*\n//gm;
+    }
+
+    # Move all LaTeX comments into a local list
+    s/([ \t]*(^|\G|[^\\]))(%.*(\n[ \t]*|$))/print "%";
+       $comments{++$global{'verbatim_counter'}} = "$3";
+       &write_mydb("verbatim", $global{'verbatim_counter'}, $3);
+       "$1$comment_mark".$global{'verbatim_counter'}."\n"/mge;
+    # Remove the htmlonly-environment
+    s/\\begin\s*{htmlonly}\s*\n?//gom;
+    s/\\end\s*{htmlonly}\s*\n?//gom;
+    # Remove enviroments which should be invisible to LaTeX2HTML.
+    s/\n[^%\n]*\\end\s*{latexonly}\s*\n?/\001/gom;
+    s/((^|\n)[^%\n]*)\\begin\s*{latexonly}([^\001]*)\001/$1/gom;
+    s/\\end\s*{comment}\s*\n?/\001/gom;
+    s/\\begin\s*{comment}([^\001]*)\001//gom;
+
+    # this used to be earlier, but that can create problems with comments
+    &wrap_other_environments if (%other_environments);
+
+#    s/\\\\/\\\\ /go;          # Makes it unnecessary to look for escaped cmds
+    local($next, $esc_del);
+    &normalize_language_changes;
+    # Patches by #JKR, #EI#, #JCL(jcl-verb)
+
+    #protect \verb|\begin/end....|  parts, for LaTeX documentation
+    s/(\\verb\*?(.))\\(begin|end)/$1\003$3/g;
+
+    local(@processedV);
+    local($opt, $style_info,$before, $contents, $after, $env);
+    while (($UNFINISHED_COMMENT)||
+  (/\\begin\s*($opt_arg_rx)?\s*\{($verbatim_env_rx|$keepcomments_rx)\}/o)) {
+       ($opt, $style_info) = ($1,$2);
+       $before=$contents=$after=$env='';
+       if ($UNFINISHED_COMMENT) {
+           $UNFINISHED_COMMENT =~ s/([^:]*)::(\d+)/$env=$1;$after=$_;
+               $before = join("",$unfinished_mark,$env,$2,"#");''/e;
+           print "\nfound the lost \\end{$env}\n";
+       }
+       #RRM: can we avoid copying long strings here ?
+       #     maybe this loop can be an  s/.../../s  with (.*?)
+       #
+       ($before, $after, $env) = ($`, $', $3) unless ($env);
+       if (!($before =~ 
+     /\\begin(\s*\[[^\]]*\]\s*)?\{($verbatim_env_rx|$keepcomments_rx)\}/)) {
+           push(@processedV,$before);
+           print "'";$before = '';
+       }
+       if ($after =~ /\s*\\end{$env[*]?}/) { # Must NOT use the s///o option!!!
+           ($contents, $after) = ($`, $');
+           $contents =~ s/^\n+/\n/s;
+#          $contents =~ s/\n+$//s;
+
+           # re-insert comments
+           $contents =~ s/$comment_mark(\d+)\n?/$comments{$1}/g;
+#          $contents =~ s/$comment_mark(\d+)/$verbatim{$1}/g;
+
+           # revert '\\ ' -> '\\' only once 
+           if ($env =~ /rawhtml|$keepcomments_rx/i) {
+               $contents = &revert_to_raw_tex($contents);
+           } else {
+               $contents =~ s/([^\\](?:\\\\)*\\)([$html_escape_chars])/$1.&special($2)/geos;
+               $contents =~ s/\\\\ /\\\\/go;
+           }
+
+           if ($env =~/$keepcomments_rx/) {
+               $verbatim{++$global{'verbatim_counter'}} = "$contents";
+           } else {
+               &write_mydb("verbatim", ++$global{'verbatim_counter'}, $contents);
+           }
+#          $verbatim{$global{'verbatim_counter'}} = "$contents" if ($env =~/$keepcomments_rx/);
+#          $verbatim{$global{'verbatim_counter'}} = "$contents";
+
+           if ($env =~ /rawhtml|$keepcomments_rx/i) {
+               if ($before) {
+                   $after = join("",$verbatim_mark,$env
+                             ,$global{'verbatim_counter'},"#",$after);
+               } else {
+                   push (@processedV, join("",$verbatim_mark,$env
+                          ,$global{'verbatim_counter'},"#"));
+               }
+           } elsif ($env =~ /tex2html_code/) {
+               if ($before) {
+                   $after = join("","\\begin", $opt, "\{verbatim_code\}"
+                         , $verbatim_mark,$env
+                         , $global{'verbatim_counter'},"#"
+                         , "\\end\{verbatim_code\}",$after);
+               } else {
+                   push (@processedV
+                         , join("","\\begin", $opt, "\{verbatim_code\}"
+                                , $verbatim_mark,$env
+                                , $global{'verbatim_counter'},"#"
+                                , "\\end\{verbatim_code\}"));
+               }
+           } else {
+               if ($before) {
+                   $after = join("","\\begin", $opt, "\{tex2html_preform\}"
+                         , $verbatim_mark,$env
+                         , $global{'verbatim_counter'},"#"
+                         , "\\end\{tex2html_preform\}",$after);
+               } else {
+                   push (@processedV
+                         , join("","\\begin", $opt, "\{tex2html_preform\}"
+                                , $verbatim_mark,$env
+                                , $global{'verbatim_counter'},"#"
+                                , "\\end\{tex2html_preform\}" ));
+               }
+           }
+       } else {
+           print "Cannot find \\end{$env}\n";
+           $after =~ s/$comment_mark(\d+)\n?/$comments{$1}/g;
+#          $after =~ s/$comment_mark(\d+)/$verbatim{$1}/g;
+           if ($env =~ /rawhtml|$keepcomments_rx/i) {
+                $after = &revert_to_raw_tex($contents);
+           } else {
+               $after =~ s/([^\\](?:\\\\)*\\)([$html_escape_chars])/$1.&special($2)/geos;
+                $after =~ s/\\\\ /\\\\/go;
+           }
+           if ($env =~/$keepcomments_rx/) {
+                $verbatim{++$global{'verbatim_counter'}} = "$after";
+           } else {
+                &write_mydb("verbatim", ++$global{'verbatim_counter'}, $after );
+           }
+           $after = join("",$unfinished_mark,$env
+                         ,$global{'verbatim_counter'},"#");
+       }
+       $_ = join("",$before,$after);
+    }
+    print STDOUT "\nsensitive environments found: ".(int(0+@processedV/2))." "
+       if((@processedV)&&($VERBOSITY > 1));
+    $_ = join('',@processedV, $_); undef @processedV;
+
+    #restore \verb|\begin/end....|  parts, for LaTeX documentation
+#    $_ =~ s/(\\verb\W*?)\003(begin|end)/$1\\$2/g;
+    $_ =~ s/(\\verb(;SPM\w+;|\W*?))\003(begin|end)/$1\\$3/g;
+
+    # Now do the \verb declarations
+    # Patches by: #JKR, #EI#, #JCL(jcl-verb)
+    # Tag \verb command and legal opening delimiter with unique number.
+    # Replace tagged ones and its contents with $verb_mark & id number if the
+    # closing delimiter can be found. After no more \verb's are to tag, revert
+    # tagged one's to the original pattern.
+    local($del,$contents,$verb_rerun);
+    local($id) = $global{'verb_counter'};
+    # must tag only one alternation per loop
+    ##RRM: can this be speeded up using a list ??
+    my $vbmark = $verb_mark;
+    while (s/\\verb(\t*\*\t*)(\S)/"<verb$1".++$id.">$2"/e ||
+           s/\\verb()(\;SPM\w+\;|[^a-zA-Z*\s])/"<verb$1".++$id.">$2"/e ||
+           s/\\verb(\t\t*)([^*\s])/"<verb$1".++$id.">$2"/e) {
+
+       $del = $2;
+       #RRM: retain knowledge of whether \verb* or \verb
+       $vb_mark = ($1 =~/^\s*\*/? $verbstar_mark : $verb_mark);
+       $esc_del = &escape_rx_chars($del);
+       $esc_del = '' if (length($del) > 2);
+
+       # try to find closing delimiter and substitute the complete
+       # statement with $verb_mark or $verbstar_mark
+#      s/(<verb[^\d>]*$id>[\Q$del\E])([^$esc_del\n]*)([\Q$del\E]|$comment_mark(\d+)\n?)/
+       s/(<verb[^\d>]*$id>\Q$del\E)([^$esc_del\n]*?)(\Q$del\E|$comment_mark(\d+)\n?)/
+           $contents=$2;
+           if ($4) { $verb_rerun = 1;
+               join('', "\\verb$del", $contents, $comments{$4})
+           } else {
+               $contents =~ s|\\\\ |\\\\|g;
+               $contents =~ s|\n| |g;
+               $verb{$id}=$contents;
+               $verb_delim{$id}=$del;
+               join('',$vb_mark,$id,$verb_mark)
+           }
+       /e;
+    }
+    $global{'verb_counter'} = $id;
+    # revert changes to fake verb statements
+    s/<verb([^\d>]*)\d+>/\\verb$1/g;
+
+    #JKR: the comments include the linebreak and the following whitespace
+#   s/([^\\]|^)(%.*\n[ \t]*)+/$1/gom; # Remove Comments but not % which may be meaningful
+    s/((^|\n)$comment_mark(\d+))+//gom; # Remove comment markers on new lines, but *not* the trailing \n
+    s/(\\\w+|(\W?))($comment_mark\d*\n?)/($2)? $2.$3:($1? $1.' ':'')/egm; # Remove comment markers, not after braces
+#    s/(\W?)($comment_mark\d*\n?)/($1)? $1.$2:''/egm; # Remove comment markers, not after braces
+    # Remove comment markers, but *not* the trailing \n
+#  HWS:  Correctly remove multiple %%'s.
+#
+    s/\\%/\002/gm;
+#    s/(%.*\n[ \t]*)//gm;
+    s/(%[^\n]*\n)[ \t]*/$comment_mark\n/gm;
+
+    s/\002/\\%/gm;
+
+    local($tmp1,$tmp2);
+    s/^$unfinished_mark$keepcomments_rx(\d+)#\n?$verbatim_mark$keepcomments_rx(\d+)#/
+       $verbatim{$4}."\n\\end{$1}"/egm; # Raw TeX
+    s/$verbatim_mark$keepcomments_rx(\d+)#/
+       $tmp1 = $1;
+       $tmp2 = &protect_after_comments($verbatim{$2});
+       $tmp2 =~ s!\n$!!s;
+       join ('', "\\begin{$tmp1}"
+               , $tmp2
+               , "\n\\end{$tmp1}"
+               )/egm; # Raw TeX
+    s/$unfinished_mark$keepcomments_rx(\d+)#/$UNFINISHED_COMMENT="$1::$2";
+       "\\begin{$1}\n".$verbatim{$2}/egm; # Raw TeX
+
+    $KEEP_FILE_MARKERS = 1;
+    if ($KEEP_FILE_MARKERS) {
+       s/%%% TEXEXPAND: \w+ FILE( MARKER) (\S*).*\n/
+           '<tex2html_'.($1?'':'end').'file>'.qq|#.$2#\n|/gem;
+    } else {
+       s/%%% TEXEXPAND[^\n]*\n//gm;
+    }
+
+    &mark_string($_);
+
+
+    # attempt to remove the \html \latex and \latexhtml commands
+    s/\\latex\s*($O\d+$C)(.*)\1//gm;
+    s/\\latexhtml\s*($O\d+$C)(.*)\1\s*($O\d+$C)(.*)\3/$4/sg;
+    s/\\html\s*($O\d+$C)(.*)\1/$2/sg;
+    s/\\html\s*($O\d+$C)//gm;
+
+#    &make_unique($_);
+}
+
+# RRM:  When comments are retained, then ensure that they are benign
+# by removing \s and escaping braces, 
+# so that environments/bracing cannot become unbalanced.
+sub protect_after_comments {
+    my ($verb_text) = @_;
+#    $verb_text =~ s/\%(.*)/'%'.&protect_helper($1)/eg;
+    $verb_text =~ s/(^|[^\\])(\\\\)*\%(.*)/$1.$2.'%'.&protect_helper($3)/emg;
+    $verb_text;
+}
+
+sub protect_helper {
+    my ($text) = @_;
+    $text =~ s/\\/ /g;
+    $text =~ s/(\{|\})/\\$1/g;
+    $text;
+}
+
+sub make_comment {
+    local($type,$_) = @_;
+    $_ =~ s/\\(index|label)\s*(($O|$OP)\d+($C|$CP)).*\2//sg;
+    $_ = &revert_to_raw_tex($_);  s/^\n+//m;
+    $_ =~ s/\\(index|label)\s*\{.*\}//sg;
+    s/\-\-/- -/g; s/\-\-/- -/g; # cannot have -- inside a comment
+    $_ = join('', '<!-- ', $type , "\n ", $_ , "\n -->" );
+    $verbatim{++$global{'verbatim_counter'}} = $_;
+    &write_mydb('verbatim', $global{'verbatim_counter'}, $_ );
+    join('', $verbatim_mark, 'verbatim' , $global{'verbatim_counter'},'#')
+}
+
+sub wrap_other_environments {
+    local($key, $env, $start, $end, $opt_env, $opt_start);
+    foreach $key (keys %other_environments) {
+       # skip bogus entries
+       next unless ($env = $other_environments{$key});
+       $key =~ s/:/($start,$end)=($`,$');':'/e;
+
+       if (($end =~ /^\#$/m) && ($start =~ /^\#/m)) {
+           # catch Indica pre-processor language switches
+           $opt_start = $';
+           if ($env =~ s/\[(\w*)\]//o) {
+               $opt_env = join('','[', ($1 ? $1 : $opt_start ), ']');
+           }
+           local($next);
+           while ($_ =~ /$start\b/) {
+               push(@pre_wrapped, $`, "\\begin\{pre_$env\}", $opt_env );
+               $_=$';
+               if (/(\n*)$end/) {
+                   push(@pre_wrapped, $`.$1,"\\end\{pre_$env\}$1");
+                   $_ = $';
+                   if (!(s/^N(IL)?//o)) {$_ = '#'.$_ }
+               } else {
+                   print "\n *** unclosed $start...$end chunk ***\n";
+                   last;
+               }
+           }
+           $_ = join('', @pre_wrapped, $_);
+           undef @pre_wrapped;
+
+       } elsif (($end=~/^\n$/) && ($start =~ /^\#/)) {
+           # catch ITRANS pre-processor language info;  $env = 'nowrap';
+           local($ilang) = $start; $ilang =~ s/^\#//m;
+           s/$start\s*\=([^<\n%]*)\s*($comment_mark\d*|\n|%)/\\begin\{tex2html_$env\}\\ITRANSinfo\{$ilang\}\{$1\}\n\\end\{tex2html_$env\}$2/g;
+
+       } elsif (!$end &&($start =~ /^\#/m)) {
+           # catch Indica pre-processor input-mode switches
+           s/$start(.*)\n/\\begin\{tex2html_$env\}$&\\end\{tex2html_$env\}\n/g;
+
+       } elsif (($start eq $end)&&(length($start) == 1)) {
+           $start =~ s/(\W)/\\$1/; $end = $start;
+           s/([^$end])$start([^$end]+)$end/$1\\begin\{pre_$env\}$2\\end\{pre_$env\}/mg;
+       } elsif ($start eq $end) {
+           if (!($start =~ /\#\#/)) {
+               $start =~ s/(\W)/\\$1/g; $end = $start; }
+           local (@pre_wrapped);
+           local($opt); $opt = '[indian]' if ($start =~ /^\#\#$/m);
+           while ($_ =~ /$start/s) {
+               push(@pre_wrapped, $` , "\\begin\{pre_$env\}$opt");
+               $_=$';
+               if (/$end/s) {
+                   push(@pre_wrapped, $`, "\\end\{pre_$env\}");
+                   $_ = $';
+               } else {
+                   print "\n *** unclosed $start...$end chunk ***\n";
+                   last;
+               }
+           }
+           $_ = join('', @pre_wrapped, $_);
+           undef @pre_wrapped;
+       } elsif ($start && ($env =~ /itrans/)) {
+           # ITRANS is of this form
+           local($indic); if($start =~ /\#(\w+)$/m) {$indic = $1}
+           #include the language-name as an optional parameter
+           s/$start\b/\\begin\{pre_$env\}\[$indic\]/sg;
+           s/$end\b/\\end\{pre_$env\}/sg;
+       } elsif (($start)&&($end)) {
+           s/$start\b/\\begin\{pre_$env\}/sg;
+           s/$end\b/\\end\{pre_$env\}/sg;
+       }
+    }
+    $_;
+}
+
+#################### Marking Matching Brackets ######################
+
+# Reads the entire input file and performs pre_processing operations
+# on it before returning it as a single string. The pre_processing is
+# done on separate chunks of the input file by separate Unix processes
+# as determined by LaTeX \input commands, in order to reduce the memory
+# requirements of LaTeX2HTML.
+sub slurp_input_and_partition_and_pre_process {
+    local($file) = @_;
+    local(%string, @files, $pos);
+    local ($count) =  1;
+
+    unless(open(SINPUT,"<$file")) {
+        die "\nError: Cannot read '$file': $!\n";
+    }
+    local(@file_string);
+    print STDOUT "$file" if ($VERBOSITY >1);
+    while (<SINPUT>) {
+       if (/TEXEXPAND: INCLUDED FILE MARKER (\S*)/) {
+           # Forking seems to screw up the rest of the input stream
+           # We save the current position ...
+           $pos = tell SINPUT;
+           print STDOUT " fork at offset $pos " if ($VERBOSITY >1);
+            $string{'STRING'} = join('',@file_string); @file_string = ();
+           &write_string_out($count);
+           delete $string{'STRING'};
+           # ... so that we can return to it
+           seek(SINPUT, $pos, 0);
+           print STDOUT "\nDoing $1 ";
+           ++$count}
+       else {
+#          $string{'STRING'} .= $_
+           push(@file_string,$_);
+       }
+    }
+    $string{'STRING'} = join('',@file_string); @file_string = ();
+    &write_string_out($count);
+    delete $string{'STRING'};
+    close SINPUT;
+    @files = ();
+    if(opendir(DIR, $TMP_)) {
+        @files = sort grep(/^\Q$PARTITION_PREFIX\E\d+/, readdir(DIR));
+        closedir(DIR);
+    }
+
+    unless(@files) {
+        die "\nFailed to read in document parts.\n".
+            "Look up section Globbing in the troubleshooting manual.\n";
+    }
+
+    $count = 0;
+    foreach $file (@files) {
+       print STDOUT "\nappending file: $TMP_$dd$file " if ($VERBOSITY > 1);
+        $_ .= (&catfile("$TMP_$dd$file") || '');
+       print STDOUT "\ntotal length: ".length($_)." characters\n" if ($VERBOSITY > 1);
+    }
+    die "\nFailed to read in document parts (out of memory?).\n"
+       unless length($_);
+    print STDOUT "\ntotal length: ".length($_)." characters\n" if ($VERBOSITY > 1);
+}
+
+sub write_string_out {
+    local($count) = @_;
+    if ($count < 10) {$count = '00'.$count}
+    elsif ($count < 100) {$count = '0'.$count}
+    local($pid);
+    # All open unflushed streams are inherited by the child. If this is
+    # not set then the parent will *not* wait
+    $| = 1;
+    # fork returns 0 to the child and PID to the parent
+    &write_mydb_simple("prelatex", $prelatex);
+    &close_dbm_database;
+    unless ($CAN_FORK) {
+       &do_write_string_out;
+    } else {
+       unless ($pid = fork) {
+           &do_write_string_out;
+           exit 0;
+       };
+       waitpid($pid,0);
+    }
+    &open_dbm_database;
+}
+
+sub do_write_string_out {
+    local($_);
+    close (SINPUT) if($CAN_FORK);
+    &open_dbm_database;
+    $_ = delete $string{'STRING'};
+    # locate blank-lines, for paragraphs.
+    # Replace verbatim environments etc.
+    &pre_process;
+    # locate the blank lines for \par s
+    &substitute_pars;
+    # Handle newcommand, newenvironment, newcounter ...
+    &substitute_meta_cmds;
+    &wrap_shorthand_environments;
+    print STDOUT "\n *** End-of-partition ***" if ($VERBOSITY > 1);
+    if(open(OUT, ">$TMP_$dd$PARTITION_PREFIX$count")) {
+        print OUT $_;
+        close(OUT);
+    } else {
+        print "\nError: Cannot write '$TMP_$dd$PARTITION_PREFIX$count': $!\n";
+    }
+    print STDOUT $_ if ($VERBOSITY > 9);
+    $preamble = join("\n",$preamble,@preamble); # undef @preamble;
+    &write_mydb_simple("preamble", $preamble);
+    # this was done earlier; it should not be repeated
+    #&write_mydb_simple("prelatex", $prelatex);
+    &write_mydb_simple("aux_preamble", $aux_preamble);
+    &close_dbm_database;
+}
+
+# Reads the entire input file into a
+# single string.
+sub slurp_input  {
+    local($file) = @_;
+    local(%string);
+    if(open(INPUT,"<$file")) {
+        local(@file_string);
+        while (<INPUT>) {
+           push(@file_string, $_ );
+        }
+        $string{'STRING'} = join('',@file_string);
+        close INPUT;
+        undef @file_string;
+    } else {
+        print "\nError: Cannot read '$file': $!\n";
+    }
+    $_ = delete $string{'STRING'}; # Blow it away and return the result
+}
+
+# MRO: make them more efficient
+sub special {
+    $html_specials{$_[0]} || $_[0];
+}
+
+sub special_inv {
+    $html_specials_inv{$_[0]} || $_[0];
+}
+
+sub special_html {
+    $html_special_entities{$_[0]} || $_[0];
+}
+
+sub special_html_inv {
+    $html_spec_entities_inv{$_[0]} || $_[0];
+}
+
+# Mark each matching opening and closing bracket with a unique id.
+sub mark_string {
+    # local (*_) = @_; # Modifies $_ in the caller;
+    # -> MRO: changed to $_[0] (same effect)
+    # MRO: removed deprecated $*, replaced by option /m
+    $_[0] =~ s/(^|[^\\])\\{/$1tex2html_escaped_opening_bracket/gom;
+    $_[0] =~ s/(^|[^\\])\\{/$1tex2html_escaped_opening_bracket/gom; # repeat this
+    $_[0] =~ s/(^|[^\\])\\}/$1tex2html_escaped_closing_bracket/gom;
+    $_[0] =~ s/(^|[^\\])\\}/$1tex2html_escaped_closing_bracket/gom; # repeat this
+    my $id = $global{'max_id'};
+    my $prev_id = $id;
+    # mark all balanced braces
+    # MRO: This should in fact mark all of them as the hierarchy is
+    # processed inside-out.
+    1 while($_[0] =~ s/{([^{}]*)}/join("",$O,++$id,$C,$1,$O,$id,$C)/geo);
+    # What follows seems esoteric...
+    my @processedB = ();
+    # Take one opening brace at a time
+    while ($_[0] =~ /\{/) { 
+       my ($before,$after) = ($`,$');
+        my $change = 0;
+       while (@UNMATCHED_OPENING && $before =~ /\}/) {
+            my $this = pop(@UNMATCHED_OPENING);
+            print "\n *** matching brace \#$this found ***\n";
+            $before =~ s/\}/join("",$O,$this,$C)/eo;
+            $change = 1;
+        }
+        $_[0] = join('',$before,"\{",$after) if($change);
+        # MRO: mark one opening brace
+       if($_[0] =~ s/^([^{]*){/push(@processedB,$1);join('',$O,++$id,$C)/eos) {
+           $before=''; $after=$';
+        }
+        if ($after =~ /\}/) { 
+           $after =~ s/\}/join("",$O,$id,$C)/eo;
+           $_[0] = join('',$before,$O,$id,$C,$after);
+       } else {
+           print "\n *** opening brace \#$id  is unmatched ***\n";
+           $after =~ /^(.+\n)(.+\n)?/;
+           print " preceding: $after \n";
+           push (@UNMATCHED_OPENING,$id);
+       }
+    }
+    $_[0] = join('',@processedB,$_[0]); undef(@processedB);
+    print STDOUT "\nInfo: bracketings found: ", $id - $prev_id,"\n"
+        if ($VERBOSITY > 1);
+    # process remaining closing braces
+    while (@UNMATCHED_OPENING && $_[0] =~ /\}/) {
+        my $this = pop(@UNMATCHED_OPENING);
+        print "\n *** matching brace \#$this found ***\n";
+       $_[0] =~ s/\}/join("",$O,$this,$C)/eo;
+    }
+
+    while ($_[0] =~ /\}/) {
+        print "\n *** there was an unmatched closing \} ";
+        my ($beforeline,$prevline,$afterline) = ($`, $`.$& , $');
+        $prevline =~ /\n([^\n]+)\}$/m;
+        if ($1) {
+           print "at the end of:\n" . $1 . "\}\n\n";
+        } else {
+           $afterline =~ /^([^\n]+)\n/m;
+           if ($1) {
+               print "at the start of:\n\}" . $1 ."\n\n";
+           } else {
+               $prevline =~ /\n([^\n]+)\n\}$/m;
+               print "on a line by itself after:\n" . $1 . "\n\}\n\n";
+           }
+        }
+        $_[0] =  $beforeline . $afterline;
+    }
+    $global{'max_id'} = $id;
+
+    # restore escaped braces
+    $_[0] =~ s/tex2html_escaped_opening_bracket/\\{/go;
+    $_[0] =~ s/tex2html_escaped_closing_bracket/\\}/go;
+}
+
+sub replace_html_special_chars {
+    # Replaces html special characters with markers unless preceded by "\"
+    s/([^\\])(<|>|&|\"|``|'')/&special($1).&special($2)/geom;
+    # MUST DO IT AGAIN JUST IN CASE THERE ARE CONSECUTIVE HTML SPECIALS
+    s/([^\\])(<|>|&|\"|``|'')/&special($1).&special($2)/geom;
+    s/^(<|>|&|\"|``|'')/&special($1)/geom;
+}
+
+#  used in \verbatiminput only:   $html_escape_chars = '<>&';
+sub replace_all_html_special_chars { s/([$html_escape_chars])/&special($1)/geom; }
+
+# The bibliography and the index should be treated as separate sections
+# in their own HTML files. The \bibliography{} command acts as a sectioning command
+# that has the desired effect. But when the bibliography is constructed
+# manually using the thebibliography environment, or when using the
+# theindex environment it is not possible to use the normal sectioning
+# mechanism. This subroutine inserts a \bibliography{} or a dummy
+# \textohtmlindex command just before the appropriate environments
+# to force sectioning.
+sub add_bbl_and_idx_dummy_commands {
+    local($id) = $global{'max_id'};
+
+    s/([\\]begin\s*$O\d+$C\s*thebibliography)/$bbl_cnt++; $1/eg;
+    ## if ($bbl_cnt == 1) {
+       s/([\\]begin\s*$O\d+$C\s*thebibliography)/$id++; "\\bibliography$O$id$C$O$id$C $1"/geo;
+    #}
+    $global{'max_id'} = $id;
+    s/([\\]begin\s*$O\d+$C\s*theindex)/\\textohtmlindex $1/o;
+    s/[\\]printindex/\\textohtmlindex /o;
+    &lib_add_bbl_and_idx_dummy_commands() if defined(&lib_add_bbl_and_idx_dummy_commands);
+}
+
+
+# Uses and modifies $default_language
+# This would be straight-forward except when there are
+#  \MakeUppercase, \MakeLowercase  or \uppercase , \lowercase commands
+# present in the source. The cases have to be adjusted before the
+# ISO-character code is set; e.g. with "z --> "Z  in  german.perl
+#
+sub convert_iso_latin_chars {
+    local($_) = @_;
+    local($next_language, $pattern);
+    local($xafter, $before, $after, $funct, $level, $delim);
+    local(@case_processed);
+    while (/$case_change_rx/) {
+       $xafter = $2;
+#      $before .= $`;
+       push(@case_processed, $`);
+       $funct = $3;
+       $after = '';
+       $_ = $';
+       if ($xafter =~ /noexpand/) { $before .= "\\$funct"; next; }
+
+       s/^[\s%]*(.)/$delim=$1;''/eo;
+       if ($delim =~ /{/ ) {
+            # brackets not yet numbered...
+#          $before .= $funct . $delim;
+           push(@case_processed, $funct . $delim);
+           $level = 1;
+           $after = $delim;
+           while (($level)&&($_)&&(/[\{\}]/)) {
+               $after .= $` . $&;
+               $_ = $';
+               if ( "$&" eq "\{" ) {$level++}
+               elsif ( "$&" eq "\}" ) { $level-- }
+               else { print $_ }
+               print "$level";
+           } 
+#          $before .= $after;
+           push(@case_processed, $after);
+       } elsif ($delim eq "<") {
+            # brackets numbered, but maybe not processed...
+           s/((<|#)(\d+)(>|#)>).*\1//;
+           $after .= $delim . $&;
+           $_ = $';
+           print STDOUT "\n<$2$funct$4>" if ($VERBOSITY > 2);
+           $funct =~ s/^\\//o;
+           local($cmd) = "do_cmd_$funct";
+           $after = &$cmd($after);
+#          $before .= $after;
+           push(@case_processed, $after);
+       } elsif (($xafter)&&($delim eq "\\")) {
+           # preceded by \expandafter ...
+           # ...so expand the following macro first
+           $funct =~ s/^\\//o;
+           local($case_change) = $funct;
+           s/^(\w+|\W)/$funct=$1;''/eo;
+           local($cmd) = $funct;
+           local($thiscmd) = "do_cmd_$funct";
+           if (defined &$thiscmd) { $_ = &$thiscmd($_) }
+           elsif ($new_command{$funct}) { 
+               local($argn, $body, $opt) = split(/:!:/, $new_command{$funct});
+               do { ### local($_) = $body;
+                    &make_unique($body);
+               } if ($body =~ /$O/);
+               if ($argn) {
+                   do { 
+                       local($before) = '';
+                       local($after) = "\\$funct ".$_;
+                       $after = &substitute_newcmd;   # may change $after
+                       $after =~ s/\\\@#\@\@/\\/o ;
+                   }
+               } else { $_ = $body . $_; }
+           } else { print "\nUNKNOWN COMMAND: $cmd "; }
+
+           $cmd = $case_change;
+           $case_change = "do_cmd_$cmd";
+           if (defined &$case_change) { $_ = &$case_change($_) }
+       } else {
+            # this should not happen, but just in case...
+           $funct =~ s/^\\//o;
+           local($cmd) = "do_cmd_$funct";
+           print STDOUT "\n\n<$delim$funct>" if ($VERBOSITY > 2);
+           $_ = join('', $delim , $_ );
+           if (defined &$cmd) { $_ = &$cmd($_) }
+       }
+    }
+#   $_ = join('', $before, $_) if ($before);
+    $_ = join('', @case_processed, $_) if (@case_processed);
+
+    # ...now do the conversions
+    ($before, $after, $funct) = ('','','');
+    @case_processed = ();
+    if (/$language_rx/o) {
+       ($next_language, $pattern, $before, $after) = (($2||$1), $&, $`, $');
+       $before = &convert_iso_latin_chars($before) if ($before);
+#      push(@case_processed, $pattern, $before);
+       local($br_id) = ++$global{'max_id'};
+       $pattern = join('' , '\selectlanguage', $O.$br_id.$C
+           , (($pattern =~ /original/) ? $TITLES_LANGUAGE : $next_language )
+           , $O.$br_id.$C );
+       push(@case_processed, $before, $pattern);
+       push(@language_stack, $default_language);
+       $default_language = $next_language;
+       $_ = &convert_iso_latin_chars($after);
+       $default_language = pop @language_stack;
+    } else {
+       $funct = $language_translations{$default_language};
+       (defined(&$funct) ? $_ = &$funct($_) :
+        do {   &write_warnings(
+               "\nCould not find translation function for $default_language.\n\n")
+           }
+       );
+       if ($USE_UTF ||(!$NO_UTF &&(defined %unicode_table)&&length(%unicode_table)>2)) {
+           &convert_to_unicode($_)};
+    }
+    $_ = join('', @case_processed, $_); undef(@case_processed);
+    $_;
+}
+
+# May need to add something here later
+sub english_translation { $_[0] }
+
+# This replaces \setlanguage{\language} with \languageTeX
+# This makes the identification of language chunks easier.
+sub normalize_language_changes {
+    s/$setlanguage_rx/\\$2TeX/gs;
+}
+
+sub get_current_language {
+    return () if ($default_language eq $TITLES_LANGUAGE);
+    local($lang,$lstyle) = ' LANG="';
+    $lang_code = $iso_languages{$default_language};
+    if (%styled_languages) {
+       $lstyle = $styled_languages{$default_language};
+       $lstyle = '" CLASS="'.$lstyle  if $lstyle;
+    }
+    ($lang_code ? $lang.$lang_code.$lstyle.'"' : '');
+}
+
+%styled_languages = ();
+
+sub do_cmd_htmllanguagestyle {
+    local($_) = @_;
+    local($class) = &get_next_optional_argument;
+    local($lang) = &missing_braces unless (
+       (s/$next_pair_pr_rx/$lang=$2;''/e)
+       ||(s/$next_pair_rx/$lang=$2;''/e));
+    return ($_) unless $lang;
+    local($class) = $iso_languages{$lang} unless $class;
+    if ($USING_STYLES && $class) {
+       print "\nStyling language: $lang = \"$class\" ";
+       $styled_languages{"$lang"} = $class;
+    }
+    $_;
+}
+
+# General translation mechanism:
+#
+#
+# The main program latex2html calls texexpand with the document name
+# in order to expand some of its \input and \include statements, here
+# also called 'merging', and to write a list of sensitized style, class,
+# input, or include file names.
+# When texexpand has finished, all is contained in one file, TMP_foo.
+# (assumed foo.tex is the name of the document to translate).
+#
+# In this version, texexpand cares for following environments
+# that may span include files / section boundaries:
+# (For a more technical description, see texexpand.)
+#  a) \begin{comment}
+#  b) %begin{comment}
+#  c) \begin{any}  introduced with \excludecomment
+#  d) %begin{any}
+#  e) \begin{verbatim}
+#  f) \begin{latexonly}
+#  g) %begin{latexonly}
+# 
+# a)-d) cause texexpand to drop its contents, it will not show up in the
+# output file. You can use this to 'comment out' a bunch of files, say.
+# 
+# e)-g) prevent texexpand from expanding input files, but the environment
+# content goes fully into the output file.
+# 
+# Together with each merging of \input etc. there are so-called %%%texexpand
+# markers accompanying the boundary.
+#
+# When latex2html reads in the output file, it uses these markers to write
+# each part to a separate file, and process them further.
+#
+#
+# If you have, for example:
+#
+# a) preample
+# b) \begin{document}
+# c) text
+# d) \input{chapter}
+# e) more text
+# f) \end{document}
+#
+# you end up in two parts, part 1 is a)-c), part 2 is the rest.
+# Regardless of environments spanning input files or sections.
+#
+#
+# What now starts is meta command substitution:
+# Therefore, latex2html forks a child process on the first part and waits
+# until it finished, then forks another on the next part and so forth
+# (see also &slurp_input_and_partition_and_preprocess).
+#
+# Here's what each child is doing:
+# Each child process reads the new commands translated so far by the previous
+# child from the TMP_global DBM database.
+# After &pre_processing, it substitutes the meta commands (\newcommand, \def,
+# and the like) it finds, and adds the freshly retrieved new commands to the
+# list so far.
+# This is done *only on its part* of the document; this saves upwards of memory.
+# Finally, it writes its list of new commands (synopsis and bodies) to the
+# DBM database, and exits.
+# After the last child finished, latex2html reads in all parts and
+# concatenates them.
+#
+#
+# So, at this point in time (start of &translate), it again has the complete
+# document, but now preprocessed and with new commands substituted.
+# This has several disadvantages: an amount of commands is substituted (in
+# TeX lingo, expanded) earlier than the rest.
+# This causes trouble if commands really must get expanded at the point
+# in time they show up.
+#
+#
+# Then, still in &translate, latex2html uses the list of section commands to
+# split the complete document into chunks.
+# The chunks are not written to files yet. They are retained in the @sections
+# list, but each chunk is handled separately.
+# latex2html puts the current chunk to $_ and processes it with
+# &translate_environments etc., then fetches the next chunk, and so on.
+# This prevents environments that span section boundaries from getting
+# translated, because \begin and \end cannot find one another, to say it this
+# way.
+#
+#
+# After the chunk is translated to HTML, it is written to a file.
+# When all chunks are done, latex2html rereads each file to get cross
+# references right, replace image markers with the image file names, and
+# writes index and bibliography.
+#
+#
+sub translate {
+    &normalize_sections;       # Deal with the *-form of sectioning commands
+
+    # Split the input into sections, keeping the preamble together
+    # Due to the regular expression, each split will create 5 more entries.
+    # Entry 1 and 2: non-letter/letter sectioning command,
+    # entry 4: the delimiter (may be empty)
+    # entry 5: the text.
+    local($pre_section, @sections);
+    if (/\\(startdocument|begin\s*($O\d+$C)\s*document\s*\2)/) {
+       $pre_section = $`.$&; $_ = $';
+    }
+    @sections = split(/$sections_rx/, $_);
+    $sections[0] = $pre_section.$sections[0] if ($pre_section);
+    undef $pre_section;
+    local($sections) = int(scalar(@sections) / 5);
+
+    # Initialises $curr_sec_id to a list of 0's equal to
+    # the number of sectioning commands.
+    local(@curr_sec_id) = split(' ', &make_first_key);
+    local(@segment_sec_id) = @curr_sec_id;
+    local($i, $j, $current_depth) = (0,0,0);
+    local($curr_sec) = $SHORT_FILENAME||$FILE;
+    local($top_sec) = ($SEGMENT ? '' : 'top of ');
+#    local(%section_info, %toc_section_info, $CURRENT_FILE, %cite_info, %ref_files);
+    local($CURRENT_FILE);
+    # These filenames may be set when translating the corresponding commands.
+    local($tocfile, $loffile, $lotfile, $footfile, $citefile, $idxfile,
+         $figure_captions, $table_captions, $footnotes, $citations, %font_size, %index,
+         %done, $t_title, $t_author, $t_date, $t_address, $t_affil, $changed);
+    local(@authors,@affils,@addresses,@emails,@authorURLs);
+    local(%index_labels, %index_segment, $preindex, %footnotes, %citefiles);
+    local($segment_table_captions, $segment_figure_captions);
+    local($dir,$nosave) = ('','');
+    local($del,$close_all,$open_all,$toc_sec_title,$multiple_toc);
+    local($open_tags_R) = [];
+    local(@save_open_tags)= ();
+    local(@language_stack) = ();
+    push (@language_stack, $default_language);
+
+#    $LATEX_FONT_SIZE = '10pt' unless ($LATEX_FONT_SIZE);
+    &process_aux_file 
+       if $SHOW_SECTION_NUMBERS || /\\(caption|(html|hyper)?((eq)?ref|cite))/;
+
+    require ("${PREFIX}internals.pl") if (-f "${PREFIX}internals.pl");
+#JCL(jcl-del)
+    &make_single_cmd_rx;
+#
+    $tocfile = $EXTERNAL_CONTENTS;
+    $idxfile = $EXTERNAL_INDEX;
+    $citefile = $EXTERNAL_BIBLIO; $citefile =~ s/#.*$//;
+    $citefiles{1} = $citefile if ($citefile);
+    print "\nTranslating ...";
+
+    while ($i <= @sections) {
+        undef $_;
+       $_ = $sections[$i];
+       s/^[\s]*//;             # Remove initial blank lines
+
+       # The section command was removed when splitting ...
+       s/^/\\$curr_sec$del/  if ($i > 0); # ... so put it back
+       if ($current_depth < $MAX_SPLIT_DEPTH)  {
+           if (($footnotes)&&($NO_FOOTNODE)&&( $current_depth < $MAX_SPLIT_DEPTH)) {
+               local($thesenotes) = &make_footnotes ;
+               print OUTPUT $thesenotes;
+           }
+           $CURRENT_FILE = &make_name($curr_sec, join('_',@curr_sec_id));
+           
+           open(OUTPUT, ">$CURRENT_FILE")
+               || die "Cannot write '$CURRENT_FILE': $!\n";
+           if ($XBIT_HACK) { # use Apache's XBit hack
+               chmod 0744, $CURRENT_FILE;
+               &check_htaccess;
+           } else {
+               chmod 0644, $CURRENT_FILE;
+           }
+
+           if ($MULTIPLE_FILES && $ROOTED) {
+               if ($DESTDIR =~ /^\Q$FIXEDDIR\E[$dd$dd]?([^$dd$dd]+)/)
+                   { $CURRENT_FILE = "$1$dd$CURRENT_FILE" };
+           }
+       }
+       &remove_document_env;
+#        &wrap_shorthand_environments;    #RRM  Is this needed ?
+       print STDOUT "\n" if ($VERBOSITY);
+       print STDOUT "\n" if ($VERBOSITY > 2);
+       print $i/5,"/$sections";
+       print ":$top_sec$curr_sec:" if ($VERBOSITY);
+
+       # Must do this early ... It also sets $TITLE
+       &process_command($sections_rx, $_) if (/^$sections_rx/);
+       # reset tags saved from the previous section
+       $open_tags_R = [ @save_open_tags ];
+       @save_open_tags = ();
+
+       local($curr_sec_tex);
+       if ((! $TITLE) || ($TITLE eq $default_title)) {
+           eval '$TITLE = '.$default_title;
+           $TITLE = $default_title if $@;
+           $curr_sec_tex = ($top_sec ? '' :
+                 join('', '"', &revert_to_raw_tex($curr_sec), '"'));
+           print STDOUT "$curr_sec_tex for $CURRENT_FILE\n" if ($VERBOSITY);
+       } else { 
+           local($tmp) = &purify($TITLE,1);
+           $tmp = &revert_to_raw_tex($tmp);
+           print STDOUT "\"$tmp\" for $CURRENT_FILE\n" if ($VERBOSITY); 
+       }
+
+       if (/\\(latextohtmlditchpreceding|startdocument)/m) {
+           local($after) = $';
+           local($before) = $`.$&;
+           $SEGMENT = 1 if ($1 =~ /startdocument/);
+           print STDOUT "\n *** translating preamble ***\n" if ($VERBOSITY);
+           $_ = &translate_preamble($before);
+           s/\n\n//g; s/<BR>//g;       # remove redundant blank lines and breaks
+#
+#          &process_aux_file  if $AUX_FILE_NEEDED;
+#
+           print STDOUT "\n *** preamble done ***\n" if ($VERBOSITY);
+           $PREAMBLE = 0;
+           $NESTING_LEVEL=0;
+           &do_AtBeginDocument;
+           $after =~ s/^\s*//m;
+           print STDOUT (($VERBOSITY >2)? "\n*** Translating environments ***" : ";");
+           $after = &translate_environments($after);
+           print STDOUT (($VERBOSITY >2)? "\n*** Translating commands ***" : ";");
+           $_ .= &translate_commands($after);
+#            $_ = &translate_commands($after);
+       } else {
+           &do_AtBeginDocument;
+           $PREAMBLE = 0;
+           $NESTING_LEVEL=0;
+           print STDOUT (($VERBOSITY >2)? "\n*** Translating environments ***" : ";");
+           $_ = &translate_environments($_);
+           print STDOUT (($VERBOSITY >2)? "\n*** Translating commands ***" : ";");
+           $_ = &translate_commands($_);
+       }
+
+       # close any tags that remain open
+       if (@$open_tags_R) {
+           ($close_all,$open_all) = &preserve_open_tags();
+           $_ .= $close_all; 
+           @save_open_tags = @$open_tags_R; $open_tags_R = [];
+       } else { ($close_all,$open_all) = ('','') }
+
+       print STDOUT (($VERBOSITY >2)? "\n*** Translations done ***" : "\n");
+#      if (($footnotes)&&($NO_FOOTNODE)&&( $current_depth < $MAX_SPLIT_DEPTH)) {
+#          $_ .= &make_footnotes
+#      }
+       print OUTPUT $_;
+
+       # Associate each id with the depth, the filename and the title
+       ###MEH -- starred sections don't show up in TOC ...
+       # RRM:  ...unless $TOC_STARS is set
+#      $toc_sec_title = &simplify($toc_sec_title);
+       $toc_sec_title = &purify($toc_sec_title);# if $SEGMENT;
+       $toc_sec_title = &purify($TITLE) unless ($toc_sec_title);       
+
+       if ($TOC_STARS) {
+           $toc_section_info{join(' ',@curr_sec_id)} =
+               "$current_depth$delim$CURRENT_FILE$delim$toc_sec_title"
+#                  if ($current_depth <= $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH);
+                   if ($current_depth <= $TOC_DEPTH);
+       } else {
+           $toc_section_info{join(' ',@curr_sec_id)} =
+               "$current_depth$delim$CURRENT_FILE$delim$toc_sec_title"
+               . ($curr_sec =~ /star$/ ? "$delim<tex2html_star_mark>" : "")
+#                  if ($current_depth <= $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH);
+                   if ($current_depth <= $TOC_DEPTH);
+       }
+
+       # include $BODYTEXT in the section_info, when starting a new page
+       $section_info{join(' ',@curr_sec_id)} =
+           "$current_depth$delim$CURRENT_FILE$delim$TITLE$delim"
+               . (($current_depth < $MAX_SPLIT_DEPTH)? $BODYTEXT: "");
+
+       # Get type of section (see also the split above)
+       $curr_sec = $sections[$i+1].$sections[$i+2];
+       $del = $sections[$i+4];
+
+       # Get the depth of the current section;
+#      $curr_sec = $outermost_level unless $curr_sec;
+       $current_depth = $section_commands{$curr_sec};
+       if ($after_segment) {
+           $current_depth = $after_segment;
+            $curr_sec_id[$after_segment] += $after_seg_num;
+            ($after_segment,$after_seg_num) = ('','');
+           for($j=1+$current_depth; $j <= $#curr_sec_id; $j++) {
+               $curr_sec_id[$j] = 0;
+           }
+       }
+       if ($SEGMENT||$SEGMENTED) {
+           for($j=1; $j <= $#curr_sec_id; $j++) {
+               $curr_sec_id[$j] += $segment_sec_id[$j];
+               $segment_sec_id[$j] = 0;
+           }
+       }; 
+
+
+       # this may alter the section-keys
+       $multiple_toc = 1 if ($MULTIPLE_FILES && $ROOTED && (/$toc_mark/));
+
+
+       #RRM : Should this be done here, or in \stepcounter ?
+       @curr_sec_id = &new_level($current_depth, @curr_sec_id);
+
+       $toc_sec_title = $TITLE = $top_sec = '';
+       $i+=5; #skip to next text section
+    }
+    $open_tags_R = [];
+    $open_all = '';
+
+    $_ = undef;
+    $_ = &make_footnotes if ($footnotes);
+    $CURRENT_FILE = '';
+    print OUTPUT;
+    close OUTPUT;
+    
+
+#    # this may alter the section-keys
+#    &adjust_root_keys if $multiple_toc;
+
+    if ($PREPROCESS_IMAGES) { &preprocess_images }
+    else { &make_image_file }
+    print STDOUT "\n *** making images ***" if ($VERBOSITY > 1);
+    &make_images;
+
+    # Link sections, add head/body/address do cross-refs etc
+    print STDOUT "\n *** post-process ***" if ($VERBOSITY > 1);
+    &post_process;
+
+    if (defined &document_post_post_process) {
+       #BRM: extra document-wide post-processing
+       print STDOUT "\n *** post-processing Document ***" if ($VERBOSITY > 1);
+       &document_post_post_process();
+    }
+
+    print STDOUT "\n *** post-processed ***" if ($VERBOSITY > 1);
+    &copy_icons if $LOCAL_ICONS;
+    if ($SEGMENT || $DEBUG || $SEGMENTED) {
+       &save_captions_in_file("figure",  $figure_captions) if $figure_captions;
+       &save_captions_in_file("table",  $table_captions) if $table_captions;
+#      &save_array_in_file ("captions", "figure_captions", 0, %figure_captions) if %figure_captions;
+#      &save_array_in_file ("captions", "table_captions", 0, %table_captions) if %table_captions;
+       &save_array_in_file ("index", "index", 0, %index);
+       &save_array_in_file ("sections", "section_info", 0, %section_info);
+       &save_array_in_file ("contents", "toc_section_info", 0,%toc_section_info);
+       &save_array_in_file ("index", "sub_index", 1, %sub_index) if %sub_index;
+       &save_array_in_file ("index", "index_labels", 1, %index_labels) if %index_labels;
+       &save_array_in_file ("index", "index_segment", 1, %index_segment) if %index_segment;
+       &save_array_in_file ("index", "printable_key", 1, %printable_key) 
+           if (%printable_key || %index_segment);
+    }
+    elsif ($MULTIPLE_FILES && $ROOTED) {
+       &save_array_in_file ("sections", "section_info", 0, %section_info);
+       &save_array_in_file ("contents", "toc_section_info", 0, %toc_section_info);
+    }
+    &save_array_in_file ("internals", "ref_files", 0, %ref_files) if $changed;
+    &save_array_in_file ("labels", "external_labels", 0, %ref_files);
+    &save_array_in_file ("labels", "external_latex_labels", 1, %latex_labels);
+    &save_array_in_file ("images", "cached_env_img", 0, %cached_env_img);
+}
+
+# RRM:
+sub translate_preamble {
+    local($_) = @_;
+    $PREAMBLE = 1;
+    $NESTING_LEVEL=0;   #counter for TeX group nesting level
+    # remove some artificially inserted constructions
+    s/\n${tex2html_deferred_rx}\\par\s*${tex2html_deferred_rx2}\n/\n/gm;
+    s/\\newedcommand(<<\d+>>)([A-Za-z]+|[^A-Za-z])\1(\[\d+\])?(\[[^]]*\])?(<<\d+>>)[\w\W\n]*\5($comment_mark\d*)?//gm;
+    s/\n{2,}/\n/ogm;
+
+    if (/\\htmlhead/) {
+        print STDOUT "\nPREAMBLE: discarding...\n$`" if ($VERBOSITY > 4);
+        local($after) = $&.$';
+       # translate segment preamble preceding  \htmlhead
+       &translate_commands(&translate_environments($`));
+       # translate \htmlhead  and rest of preamble
+       $_=&translate_commands(&translate_environments($after));
+        print STDOUT "\nPREAMBLE: retaining...\n$_" if ($VERBOSITY > 4);
+    } else {
+       # translate only preamble here (metacommands etc.)
+       # there should be no textual results, if so, discard them
+       &translate_commands(&translate_environments($_));
+        print STDOUT "\nPREAMBLE: discarding...\n$_" if ($VERBOSITY > 4);
+       $_="";
+    };
+    $_ = &do_AtBeginDocument($_);
+    if (! $SEGMENT) { $_ = ''} # segmented documents have a heading already
+    $_;
+}
+
+############################ Processing Environments ##########################
+
+sub wrap_shorthand_environments {
+    # This wraps a dummy environment around environments that do not use
+    # the begin-end convention. The wrapper will force them to be
+    # evaluated by Latex rather than them being translated.
+    # Wrap a dummy environment around matching TMPs.
+    # s/^\$\$|([^\\])\$\$/{$1.&next_wrapper('tex2html_double_dollar')}/ge;
+    # Wrap a dummy environment around matching $s.
+    # s/^\$|([^\\])\$/{$1.&next_wrapper('$')}/ge;
+    # s/tex2html_double_dollar/\$\$/go;
+    # Do \(s and \[s
+    #
+    local($wrapper) = "tex2html_wrap_inline";  # \ensuremath wrapper
+    print STDOUT "\n *** wrapping environments ***\n" if ($VERBOSITY > 3);
+
+    # MRO: replaced $* with /m
+    print STDOUT "\\(" if ($VERBOSITY > 3);
+    s/(^\\[(])|([^\\])(\\[(])/{$2.&make_any_wrapper(1,'',$wrapper).$1.$3}/geom;
+    print STDOUT "\\)" if ($VERBOSITY > 3);
+    s/(^\\[)]|[^\\]\\[)])/{$1.&make_any_wrapper(0,'',$wrapper)}/geom;
+
+    print STDOUT "\\[" if ($VERBOSITY > 3);
+    s/(^\\[[])|([^\\])(\\[[])/{$2.&make_any_wrapper(1,1,"displaymath")}/geom;
+    print STDOUT "\\]" if ($VERBOSITY > 3);
+    s/(^\\[\]])|([^\\])(\\[\]])/{$2.&make_any_wrapper(0,1,"displaymath")}/geom;
+
+    print STDOUT "\$" if ($VERBOSITY > 3);
+    s/$enspair/print "\$";
+       {&make_any_wrapper(1,'',$wrapper).$&.&make_any_wrapper(0,'',$wrapper)}/geom;
+
+    $double_dol_rx = '(^|[^\\\\])\\$\\$';
+    $single_dol_rx = '(^|[^\\\\])\\$';
+    print STDOUT "\$" if ($VERBOSITY > 3);
+
+    local($dollars_remain) = 0;
+    $_ = &wrap_math_environment;
+    $_ = &wrap_raw_arg_cmds;
+}
+
+sub wrap_math_environment {
+
+    # This wraps math-type environments
+    # The trick here is that the opening brace is the same as the close,
+    # but they *can* still nest, in cases like this:
+    #
+    # $ outer stuff ... \hbox{ ... $ inner stuff $ ... } ... $
+    #
+    # Note that the inner pair of $'s is nested within a group.  So, to
+    # handle these cases correctly, we need to make sure that the outer
+    # brace-level is the same as the inner. --- rst
+    #tex2html_wrap
+    # And yet another problem:  there is a scungy local idiom to do
+    # this:  $\_$ for a boldfaced underscore.  xmosaic can't display the
+    # resulting itty-bitty bitmap, for some reason; even if it could, it
+    # would probably come out as an overbar because of the floating-
+    # baseline problem.  So, we have to special case this.  --- rst again.
+
+    local ($processed_text, @processed_text, $before, $end_rx, $delim, $ifclosed);
+    local ($underscore_match_rx) = "^\\s*\\\\\\_\\s*\\\$";
+    local ($wrapper);
+    print STDOUT "\nwrap math:" if ($VERBOSITY > 3);
+
+    #find braced dollars, in tabular-specs
+    while (/((($O|$OP)\d+($C|$CP))\s*)\$(\s*\2)/) {
+        push (@processed_text, $`, $1.$dol_mark.$5);
+        $_ = $';
+    }
+    $_ = join('',@processed_text, $_) if (@processed_text);
+    undef @processed_text;
+
+    $dollars_remain = 0;
+    while (/$single_dol_rx/) {
+       $processed_text .= $`.$1;
+       $_ = $';
+       $wrapper = "tex2html_wrap_inline";
+       $end_rx = $single_dol_rx; # Default, unless we begin with $$.
+       $delim = "\$";
+
+        if (/^\$/ && (! $`)) {
+           s/^\$//;
+           $end_rx = $double_dol_rx;
+           $delim = "";        # Cannot say "\$\$" inside displaymath
+           $wrapper = "displaymath";
+
+        } elsif (/$underscore_match_rx/ && (! $`)) {
+
+            # Special case for $\_$ ...
+
+            s/$underscore_match_rx//;
+            $processed_text .= '\\_';
+            next;
+        }
+
+        # Have an opening $ or $$.  Find matching close, at same bracket level
+#      $processed_text .= &make_any_wrapper(1,'',$wrapper).$delim;
+
+       print STDOUT "\$" if ($VERBOSITY > 3);
+       $ifclosed = 0;
+       local($thismath);
+        while (/$end_rx/) {
+           # Forget the $$ if we are going to replace it with "displaymath"
+            $before = $` . (($wrapper eq "displaymath")? "$1" : $&);
+           last if ($before =~ /\\(sub)*(item|section|chapter|part|paragraph)(star)?\b/);
+           $thismath .= $before;
+            $_ = $';
+           s/^( [^\n])/\\space$1/s;  #make sure a trailing space doesn't get lost.
+
+            # Found dollar sign inside open subgroup ... now see if it's
+            # at the same brace-level ...
+
+            local ($losing, $br_rx) = (0, '');
+           print STDOUT "\$" if ($VERBOSITY > 3);
+            while ($before =~ /$begin_cmd_rx/) {
+                $br_rx = &make_end_cmd_rx($1);  $before = $';
+
+                if ($before =~ /$br_rx/) { $before = $'; }
+                else { $losing = 1; last; }
+            }
+            do { $ifclosed = 1; last } unless $losing;
+
+            # It wasn't ... find the matching close brace farther on; then
+            # keep going.
+
+            /$br_rx/;
+
+            $thismath .= $`.$&;
+
+           #RRM: may now contain unprocessed $s e.g. $\mbox{...$...$...}$
+           # the &do_cmd_mbox uses this specially to force an image
+           # ...but there may be other situations; e.g. \hbox
+           # so set a flag:
+           $dollars_remain = 1;
+
+            $_ = $';
+        }
+
+        # Got to the end.  Whew!
+       if ($ifclosed) {
+           # also process any nested math
+           while (($dollars_remain)&&($delim eq "\$")) {
+               local($saved) = $_;
+                $thismath =~ s/\$$//;
+                $_ = $thismath;
+               $thismath =  &wrap_math_environment;
+               $thismath .= "\$";
+               $_ = $saved;
+           }
+           $processed_text .= &make_any_wrapper(1,'',$wrapper) . $delim 
+               . $thismath . &make_any_wrapper(0,'',$wrapper);
+       } else {
+           print STDERR "\n\n *** Error: unclosed math or extra `\$', before:\n$thismath\n\n";
+#          # remove a $ to try to recover as much as possible.
+#          $thismath =~ s/([^\\]\\\\|[^\\])\$/$1\%\%/;
+#          $_ = $thismath . $_; $thismath = "";
+       print "\n$thismath\n\n\n$_\n\n\n"; die;
+           
+       }
+    }
+    $processed_text . $_;
+}
+
+sub translate_environments {
+    local ($_) = @_;
+    local($tmp, $capenv);
+#   print "\nTranslating environments ...";
+    local($after, @processedE);
+    local ($contents, $before, $br_id, $env, $pattern);
+    for (;;) {
+#      last unless (/$begin_env_rx/o);
+       last unless (/$begin_env_rx|$begin_cmd_rx|\\(selectlanguage)/o);
+#      local ($contents, $before, $br_id, $env, $pattern);
+       local($this_env, $opt_arg, $style_info);
+       $contents = '';
+       # $1,$2 : optional argument/text --- stylesheet info
+       # $3 : br_id (at the beginning of an environment name)
+       # $4 : environment name
+       # $5 : br_id of open-brace, when $3 == $4 == '';
+       # $6 : \selectlanguage{...}
+       if ($7) {
+           push(@processedE,$`);
+           $_ = $';
+           if (defined &do_cmd_selectlanguage) {
+               $_ = &do_cmd_selectlanguage($_);
+           } else {
+               local($cmd) = $7;
+               $pattern = &missing_braces unless (
+                   s/$next_pair_rx/$pattern = $2;''/e);
+               local($trans) = $pattern.'_translation';
+               if (defined &$trans) {
+                   &set_default_language($pattern,$_);
+               }
+               undef $cmd; undef $trans;
+           }
+           next;
+       } elsif ($4) {
+           ($before, $opt_arg, $style_info, $br_id
+                , $env, $after, $pattern) = ($`, $2, $3, $4, $5, $', $&);
+           if (($before)&& (!($before =~ /$begin_env_rx|$begin_cmd_rx/))) {
+               push(@processedE,$before);
+               $_ = $pattern . $after; $before = '';
+           }
+       } else {
+           ($before, $br_id, $env, $after, $pattern) = ($`, $6, 'group', $', $&);
+           if (($before)&& (!($before =~ /$begin_env_rx|$begin_cmd_rx/))) {
+               push(@processedE,$before);
+               $_ = $pattern . $after; $before = '';
+           }
+           local($end_cmd_rx) = &make_end_cmd_rx($br_id);
+           if ($after =~ /$end_cmd_rx/) {
+               # ... find the the matching closing one
+               $NESTING_LEVEL++;
+               ($contents, $after) = ($`, $');
+               $contents = &process_group_env($contents);
+               print STDOUT "\nOUT: {$br_id} ".length($contents) if ($VERBOSITY > 3);
+               print STDOUT "\n:$contents\n" if ($VERBOSITY > 7);
+               # THIS MARKS THE OPEN-CLOSE DELIMITERS AS PROCESSED
+               $_ = join("", $before,"$OP$br_id$CP", $contents,"$OP$br_id$CP", $after);
+               $NESTING_LEVEL--;
+           } else {
+               $pattern = &escape_rx_chars($pattern);
+               s/$pattern//;
+               print "\nCannot find matching bracket for $br_id";
+               $_ = join("", $before,"$OP$br_id$CP", $after);
+           }
+           next;
+       }
+       $contents = undef;
+       local($defenv) = $env =~ /deferred/;
+#      local($color_env);
+       local($color_env)
+           unless ($env =~ /tabular|longtable|in(line|display)|math/);
+       local($closures,$reopens);
+       local(@save_open_tags) = @$open_tags_R unless ($defenv);
+       local($open_tags_R) = [ @save_open_tags ] unless ($defenv);
+       local(@saved_tags) if ($env =~ /tabular|longtable/);
+       if ($env =~ /tabular|longtable|makeimage|in(line|display)/) {
+           @save_open_tags = @$open_tags_R;
+           $open_tags_R = [ @save_open_tags ];
+           # check for color
+           local($color_test) = join(',',@$open_tags_R);
+           if ($color_test =~ /(color{[^}]*})/g ) {
+               $color_env = $1;
+           } # else { $color_env = '' }
+
+           if ($env =~ /tabular|longtable|makeimage/) {
+               # close to the surrounding block-type tag
+               ($closures,$reopens,@saved_tags) = &preserve_open_block_tags();
+               @save_open_tags = @$open_tags_R;
+               $open_tags_R = [ @save_open_tags ];
+               if ($color_env) {
+                   $color_test = join(',',@saved_tags);
+                   if ($color_test =~ /(color{[^}]*})/g ) {
+                       $color_env = $1;
+                   }
+               }
+           } elsif ($env =~ /in(line|display)/) {
+               $closures = &close_all_tags() if ((&defined_env($env))
+                   &&!($defenv)&&!($env=~/inline/)&&(!$declarations{$env}));
+               if ($color_env) {
+                   $color_test = $declarations{$color_env};
+                   $color_test =~ s/<\/.*$//;
+                   $closures .= "\n$color_test";
+                   push (@$open_tags_R , $color_env);          
+               }
+           }
+       } elsif ($env =~ /alltt|tex2html_wrap/) {
+           # alltt is constructed as paragraphs, not with <PRE>
+           #  tex2html_wrap  creates an image, which is at text-level
+       } else {
+           $closures = &close_all_tags() if ((&defined_env($env))
+               &&!($defenv)&&(!$declarations{$env}) );
+       }
+       # Sets $contents and modifies $after
+       if (&find_end_env($env,$contents,$after)) {
+           print STDOUT "\nIN-A {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
+           &process_command($counters_rx, $before)
+               if ($before =~ /$counters_rx/);
+           # This may modify $before and $after
+           # Modifies $contents
+#RRM: the do_env_... subroutines handle when to translate sub-environments
+#          $contents = &translate_environments($contents) if
+##             ((!$defenv) && (&defined_env($env)) && (! $raw_arg_cmds{$env})
+##             && (!$declarations{$env})
+#              ((&defined_env($env)) && (! $raw_arg_cmds{$env})
+#              && (!($env =~ /latexonly|enumerate|figure|table|makeimage|wrap_inline/))
+#              && ((! $NO_SIMPLE_MATH)||(!($env =~ /wrap/)))
+#              && (!($env =~ /(math|wrap|equation|eqnarray|makeimage|minipage|tabular)/) )
+#              );
+           if ($opt_arg) { 
+               &process_environment(1, $env, $br_id, $style_info); # alters $contents
+           } else {
+               &process_environment(0, $env, $br_id, '');
+           }
+           undef $_;
+           print STDOUT "\nOUT-A {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
+           #JCL(jcl-env) - insert the $O$br_id$C stuff to handle environment grouping
+           if (!($contents eq '')) {
+               $after =~ s/^\n//o if ($defenv);
+               $this_env = join("", $before, $closures
+                         , $contents
+                         , ($defenv ? '': &balance_tags())
+                         , $reopens ); $_ = $after;
+           } else { 
+               $this_env = join("", $before , $closures
+                         , ($defenv ? '': &balance_tags())
+                         , $reopens ); $_ = $after;
+           };
+       ### Evan Welsh <welsh@epcc.ed.ac.uk> added the next 24 lines ##
+       } elsif (&defined_env($env)) {
+           print STDOUT "\nIN-B {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
+           # If I specify a function for the environment then it
+           # calls it with the contents truncated at the next section.
+           # It assumes I know what I'm doing and doesn't give a
+           # deferred warning.
+           $contents = $after;
+           if ($opt_arg) { 
+               $contents = &process_environment(1, $env, $br_id, $style_info);
+           } else {
+               $contents = &process_environment(0, $env, $br_id, '');
+           }
+           print STDOUT "\nOUT-B {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
+           $this_env = join("", $before, $closures ,$contents, $reopens);
+
+           # there should not be anything left over 
+#          $_ = $after;
+           $_ = '';
+       } elsif ($ignore{$env}) {
+           print STDOUT "\nIGNORED {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
+           # If I specify that the environment should be ignored then
+           # it is but I get a deferred warning.
+           $this_env = join("", $before , $closures , &balance_tags()
+                     , $contents, $reopens );
+           $_ = $after;
+           &write_warnings("\n\\end{$env} not found (ignored).\n");
+       } elsif ($raw_arg_cmds{$env}) {
+           print "\nIN-C {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
+           # If I specify that the environment should be passed to tex
+           # then it is with the environment truncated at the next
+           # section and I get a deferred warning.
+
+           $contents = $after;
+           if ($opt_arg) { 
+               $contents = &process_environment(1, $env, $br_id, $style_info);
+           } else {
+               $contents = &process_environment(0, $env, $br_id, '');
+           }
+           print STDOUT "\nOUT-C {$env $br_id}\n$contents\n" if ($VERBOSITY > 4);
+           $this_env = join("", $before, $closures
+                            , $contents, &balance_tags(), $reopens );
+           $_='';
+           &write_warnings(
+               "\n\\end{$env $br_id} not found (truncated at next section boundary).\n");
+       } else {
+           $pattern = &escape_rx_chars($pattern);
+           s/$pattern/$closures/;
+           print "\nCannot find \\end{$env $br_id}\n";
+           $_ .= join('', &balance_tags(), $reopens) unless ($defenv);
+       }
+       if ($this_env =~ /$begin_env_rx|$begin_cmd_rx/) {
+           $_ = $this_env . $_;
+       } else { push (@processedE, $this_env) }
+    }
+    $_ = join('',@processedE) . $_;
+    $tmp = $_; undef $_;
+    &process_command($counters_rx, $tmp) if ($tmp =~ /$counters_rx/);
+    $_ = $tmp; undef $tmp;
+    $_
+}
+
+sub find_end_env {
+    # MRO: find_end_env($env,$contents,$rest)
+    #local ($env, *ref_contents, *rest) = @_;
+    my $env = $_[0];
+    my $be_rx = &make_begin_end_env_rx($env);
+    my $count = 1;
+
+    while ($_[2] =~ /($be_rx)(\n?)/s) { # $rest
+       $_[1] .= $`; # $contents
+
+       if ($2 eq "begin") { ++$count }
+       else { --$count };
+
+       #include any final \n at an {end} only
+       $_[2] = (($2 eq 'end')? $5 : '') . $'; # $rest
+       last if $count == 0;
+
+       $_[1] .= $1; # $contents
+    }
+
+    if ($count != 0) {
+       $_[2] = join('', $_[1], $_[2]); # $rest = join('', $contents, $rest);
+       $_[1] = ''; # $contents
+       return(0)
+    } else { return(1) }
+}
+
+
+sub process_group_env {
+    local($contents) = @_;
+    local(@save_open_tags) = @$open_tags_R;
+    local($open_tags_R) = [ @save_open_tags ];
+    print STDOUT "\nIN::{group $br_id}" if ($VERBOSITY > 4);
+    print STDOUT "\n:$contents\n" if ($VERBOSITY > 6);
+
+    # need to catch explicit local font-changes
+    local(%font_size) = %font_size if (/\\font\b/);
+
+    # record class/id info for a style-sheet entry
+    local($env_id, $tmp, $etmp);
+    if (($USING_STYLES) && !$PREAMBLE ) { $env_id = $br_id; }
+#      $env_id = "grp$br_id";
+#      $styleID{$env_id} = " ";
+#        $env_id = " ID=\"$env_id\"";
+#    }
+
+    undef $_;
+    $contents =~ s/^\s*$par_rx\s*//s; # don't start with a \par 
+    if ($contents =~ /^\s*\\($image_switch_rx)\b\s*/s) {
+       # catch TeX-like environments: {\fontcmd ... }
+       local($image_style) = $1;
+       if ($USING_STYLES) {
+           $env_style{$image_style} = " " unless ($env_style{$image_style});
+       }
+       local($switch_cmd) = "do_cmd_${image_style}";
+       if (defined &$switch_cmd ) {
+           eval "\$contents = \&${switch_cmd}(\$')";
+           print "\n*** &$switch_cmd didn't work: $@\n$contents\n\n" if ($@);
+       } elsif ($contents =~ /$par_rx/) {
+           # split into separate image for each paragraph
+           local($par_style,$this_par_img) = '';
+           local(@par_pieces) = split($par_rx, $contents);
+           local($this_par,$par_style,$par_comment);
+           $contents = '';
+           while (@par_pieces) {
+               $this_par = shift @par_pieces;
+               if ($this_par =~ /^\s*\\($image_switch_rx)\b/s) {
+                   $image_style = $1;
+                   $par_style = 'P.'.$1;
+                   $env_style{$par_style} = " " unless ($env_style{$par_style});
+               }
+#      no comment: source is usually too highly encoded to be meaningful
+#      $par_comment = &make_comment($image_style,$this_par);
+               $this_par_img = &process_in_latex("\{".$this_par."\}");
+               $contents .=  join(''  #,"\n", $par_comment
+                       , "\n<P"
+                       , (($USING_STYLES && $image_style)? " CLASS=\"$image_style\"" :'')
+                       ,">", $this_par_img
+                       , "</P>\n");
+               if (@par_pieces) {
+                   # discard the pieces from matching  $par_rx
+                   $dum = shift @par_pieces;
+                   $dum = shift @par_pieces;
+                   $dum = shift @par_pieces;
+                   $dum = shift @par_pieces;
+                   $dum = shift @par_pieces;
+                   $dum = shift @par_pieces;
+#                  $contents .= "\n</P>\n<P>";
+               }
+           }
+       } else {
+           $contents = &process_undefined_environment("tex2html_accent_inline"
+               , ++$global{'max_id'},"\{".$contents."\}");
+        }
+    } elsif ($contents =~ /^\s*\\(html)?url\b($O\d+$C)[^<]*\2\s*/) {
+       # do nothing
+       $contents = &translate_environments($contents);
+       $contents = &translate_commands($contents);
+    } elsif (($env_switch_rx)&&($contents =~ s/^(\s*)\\($env_switch_rx)\b//s)) {
+       # write directly into images.tex, protected by \begingroup...\endgroup
+       local($prespace, $cmd, $tmp) = ($1,$2,"do_cmd_$2");
+       $latex_body .= "\n\\begingroup ";
+       if (defined &$tmp) {
+           eval("\$contents = &do_cmd_$cmd(\$contents)");
+       }
+       $contents = &translate_environments($contents);
+       $contents = &translate_commands($contents);
+       undef $tmp; undef $cmd;
+       $contents .= "\n\\endgroup ";
+    } elsif ($contents =~ /^\s*\\([a-zA-Z]+)\b/s) { 
+       local($after_cmd) = $';
+       local($cmd) = $1; $tmp = "do_cmd_$cmd"; $etmp = "do_env_$cmd";
+       if (($cmd =~/^(rm(family)?|normalsize)$/)
+               ||($declarations{$cmd}&&(defined &$tmp))) {
+           do{
+               local(@save_open_tags) = @$open_tags_R;
+               eval "\$contents = \&$tmp(\$after_cmd);";
+               print "\n*** eval &$tmp failed: $@\n$contents\n\n" if ($@);
+               $contents .= &balance_tags();
+           };
+       } elsif ($declarations{$cmd}&&(defined &$etmp)) {
+           eval "\$contents = \&$etmp(\$after_cmd);";
+       } else {
+           $contents = &translate_environments($contents);
+           $contents = &translate_commands($contents)
+               if ($contents =~ /$match_br_rx/o);
+           # Modifies $contents
+           &process_command($single_cmd_rx,$contents) if ($contents =~ /\\/o);
+       }
+       undef $cmd; undef $tmp; undef $etmp;
+    } else { 
+       $contents = &translate_environments($contents);
+       $contents = &translate_commands($contents)
+           if ($contents =~ /$match_br_rx/o);
+        # Modifies $contents
+       &process_command($single_cmd_rx,$contents)
+           if ($contents =~ /\\/o);
+    }
+    $contents . &balance_tags();
+}
+
+# MODIFIES $contents
+sub process_environment {
+    local($opt, $env, $id, $styles) = @_;
+
+    local($envS) = $env; $envS =~ s/\*\s*$/star/;
+    local($env_sub,$border,$attribs,$env_id) = ("do_env_$envS",'','','');
+    local($original) = $contents;
+
+    if ($env =~ /tex2html_deferred/ ) {
+       $contents = &do_env_tex2html_deferred($contents);
+       return ($contents);
+    }
+    $env_id = &read_style_info($opt, $env, $id, $styles) 
+       if (($USING_STYLES)&&($opt));
+
+    if (&defined_env($env)) {
+       print STDOUT ",";
+       print STDOUT "{$env $id}" if ($VERBOSITY > 1);
+#      $env_sub =~ s/\*$/star/;
+       $contents = &$env_sub($contents);
+
+    } elsif ($env =~ /tex2html_nowrap/) {
+       #pass it on directly for LaTeX, via images.tex
+       $contents = &process_undefined_environment($env, $id, $contents);
+       return ($contents);
+
+#    elsif (&special_env) {    # &special_env modifies $contents
+    } else {
+       local($no_special_chars) = 0;
+       local($failed) = 0;
+       local($has_special_chars) = 0;
+       &special_env; #  modifies $contents
+       print STDOUT "\n<MATH $env$id $contents>" if ($VERBOSITY > 3);
+       if ($failed || $has_special_chars) {
+           $contents = $original;
+           $failed = 1;
+           print STDOUT " !failed!\n" if ($VERBOSITY > 3);
+        }
+    }
+    if (($contents) && ($contents eq $original)) {
+        if ($ignore{$env}) {  return(''); }
+        # Generate picture
+       if ($contents =~ s/$htmlborder_rx//o) {
+           $attribs = $2; $border = (($4)? "$4" : 1)
+       } elsif ($contents =~ s/$htmlborder_pr_rx//o) { 
+           $attribs = $2; $border = (($4)? "$4" : 1)
+       }
+       $contents = &process_undefined_environment($env, $id, $contents);
+       $env_sub = "post_latex_$env_sub"; # i.e. post_latex_do_env_ENV
+        if ( defined &$env_sub) {
+           $contents = &$env_sub($contents);
+       } elsif (($border||($attributes))&&($HTML_VERSION > 2.1)) {
+           $contents = &make_table($border,$attribs,'','','',$contents);
+       } else {
+           $contents = join('',"<BR>\n",$contents,"\n<BR>")
+               unless (!($contents)||($inner_math)||($env =~
+                     /^(tex2html_wrap|tex2html_nowrap|\w*math|eq\w*n)/o ));
+       }
+    }
+    $contents;
+}
+
+
+#RRM: This reads the style information contained in the optional argument
+#   to the \begin command. It is stored to be recovered later as an entry
+#   within the automatically-generated style-sheet, if $USING_STYLES is set.
+# Syntax for this info is:
+#   <style names> ; <extra style-info> 
+
+sub read_style_info {
+    local($opt, $envS, $id, $styles) = @_;
+    return() unless (($opt)&&($USING_STYLES));
+    # allow macro-expansion within the style-info
+    $opt = &translate_commands($opt) if ($opt =~ /\\/);
+
+    # record class/id info for a style-sheet entry
+    local($style_names, $style_extra, $env_id)=(''," ",'');
+    if ($opt) {
+       # if there is a `;'  then <names> ; <extra>
+       if ($styles =~ /^\s*([^\|]*)\|\s*(.*)$/) {
+           $style_names = $1; $style_extra = $2;
+           if ($style_names =~ /[=:;]/) {
+               # cannot be <names>, so is <extra>
+               $style_extra = $style_names.$style_extra;
+               $style_names = '';
+           }
+       } elsif ($styles =~ /[\=\:]/) {
+           # cannot be <names>, so is <extras>
+           $style_extra = $styles;
+       } else { $style_names = $styles }
+       $style_extra =~ s/\s*[=:]\s*/ : /go;
+       $style_extra =~ s/([\w,\-]+)\s+([\w,\-]+)/$1 ; $2/go;
+       $style_extra =~ s/\s*,\s*/ /go;
+
+       if ($style_names) {
+           local($sname);
+           local(@names) = split ( /\s+/ , $style_names );
+           # ensure a style-sheet entry for each new name
+           foreach $sname (@names) {
+               $env_style{$sname} = " "
+                   unless (($env_style{$sname})||($sname =~ /^\s*$/));         
+           }
+       }
+    }
+    # remove uninformative part of internally-defined env names
+    $envS =~ s/tex2html_(\w+_)?(\w+)/$2/; $envS =~ s/preform/pre/;
+    $env_id = $envS.$id;
+    $styleID{$env_id} = $style_extra unless ($PREAMBLE);
+    
+    if ($style_names) { $envS = "$style_names" }
+    elsif (($envS =~ /^pre$/)&&
+       (/^\\begin.*preform($O|$OP)\d+($C|$CP)$verbatim_mark(\w*[vV]erbatim)(\*?)/))
+           { $envS = $3.($4 ? 'star' : '') };
+    $env_style{$envS} = " " unless (($style_names)||($env_style{$envS}));
+    $env_id = " ID=\"$env_id\"".(($envS) ? " CLASS=\"$envS\"" : '');
+    return($env_id);
+}
+
+# RRM: This provides the mechanism to save style information in %env_style
+#      using LaTeX macros  \htmlsetstyle  and  \htmladdtostyle
+#
+sub process_htmlstyles {
+    local($mode, $_) = @_;
+    local($pre_tags) = &get_next_optional_argument;
+    local($class) = &missing_braces unless (
+        (s/$next_pair_pr_rx/$class = $2;''/e)
+        ||(s/$next_pair_rx/$class = $2;''/e));
+    local($sinfo) = &missing_braces unless (
+        (s/$next_pair_pr_rx/$sinfo = $2;''/e)
+        ||(s/$next_pair_rx/$sinfo = $2;''/e));
+    return ($_) unless ($class||$pre_tags);
+
+    $class = $pre_tags.($class ?'.':'').$class;
+    $sinfo =~ s/\s*[:=]\s*/ : /g;
+    $sinfo =~ s/\s*,\s*/ /g;
+    if ($mode =~ /add/) {
+       $sinfo = '; '.$sinfo if ($env_style{$class}); 
+       $env_style{$class} .= $sinfo;
+    } else { $env_style{$class} = $sinfo }
+    $_;
+}
+sub do_cmd_htmlsetstyle   { &process_htmlstyles('set',@_) }
+sub do_cmd_htmladdtostyle { &process_htmlstyles('add',@_) }
+
+
+# The $<$, $>$, $|$ and $=>$, etc strings are replaced with their textual
+# equivalents instead of passing them on to latex for processing in math-mode.
+# This will not be necessary when the mechanism for passing environments
+# to Latex is improved.
+# RETURNS SUCCESS OR FAILURE
+sub special_env {
+    # Modifies $contents in its caller
+    local($next)='';
+    local ($allow) = $HTML_VERSION ge '3.0' ?
+        "[^#\$%&~\\\\{}]|\\limits" : "[^^#\$%&~_\\\\{}]";
+    #JKR: Use italics instead of bold #HWS: Generalize to include more symbols.
+#    $contents =~ s/^\$(\s*($html_specials_inv_rx|$allow)*\s*)\$(.)?/
+#      $next=$3;&simple_math_env($1).(($next =~ m|\w|)? " ":'').$next/ige;
+    $contents =~ s/^\$(\s*($html_specials_inv_rx|$allow)*\s*)\$$/
+       &simple_math_env($1)." "/ige;
+    if ($contents =~ /\&\w*;/) { $has_math_chars=1 }
+    if ($contents =~ /;SPM([a-zA-Z]+);/) { $has_special_chars=1 };
+}
+
+# Translate simple math environments into italic.
+# Only letters should become italic; symbols should stay non-italic.
+sub simple_math_env {
+    local($mathcontents) = @_;
+    if ($mathcontents eq '') { return("$mathcontents"); }
+    elsif ($NO_SIMPLE_MATH) {  # always make an image
+       $failed = 1; return($mathcontents);
+    } elsif ($mathcontents =~ /\\/) { # any macro kills "simple-math"
+       local($save_math) = $mathcontents;
+       local(@text_only) = ();
+       while ((!$failed)&&($mathcontents =~
+               /\\((boldsymbol|bm)|(math|text)(bf|rm|it|tt)|times|[{}@#^_])(\b|[^A-Za-z]|$)/)) {
+           # ...except when only simple styles
+           push (@text_only, $`, ("$2$4" ? "\\simplemath".($4 ? $4 :"bf") :"\\$1") );
+           $mathcontents = $5.$';
+           $failed = 1 if ($` =~ /\\/);
+       }
+       $failed = 1 if ($mathcontents =~ /\\/);
+       return($save_math) if $failed;
+       $mathcontents = join('',@text_only,$mathcontents);
+    }
+    # Is there a problem here, with nested super/subscripts ?
+    # Yes, so do each pattern-match for bracketings within a while-loop
+    while ($mathcontents =~ s/\^$any_next_pair_rx/<SUP>$2<\/SUP>/go){};
+    while ($mathcontents =~ s/\^$any_next_pair_pr_rx/<SUP>$2<\/SUP>/go){};
+    while ($mathcontents =~ s/_$any_next_pair_rx/<SUB>$2<\/SUB>/g){};
+    while ($mathcontents =~ s/_$any_next_pair_pr_rx/<SUB>$2<\/SUB>/g){};
+
+    $mathcontents =~ s/\^(\\[a-zA-Z]+|.)/<SUP>$1<\/SUP>/g;
+    $mathcontents =~ s/_(\\[a-zA-Z]+|.)/<SUB>$1<\/SUB>/g;
+    $mathcontents =~ s/(^|\s|[,;:'\?\.\[\]\(\)\+\-\=\!>]|[^\\<]\/|\d)(<(I|TT|B)>)?([a-zA-Z]([a-zA-Z ]*[a-zA-Z])?)(<\/\3>)?/
+       $1.(($2)? $2 :'<I>').$4.(($6)? $6 : '<\/I>')/eig;
+
+    $mathcontents =~ s/\\times($|\b|[^A-Za-z])/ x $1/g;
+    $mathcontents =~ s/\\times($|\b|[^A-Za-z])/ x $1/g;
+    $mathcontents =~ s/\\\\/<BR>\n/g;
+    $mathcontents =~ s/\\\\/<BR>\n/g;
+    $mathcontents =~ s/\\([,;])/ /g;
+    $mathcontents =~ s/\\(\W)/$1/g;
+    $mathcontents =~ s/ {2,}/ /g;
+
+    # any simple style changes remove enclosed <I> tags
+    $mathcontents = &translate_commands($mathcontents)
+       if ($mathcontents =~ /\\/);
+
+    $mathcontents =~ s/<I><\/(SUB|SUP)>/<\/$1><I>/g;
+    $mathcontents =~ s/<(SUB|SUP)><\/I>/<\/I><$1>/g;
+    $mathcontents =~ s/;<I>SPM([a-zA-Z]+)<\/I>;/;SPM$1;/go;
+    $mathcontents =~ s/<(\/?)<I>(SUB|SUP|I|B|TT)<\/I>>/<$1$2>/g;
+    $mathcontents =~ s/<\/(B|I|TT)><\1>//g;
+    $mathcontents;
+}
+
+sub do_cmd_simplemathrm { 
+    local ($_) = @_;
+    local($text);
+    $text = &missing_braces unless (
+        (s/$next_pair_pr_rx/$text = $2;''/e)
+        ||(s/$next_pair_rx/$text = $2;''/e));
+    $text =~ s/<\/?I>//g;
+    join('', $text, $_)
+}
+sub do_cmd_simplemathbf { 
+    local ($_) = @_;
+    local($text);
+    $text = &missing_braces unless (
+        (s/$next_pair_pr_rx/$text = $2;''/e)
+        ||(s/$next_pair_rx/$text = $2;''/e));
+    $text =~ s/<\/?I>//g;
+    join('','<B>', $text, '</B>', $_)
+}
+sub do_cmd_simplemathtt {
+    local ($_) = @_;
+    local($text);
+    $text = &missing_braces unless (
+        (s/$next_pair_pr_rx/$text = $2;''/e)
+        ||(s/$next_pair_rx/$text = $2;''/e));
+    $text =~ s/<\/?I>//g;
+    join('','<TT>', $text, '</TT>', $_)
+}
+
+sub process_math_in_latex {
+    local($mode,$style,$level,$math) = @_;
+    local(@anchors);
+    if ($level) {
+       $style = (($level > 1) ? "script" : "") . "script";
+    } elsif (! $style) { 
+       $style = (($mode =~/display|equation/)? "display" : "")
+    }
+    $style = "\\${style}style" if ($style);
+
+    #  &process_undefined_environment  changes $_ , so save it.
+    local($after) = $_;
+
+    # the 'unless' catches nested AMS-aligned environments
+    $mode = "tex2html_wrap_" .
+       (($mode =~/display|equation|eqnarray/) ? 'indisplay' : 'inline')
+           unless ($mode =~ /^equationstar/ && $outer_math =~ /^equationstar/);
+
+    $global{'max_id'}++;
+    $math =~ s/\\(\n|$)/\\ $1/g;       # catch \ at end of line or string
+    $math =~ s/^\s*((\\!|;SPMnegsp;)\s*)*//g;          # remove neg-space at start of string
+    if ($mode =~ /tex2html_wrap_/ ) {
+       $math = &process_undefined_environment( $mode
+           , $global{'max_id'}, join('', "\$$style ", $math, "\$"));
+    } else {
+       # some AMS environments must be within {equation} not {displaymath}
+       $math =~ s/displaymath/equation*/
+               if ($math =~ /\\begin\{(x+|fl)*align/);
+       $math = &process_undefined_environment($mode, $global{'max_id'}, $math);
+    }
+    $math .= "\n" if ($math =~ /$comment_mark\s*\d+$/s);
+    $_ = $after;
+    # the delimiter \001 inhibits an unwanted \n at image-replacement
+    $math . ($math =~ /$image_mark/? "\001" : '');
+}
+     
+#RRM: Explicit font switches need images. Use the image_switch mechanism.
+sub do_cmd_font {
+    local($_) = @_;
+    local($fontinfo,$fontname,$size) = ('','','10pt');
+    s/\s*\\(\w+)\s*=?\s*(.*)(\n|$)/$fontname=$1;$fontinfo=$2;''/eo;
+    $image_switch_rx .= "|$fontname";
+
+    if ($fontinfo =~ /([.\d]+\s*(true)?(pt|mm|cm))/ ) { $size = $1 }
+    elsif ( $fontinfo =~ /[a-zA-Z]+(\d+)\b/ ) { $size = $1.'pt' }
+    if  ( $fontinfo =~ /(scaled|at)\s*\\?(.+)/) { $size .= " scaled $1" }
+    $font_size{$fontname} = $size;
+    $_;
+}
+sub wrap_cmd_font {
+    local($cmd, $_) = @_;
+    local ($args, $dummy, $pat) = "";
+    if (/\n/) { $args .= $`.$& ; $_ = $' } else {$args = $_; $_ = ''};
+    (&make_deferred_wrapper(1).$cmd.$padding.$args.&make_deferred_wrapper(0),$_)
+}
+
+sub do_cmd_newfont {
+    local($_) = @_;
+    local($fontinfo,$fontname,$size) = ('','','10pt');
+    $fontname = &missing_braces unless (
+       (s/$next_pair_pr_rx/$fontname=$2;''/eo)
+       ||(s/$next_pair_rx/$fontname=$2;''/eo));
+    $fontname=~ s/^\s*\\|\s*$//g;
+    $image_switch_rx .= "|$fontname";
+
+    $fontinfo = &missing_braces unless (
+       (s/$next_pair_pr_rx/$fontinfo=$2;''/eo)
+       ||(s/$next_pair_rx/$fontinfo=$2;''/eo));
+    if ($fontinfo =~ /([.\d]+\s*(true)?(pt|mm|cm))/ ) { $size = $1 }
+    elsif ( $fontinfo =~ /[a-zA-Z]+(\d+)\b/ ) { $size = $1.'pt' }
+    if  ( $fontinfo =~ /(scaled|at)\s*\\?(.+)/) { $size .= " scaled $1" }
+    $font_size{$fontname} = $size;
+    $_;
+}
+
+sub defined_env {
+    local($env) = @_;
+    $env =~ s/\*$/star/;
+    local($env_sub) = ("do_env_$env");
+    # The test using declarations should not be necessary but 'defined'
+    # doesn't seem to recognise subroutines generated dynamically using 'eval'.
+    # Remember that each entry in $declarations generates a dynamic prodedure ...
+    ((defined &$env_sub) || ($declarations{$env}));
+}
+
+# RRM: utility to add style information to stored image-parameters
+#      currently only (math) scaling info is included;
+#      current color, etc.  could also be added here.
+sub addto_encoding {
+    local($env, $contents) = @_;
+#    $contents =~ s/(\\(begin|end)\s*)?<<\d*>>|\n//g;  # RRM: remove env delimiters
+    $contents =~ s/(\\(begin|end)\s*(<<\d*>>))|\n//g;  # RRM: remove env delimiters
+    # append scaling information for environments using it
+    if (($MATH_SCALE_FACTOR)
+       &&(($contents =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/)
+          ||($env =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/))
+       ) { $contents .= ";MSF=$MATH_SCALE_FACTOR" }
+
+    if ($LATEX_FONT_SIZE =~ /([\d\.]+)pt/) {
+       local($fsize) = $1;
+       $contents .= ";LFS=$fsize" unless ($fsize ==10);
+    }
+
+    if (($EXTRA_IMAGE_SCALE)
+       &&(($contents =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/)
+          ||($env =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/))
+       ) { $contents .= ";EIS=$EXTRA_IMAGE_SCALE" }
+
+    if (($DISP_SCALE_FACTOR)
+       &&(($contents =~ /indisplay|displaymath|eqnarray|equation/)
+          ||($env =~ /indisplay|displaymath|eqnarray|equation/))
+       &&!(($contents =~ /makeimage/)||($env =~ /makeimage/))
+       ) { $contents .= ";DSF=$DISP_SCALE_FACTOR" }
+
+    if (($EQN_TAGS)
+       &&(($env =~ /eqnarray($|[^_\*])|equation/)
+          ||($contents =~ /eqnarray($|[^_\*])|equation/))
+       &&!(($contents =~ /makeimage/)||($env =~ /makeimage/))
+       ) { $contents .= ";TAGS=$EQN_TAGS" }
+
+    if (($FIGURE_SCALE_FACTOR)
+       &&!(($contents =~ /makeimage/)||($env =~ /makeimage/))
+       &&(($contents =~ /figure/)||($env =~ /figure/))
+       ) { $contents .= ";FSF=$FIGURE_SCALE_FACTOR"}
+
+    if (($ANTI_ALIAS)
+       &&(($contents =~ /figure/)||($env =~ /figure/))
+       &&!(($contents =~ /makeimage/)||($env =~ /makeimage/))
+       ) { $contents .= ";AAF" }
+    elsif ($ANTI_ALIAS_TEXT) { $contents .= ";AAT" }
+    if (!$TRANSPARENT_FIGURES) { $contents .= ";NTR" }
+
+    $contents;
+}
+
+sub process_undefined_environment {
+    local($env, $id, $contents) = @_;
+    if ($env =~ s/\*{2,}/*/) { print "\n*** $_[0] has too many \*s ***"};
+
+    local($name,$cached,$raw_contents,$uucontents) = ("$env$id");
+    $name =~ s/\*/star/;
+    local($oldimg,$size,$fullcontents,$imgID);
+    return if ($AUX_FILE);
+
+    # catch \footnotemark within an image, especially if in math
+    local(@foot_anchors,$foot_anchor);
+    local($im_footnote,$im_mpfootnote) = ($global{'footnote'},$global{'mpfootnote'});
+    @foot_anchors = &process_image_footnote($contents)
+       if ($contents =~ /\\footnote(mark)?\b/s);
+    if ((@foot_anchors)&&($eqno)) {
+       # append the markers to the equation-numbers
+       $eqno .= join(' ', ' ', @foot_anchors);
+       @foot_anchors = ();
+    }
+    
+    print STDOUT "\nUNDEF-IN {$env $id}:\n$contents\n" if ($VERBOSITY > 4);
+    #RRM - LaTeX commands wrapped with this environment go directly into images.tex.
+    if ($env =~ /tex2html_nowrap|^lrbox$/){ # leave off the wrapper, do not cache
+       # totally ignore if in preamble...
+       # ...since it will be put into  images.tex  anyway!!
+       if (!($PREAMBLE)) {
+           $contents =~ s/^\n+|\n+$/\n/g;
+           local($lcontents) = join('', "\\begin{$env}", $contents , "\\end{$env}" );
+           $lcontents =~ s/\\(index|label)\s*(($O|$OP)\d+($C|$CP)).*\2//sg;
+           print STDOUT "pre-LATEX {$env}:\n$lcontents\n" if ($VERBOSITY > 3);
+           $raw_contents = &revert_to_raw_tex($lcontents);
+           print STDOUT "LATEX {$env}:\n$raw_contents\n" if ($VERBOSITY > 3);
+           $latex_body .= "\n$raw_contents"."%\n\n" ;
+       }
+       return("") if ($env =~ /^lrbox/);
+       # ignore enclosed environments; e.g. in  \settolength  commands
+#      $contents = &translate_environments($contents); # ignore environments
+#      $contents = &translate_commands($contents);
+       # ...but apply any Perl settings that may be defined
+       $contents = &process_command($single_cmd_rx,$contents);
+       print STDOUT "\nOUT {$env $id}:\n$contents\n" if ($VERBOSITY > 4);
+       return("");
+    }
+    # catch pre-processor environments
+    if ($PREPROCESS_IMAGES) {
+       local($pre_env,$which, $done, $indic);
+       while ($contents =~ /$pre_processor_env_rx/) {
+           $done .= $`; $pre_env = $5; $which =$1; $contents = $';
+           if (($which =~ /begin/)&&($pre_env =~ /indica/)) {
+               if ($contents =~ s/^\[(\w+)]//o) { $done .= '#'.$1 }
+           } elsif (($which =~ /end/)&&($pre_env =~ /indica/)) {
+               $done .= '#NIL';
+           } elsif (($which =~ /begin/)&&($pre_env =~ /itrans/)) {
+               if ($contents =~ s/^\[(\w+)]/$indic=$1;''/e)
+                   { $done .= "\#$indic" }
+           } elsif (($which =~ /end/)&&($pre_env =~ /itrans/)) {
+               $done .= "\#end$indic";
+           } elsif ($which =~ /begin/) {
+               $done .= (($which =~ /end/)? $end_preprocessor{$pre_env}
+                         : $begin_preprocessor{$pre_env} )
+           }
+       }
+       $contents = $done . $contents;
+    }
+    $fullcontents =  $contents; # save for later \label search.
+    # MRO: replaced $* with /m
+    $contents =~ s/\n?$labels_rx(\%([^\n]+$|$EOL))?/\n/gm;
+
+    local($tmp) = $contents;
+    $tmp =~ s/^((\\par|\%)?\s*\n)+$//g;
+    return( &do_labels($fullcontents, "\&nbsp;") ) unless $tmp;
+
+    # just a comment as the contents of a cell in a math-display
+    if ($tmp =~ /\$\\(display|text|(script)+)style\s*$comment_mark\d+\s*\$$/)
+       { return ( &do_labels($fullcontents, "\&nbsp;") ) };
+
+    $contents = "\n% latex2html id marker $id\n$contents" if
+       (!$PREAMBLE &&($contents =~ /$order_sensitive_rx/)
+               &&(!($env =~ /makeimage/)));
+
+    $env =~ s/displaymath/equation*/
+       if ($contents =~ /\\begin\{(x+|fl)*align/);
+    #RRM: include the inline-color, when applicable
+    $contents = join(''
+           , (($inner_math =~ /in(display|line)/) ? '$' : '')
+           , "\\begin{$env}"
+           , ($color_env ? "\\bgroup\\$color_env" : '')
+           , $contents , ($color_env ? "\\egroup" : '')
+           , "\\end{$env}"
+           , (($inner_math =~ /in(display|line)/) ? '$' : '')
+       ) if ($contents);
+
+    # append to the name of special environments found within math
+    if ($inner_math) {
+       local($ext) = $inner_math;
+       if ($inner_math =~ /(display|line)/){ $ext = 'in'.$1;};
+       $name =~ s/(\d+)$/_$ext$1/;
+    }
+
+    if (!($latex_body{$name} = $contents)) {
+       print "\n *** code for $name is too long ***\n"}
+    if ($contents =~ /$htmlimage_rx/) {
+       $uucontents = &special_encoding($env,$2,$contents);
+    } elsif ($contents =~ /$htmlimage_pr_rx/) {
+       $uucontents = &special_encoding($env,$2,$contents);
+    } else {
+       $uucontents = &encode(&addto_encoding($env,$contents));
+    }
+    $cached = $cached_env_img{$uucontents};
+    print STDOUT "\nCACHED: $uucontents:\n$cached\n" if ($VERBOSITY > 4);
+    if ($NOLATEX) { 
+       $id_map{$name} = "[$name]";
+    } elsif (defined ($_ = $cached)) { # Is it in our cache?
+       # Have we already used it?
+       if (($oldimg) = /SRC="$PREFIX$img_rx\.$IMAGE_TYPE"/o) {
+           # No, check its size
+           local($eis) = 1;
+           # Does it have extra scaling ?
+           if ($uucontents =~ /EIS=(.*);/) { $eis = $1 }
+           ($size, $imgID) = &get_image_size("$PREFIX$oldimg.old", $eis);      
+           # Does it have extra scaling ?
+#          if ($uucontents =~ /EIS=(.*);/) {
+#              local($eis) = $1; local($w,$h);
+#              # quotes will not be there with HTML 2.0
+#              $size =~ s/(WIDTH=\")(\d*)(\".*HEIGHT=\")(\d*)\"/
+#                  $w = int($2\/$eis + .5); $h=int($4\/$eis + .5);
+#                  "$1$w$3$h\""/e ; # insert the re-scaled size
+#          }
+           # quotes will not be there with HTML 2.0
+           $size =~ s/\"//g if ($HTML_VERSION < 2.2);
+           if ($size && /\s$size\s/) {
+               # Size is OK; recycle it!
+               ++$global_page_num;
+               $_ = $cached ;    # ...perhaps restoring the desired size.
+               s/(${PREFIX}T?img)\d+\.($IMAGE_TYPE|html)/
+                       &rename_html($&,"$1$global_page_num.$2")/geo;
+           } else {
+               if ($env =~ /equation/) { &extract_eqno($name,$cached) }
+               $_ = "";                                # The old Image has wrong size!
+               undef($cached);                 #  (or it doesn't exist)
+           }
+       }
+       s/(IMG\n)/$1$imgID/ if $imgID;
+
+       s/$PREFIX$img_rx\.new/$PREFIX$1.$IMAGE_TYPE/go; # Point to the actual image file(s)
+       $id_map{$name} = $_;
+       s/$PREFIX$img_rx\.$IMAGE_TYPE/$PREFIX$1.new/go; # But remember them as used.
+       $cached_env_img{$uucontents} = $_;
+    }
+
+    if (! defined($cached)) {                          # Must generate it anew.
+       &clear_images_dbm_database
+           unless ($new_page_num ||($NO_SUBDIR && $FIXEDDIR));
+       $new_id_map{$name} = $id_map{$name} = ++$global_page_num . "#" .
+           ++$new_page_num;
+       $orig_name_map{$id_map{$name}} = $name;
+       $cached_env_img{$uucontents} = $id_map{$name} if ($REUSE == 2);
+
+       #RRM: this (old) code frequently crashes NDBM, so do it in 2 steps
+#      $img_params{$name} = join('#', &extract_parameters($contents));
+       local(@params) = &extract_parameters($contents);
+       $img_params{$name} = join('#',@params); undef $params;
+       print "\nIMAGE_PARAMS $name: ".$img_params{$name} if ($VERBOSITY > 3);
+
+       $contents =~ s/\\(index|label)\s*(($O|$OP)\d+($C|$CP)).*\2//sg;
+       print STDOUT "\nLATEX {$env}:\n$contents" if ($VERBOSITY > 3);
+       $raw_contents = &revert_to_raw_tex($contents) unless ($contents =~ /^\s*$/) ;
+       $raw_contents =~ s/\\pagebreak|\\newpage|\\clearpage/\\\\/go;
+       print STDOUT "\nLATEX {$env}:\n$raw_contents\n" if ($VERBOSITY > 3);
+       local($box_type) = '';
+       if ($raw_contents =~ /\\special\s*\{/) { 
+           $tex_specials{$name} = "1";
+           &write_warnings("\nenvironment $name contains \\special commands");
+           print STDOUT "\n *** environment $name contains \\special commands ***\n"
+               if ($VERBOSITY);
+       } elsif (($env =~ /$inline_env_rx/)||($inner_math =~ /in(line|display)/)) {
+           # crop to the marks only... or shave a bit off the bottom
+           if (($env =~ /tex2html_[^w]/)||$inner_math) {
+               # e.g. accents, indic  but not wrap
+               $crop{$name} = "bl";
+               $box_type = "i";                
+           } else {
+           # ...or shave a bit off the bottom as well
+               $crop{$name} = "bls";
+               $box_type = "h";
+           }
+       } elsif (($env =~ /(eqnarray|equation)(\*|star)/)||($inner_math)) {
+           # crop to minimum size...
+           $crop{$name} = "blrl";
+           $box_type = "v";
+       } elsif ($env =~ /(picture|tex2html_wrap)(\*|star)?/) {
+           # crop hbox to minimum size...
+           $crop{$name} = "";
+           $box_type = "p";
+       } elsif ($env =~ /$display_env_rx/) {
+           # crop vbox to minimum size...
+           $crop{$name} = "blrl" ;
+           if ($env =~ /(equation|eqnarray)((s)?$|\d)/) {
+               # ... unless equation numbers are included ...
+               if ($3) { #  AMS {subequations}
+                   $global{'eqn_number'}=$prev_eqn_number if $prev_eqn_number;
+                   --$global{'eqn_number'};
+               }
+               $raw_contents = join('' ,
+                   (($eqno{$name}||$global{'eqn_number'})?
+                     &set_equation_counter($eqno{$name}) : '')
+                   , $raw_contents);
+               $crop{$name} = "bl" ;
+           } elsif ($HTML_VERSION < 2.2) {
+               # ... HTML 2.0 cannot align images, so keep the full typeset width
+               $crop{$name} = "bl" ;           
+           }
+           $box_type = "v";
+       }
+       
+       #RRM: include the TeX-code for the appropriate type of box.
+       eval "\$raw_contents = \&make_$box_type"."box($name, \$raw_contents);";
+
+       # JCL(jcl-pag) - remember html text if debug is set.
+       local($_);
+       if ($DEBUG) {
+           $_ = $contents;
+           s/\n/ /g;
+           $_ = &revert_to_raw_tex($_);
+           # incomplete or long commented code can break pre-processors
+           if ($PREPROCESS_IMAGES) {
+               $_ = ((/^(\\\w+)?\{[^\\\}\<]*\}?/)? $& : '').'...' ;
+               $_ = '{ ... }' if ( length($_) > 100);
+           } elsif ( length($_) > 200) {
+                   $_ = join('',substr($_,0,200),"...\}");
+           }
+           s/\\(begin|end)/$1/g; s/[\000-\020]//g;
+           $_ = join('',"% contents=",$_,"\n");
+       }
+       $raw_contents = '\setcounter{equation}{'.$prev_eqn_number."}\n".$raw_contents
+           if ($env =~ /subequations/);
+
+# JCL(jcl-pag) - build the page entries for images.tex:  Each page is embraced to
+# let most statements have only local effect. Each page must compile into a
+# single dvi page to get proper image translation. Hence the invisible glue to
+# get *at least* one page (raw_contents alone might not wield glue), and
+# sufficing page length to get *exactly* one page.
+#
+       $latex_body .= "{\\newpage\\clearpage\n$_" .
+#          "$raw_contents\\hfill\\vglue1pt\\vfill}\n\n";
+#          "$raw_contents\\hfill\\vss}\n\n" if ($raw_contents);
+#          "$raw_contents\\hfill\\lthtmlcheckvsize\\clearpage}\n\n" if ($raw_contents);
+           "$raw_contents\\lthtmlcheckvsize\\clearpage}\n\n" if ($raw_contents);
+    }
+    print STDOUT "\nIMAGE_CODE:{$env $id}:\n$raw_contents\n" if ($VERBOSITY > 4);
+
+    # Anchor the labels and put a marker in the text;
+    local($img) = &do_labels($fullcontents,"$image_mark#$name#");
+    print STDOUT "\nUNDEF_OUT {$env $id}:\n$img\n" if ($VERBOSITY > 4);
+    return($img) unless (@foot_anchors);
+
+    # use the image as source to the 1st footnote, unless it is already an anchor.
+    if ($img =~ /<\/?A>/) {
+       join(' ', $img, @foot_anchors);         
+    } elsif ($#foot_anchors ==0) {
+       $foot_anchor = shift @foot_anchors;
+       $foot_anchor =~ s/<SUP>.*<\/SUP>/$img/;
+#      join(' ', $foot_anchor, @foot_anchors);         
+       $foot_anchor;
+    } else {
+       join(' ', $img, @foot_anchors);         
+    }
+}
+
+sub special_encoding { # locally sets $EXTRA_IMAGE_SCALE
+    local($env,$_,$contents) = @_; 
+    local($exscale) = /extrascale=([\.\d]*)/;
+    local($EXTRA_IMAGE_SCALE) = $exscale if ($exscale);
+    &encode(&addto_encoding($env,$contents));
+}
+
+
+sub extract_eqno{
+    local($name,$contents) = @_;
+    if ($contents =~ /<P ALIGN="\w+">\(([^<>])\)<\/P>$/) {
+       if (($eqno{$name})&&!($eqno{$name} eq $1)) {
+           &write_warnings("\nequation number for $name may be wrong.")};
+       $eqno{$name}="$1";
+    }
+}
+sub set_equation_counter{
+    if ( $global{'eqn_number'}) {
+       "\\setcounter{equation}{". $global{'eqn_number'} ."}\n"
+    } else { "\\setcounter{equation}{0}\n" }
+}
+
+# RRM: 3 different types of boxing, for image environments.
+
+#      general environments --- crops to width & height
+sub make_box {
+    local($id,$contents) = @_;
+    "\\lthtmlfigureA{". $id ."}%\n". $contents ."%\n\\lthtmlfigureZ\n";
+}
+
+#      inline math --- horizontal mode, captures height/depth + \mathsurround
+sub make_hbox {
+    local($id,$contents) = @_;
+    if ($id =~ /indisplay/) {
+       "\\lthtmlinlinemathA{". $id ."}%\n". $contents ."%\n\\lthtmlindisplaymathZ\n";
+    } else {
+       "\\lthtmlinlinemathA{". $id ."}%\n". $contents ."%\n\\lthtmlinlinemathZ\n";
+    }
+}
+
+#      inline text-image (e.g. accents) --- horizontal mode, captures height/depth
+sub make_ibox {
+    local($id,$contents) = @_;
+    "\\lthtmlinlineA{". $id ."}%\n". $contents ."%\n\\lthtmlinlineZ\n";
+}
+
+#      centered images (e.g. picture environments) --- horizontal mode
+sub make_pbox {
+    local($id,$contents) = @_;
+    "\\lthtmlpictureA{". $id ."}%\n". $contents ."%\n\\lthtmlpictureZ\n";
+}
+
+#      displayed math --- vertical mode, captures height/depth + page-width
+sub make_vbox {
+    local($id,$contents) = @_;
+    if (($HTML_VERSION >=3.2)&&($id =~/(equation|eqnarray)($|\d)/) &&! $failed ) {
+       if ($contents =~ s/^\\setcounter\{equation\}\{\d+\}/$&%\n\\lthtmldisplayB\{$id\}%/)
+           { $contents ."%\n\\lthtmldisplayZ\n" }
+       else { "\\lthtmldisplayB{$id}%\n". $contents ."%\n\\lthtmldisplayZ\n" }
+    } else { "\\lthtmldisplayA{$id}%\n". $contents ."%\n\\lthtmldisplayZ\n"}
+}
+
+sub preprocess_images {
+    do {
+       print "\nWriting image.pre file ...\n";
+       open(ENV,">.$dd${PREFIX}images.pre")
+            || die "\nCannot write '${PREFIX}images.pre': $!\n";
+       print ENV &make_latex($latex_body);
+       print ENV "\n";
+       close ENV;
+       &copy_file($FILE, "bbl");
+       &copy_file($FILE, "aux");
+       local($num_cmds, $cnt, $this, @cmds);
+       @cmds = (split ('\n', $preprocessor_cmds));
+       $this_cmd = $num_cmds = 1+$#cmds;
+       $cnt = $num_cmds; $preprocessor_cmds = '';
+       while (@cmds) {
+           $this_cmd = shift @cmds; last unless ($this_cmd);
+           $this_cmd =~ s/.pre /.tex$cnt / if(($cnt)&&($cnt < $num_cmds));
+           $cnt--; $this_cmd .= $cnt if ($cnt);
+           $preprocessor_cmds .= $this_cmd."\n";
+           L2hos->syswait($this_cmd);
+       }
+       # save pre-processor commands in a file:  preproc
+       open(CMDS,">.$dd${PREFIX}preproc")
+            || die "\nCannot write '${PREFIX}preproc': $!\n";
+       print CMDS $preprocessor_cmds ;
+       close CMDS;
+
+    } if ((%latex_body) && ($latex_body =~ /newpage/));
+}
+sub make_image_file {
+    do {
+       print "\nWriting image file ...\n";
+       open(ENV,">.$dd${PREFIX}images.tex")
+            || die "\nCannot write '${PREFIX}images.tex': $!\n";
+       print ENV &make_latex($latex_body);
+       print ENV "\n";
+       close ENV;
+       &copy_file($FILE, "bbl");
+       &copy_file($FILE, "aux");
+    } if ((%latex_body) && ($latex_body =~ /newpage/));
+}
+
+sub make_latex_images{
+    &close_dbm_database if $DJGPP;
+    local($dd) = $dd; $dd = '/' if ($dd eq "\\"); 
+    local($latex_call) = "$LATEX .$dd${PREFIX}images.tex";
+    print "$latex_call\n" if (($DEBUG)||($VERBOSITY > 1));
+    L2hos->syswait($latex_call);
+    &open_dbm_database if $DJGPP;
+}
+
+sub make_off_line_images {
+    local($name, $page_num);
+    if (!$NOLATEX && -f ".${dd}${PREFIX}images.tex") {
+       &make_tmp_dir;  # sets  $TMPDIR  and  $DESTDIR
+       $IMAGE_PREFIX =~ s/^_//o if ($TMPDIR);
+
+       &make_latex_images();
+
+       print "\nGenerating postscript images using dvips ...\n";
+       &process_log_file(".$dd${PREFIX}images.log"); # Get eqn size info
+       unless ($LaTeXERROR) {
+           local($dvips_call) = 
+               "$DVIPS -S1 -i $DVIPSOPT -o$TMPDIR$dd${IMAGE_PREFIX} .${dd}${PREFIX}images.dvi";
+           print "$dvips_call\n" if (($DEBUG)||($VERBOSITY > 1));
+
+           &close_dbm_database if $DJGPP;
+           L2hos->syswait($dvips_call) && print "Error: $!\n";
+           undef $dvips_call;
+           &open_dbm_database if $DJGPP;
+
+           # add suffix .ps to the file-names for each image
+           if(opendir(DIR, $TMPDIR || '.')) {
+                #  use list-context instead; thanks De-Wei Yin <yin@asc.on.ca>
+               my (@ALL_IMAGE_FILES) = grep /^$IMAGE_PREFIX\d+$/o, readdir(DIR);
+               foreach (@ALL_IMAGE_FILES) {
+                       L2hos->Rename("$TMPDIR$dd$_", "$TMPDIR$dd$_.ps");
+               }
+               closedir(DIR);
+            } else {
+                print "\nError: Cannot read dir '$TMPDIR': $!\n";
+            }
+       }
+    }
+    if ($LaTeXERROR) {
+        print "\n\n*** LaTeXERROR\n"; return();
+    }
+
+    while ( ($name, $page_num) = each %new_id_map) {
+       # Extract the page, convert and save it
+       &extract_image($page_num,$orig_name_map{$page_num});
+    }
+}
+
+# Generate images for unknown environments, equations etc, and replace
+# the markers in the main text with them.
+# - $cached_env_img maps encoded contents to image URL's
+# - $id_map maps $env$id to page numbers in the generated latex file and after
+# the images are generated, maps page numbers to image URL's
+# - $page_map maps page_numbers to image URL's (temporary map);
+# Uses global variables $id_map and $cached_env_img,
+# $new_page_num and $latex_body
+
+
+sub make_images {
+    local($name, $contents, $raw_contents, $uucontents, $page_num,
+         $uucontents, %page_map, $img);
+    # It is necessary to run LaTeX this early because we need the log file
+    # which contains information used to determine equation alignment
+    if ( $latex_body =~ /newpage/) {
+       print "\n";
+       if ($LATEX_DUMP) {
+           # dump a pre-compiled format
+           if (!(-f "${PREFIX}images.fmt")) {
+               print "$INILATEX ./${PREFIX}images.tex\n" 
+                   if (($DEBUG)||($VERBOSITY > 1));
+               print "dumping ${PREFIX}images.fmt\n"
+                   unless ( L2hos->syswait("$INILATEX ./${PREFIX}images.tex"));
+           }
+           local ($img_fmt) = (-f "${PREFIX}images.fmt");
+           if ($img_fmt) {
+                # use the pre-compiled format
+               print "$TEX \"&./${PREFIX}images\" ./${PREFIX}images.tex\n"
+                   if (($DEBUG)||($VERBOSITY > 1));
+               L2hos->syswait("$TEX \"&./${PREFIX}images\" ./${PREFIX}images.tex");
+           } elsif (-f "${PREFIX}images.dvi") {
+               print "${PREFIX}images.fmt failed, proceeding anyway\n";
+           } else {
+               print "${PREFIX}images.fmt failed, trying without it\n";
+               print "$LATEX ./${PREFIX}images.tex\n"
+                   if (($DEBUG)||($VERBOSITY > 1));
+               L2hos->syswait("$LATEX ./${PREFIX}images.tex");
+           }
+       } else { &make_latex_images() }
+#          local($latex_call) = "$LATEX .$dd${PREFIX}images.tex";
+#          print "$latex_call\n" if (($DEBUG)||($VERBOSITY > 1));
+#          L2hos->syswait("$latex_call");
+##         print "$LATEX ./${PREFIX}images.tex\n" if (($DEBUG)||($VERBOSITY > 1));
+##         L2hos->syswait("$LATEX ./${PREFIX}images.tex");
+##        }
+       $LaTeXERROR = 0;
+       &process_log_file("./${PREFIX}images.log"); # Get image size info
+    }
+    if ($NO_IMAGES) {
+        my $img = "image.$IMAGE_TYPE";
+       my $img_path = "$LATEX2HTMLDIR${dd}icons$dd$img";
+       L2hos->Copy($img_path, ".$dd$img")
+            if(-e $img_path && !-e $img);
+    }
+    elsif ((!$NOLATEX) && ($latex_body =~ /newpage/) && !($LaTeXERROR)) {
+       print "\nGenerating postscript images using dvips ...\n";
+        &make_tmp_dir;  # sets  $TMPDIR  and  $DESTDIR
+       $IMAGE_PREFIX =~ s/^_//o if ($TMPDIR);
+
+       local($dvips_call) = 
+               "$DVIPS -S1 -i $DVIPSOPT -o$TMPDIR$dd$IMAGE_PREFIX .${dd}${PREFIX}images.dvi\n";
+       print $dvips_call if (($DEBUG)||($VERBOSITY > 1));
+       
+       if ((($PREFIX=~/\./)||($TMPDIR=~/\./)) && not($DVIPS_SAFE)) {
+           print " *** There is a '.' in $TMPDIR or $PREFIX filename;\n"
+               . "  dvips  will fail, so image-generation is aborted ***\n";
+       } else {
+           &close_dbm_database if $DJGPP;
+           L2hos->syswait($dvips_call) && print "Error: $!\n";
+           &open_dbm_database if $DJGPP;
+       }
+
+       # append .ps suffix to the filenames
+       if(opendir(DIR, $TMPDIR || '.')) {
+            # use list-context instead; thanks De-Wei Yin <yin@asc.on.ca>
+           my @ALL_IMAGE_FILES = grep /^$IMAGE_PREFIX\d+$/o, readdir(DIR);
+           foreach (@ALL_IMAGE_FILES) {
+               L2hos->Rename("$TMPDIR$dd$_", "$TMPDIR$dd$_.ps");
+           }
+           closedir(DIR);
+        } else {
+            print "\nError: Cannot read dir '$TMPDIR': $!\n";
+        }
+    }
+    do {print "\n\n*** LaTeXERROR"; return()} if ($LaTeXERROR);
+    return() if ($LaTeXERROR); # empty .dvi file
+    L2hos->Unlink(".$dd${PREFIX}images.dvi") unless $DEBUG;
+
+    print "\n *** updating image cache\n" if ($VERBOSITY > 1);
+    while ( ($uucontents, $_) = each %cached_env_img) {
+       delete $cached_env_img{$uucontents}
+           if ((/$PREFIX$img_rx\.$IMAGE_TYPE/o)&&!($DESTDIR&&$NO_SUBDIR));
+       $cached_env_img{$uucontents} = $_
+           if (s/$PREFIX$img_rx\.new/$PREFIX$1.$IMAGE_TYPE/go);
+    }
+    print "\n *** removing unnecessary images ***\n" if ($VERBOSITY > 1);
+    while ( ($name, $page_num) = each %id_map) {
+       $contents = $latex_body{$name};
+       if ($page_num =~ /^\d+\#\d+$/) { # If it is a page number
+           do {                # Extract the page, convert and save it
+               $img = &extract_image($page_num,$orig_name_map{$page_num});
+               if ($contents =~ /$htmlimage_rx/) {
+                   $uucontents = &special_encoding($env,$2,$contents);
+               } elsif ($contents =~ /$htmlimage_pr_rx/) {
+                   $uucontents = &special_encoding($env,$2,$contents);
+               } else {
+                   $uucontents = &encode(&addto_encoding($contents,$contents));
+               }
+               if (($HTML_VERSION >=3.2)||!($contents=~/$order_sensitive_rx/)){
+                   $cached_env_img{$uucontents} = $img;
+               } else {
+                    # Blow it away so it is not saved for next time
+                   delete $cached_env_img{$uucontents};
+                   print "\nimage $name not recycled, contents may change (e.g. numbering)";
+               }
+               $page_map{$page_num} = $img;
+           } unless ($img = $page_map{$page_num}); # unless we've just done it
+           $id_map{$name} = $img;
+       } else {
+           $img = $page_num;   # it is already available from previous runs
+       }
+       print STDOUT " *** image done ***\n" if ($VERBOSITY > 2);
+    }
+    &write_warnings(
+                   "\nOne of the images is more than one page long.\n".
+                   "This may cause the rest of the images to get out of sync.\n\n")
+       if (-f sprintf("%s%.3d%s", $IMAGE_PREFIX, ++$new_page_num, ".ps"));
+    print "\n *** no more images ***\n"  if ($VERBOSITY > 1);
+    # MRO: The following cleanup seems to be incorrect: The DBM is
+    # still open at this stage, this causes a lot of unlink errors
+    #
+    #do { &cleanup; print "\n *** clean ***\n"  if ($VERBOSITY > 1);}
+    #  unless $DJGPP;
+}
+
+# MRO: This copies the navigation icons from the distribution directory
+# or an alternative specified in $ALTERNATIVE_ICONS
+# to the document directory.
+
+sub copy_icons {
+    local($icon,$_);
+    print "\nCopying navigation icons ...";
+    foreach (keys %used_icons) {
+       # each entry ends in gif or png
+       if ($ALTERNATIVE_ICONS) {
+           L2hos->Copy("$ALTERNATIVE_ICONS$dd$_", ".$dd$_")
+               if (-e "$ALTERNATIVE_ICONS$dd$_" && !-e $_);
+       } elsif (/(gif|png)$/) {
+           L2hos->Copy("$LATEX2HTMLDIR${dd}icons$dd$_", ".$dd$_")
+               if (-e "$LATEX2HTMLDIR${dd}icons$dd$_" && !-e $_);
+       }
+    }
+}
+
+sub process_log_file {
+    local($logfile) = @_;
+    local($name,$before,$lengthsfound);
+    local($TeXpt)= 72/72.27;
+    local($image_counter);
+    open(LOG, "<$logfile") || die "\nCannot read logfile '$logfile': $!\n";
+    while (<LOG>) {
+        if (/Overfull/) { $before .= $_ }
+        elsif (/latex2htmlLength ([a-zA-Z]+)=(\-?[\d\.]+)pt/) {
+           ${$1} = 0.0+$2; $lengthsfound = 1;
+       } elsif (/latex2htmlSize|l2hSize/) {
+           /:([^:]*):/;
+           $name = $1; $name =~ s/\*//g;
+           ++$image_counter;
+           s/:([0-9.]*)pt/$height{$name} = $1*$TeXpt;''/e;
+           s/::([0-9.]*)pt/$depth{$name} = $1*$TeXpt;''/e;
+           s/::([0-9.]*)pt/$width{$name} = $1*$TeXpt;''/e;
+           s/\((.*)\)/$eqno{$name} = 1+$1;''/e;
+           if ($before) {
+               local($tmp);
+               if ($before =~ /hbox\s*\((\d+\.?\d*)pt/) {
+                   $width{$name} = $width{$name}+$1*$TeXpt;
+               }
+               if ($before =~ /vbox\s*\((\d+\.?\d*)pt/) {
+                   $height{$name} = $height{$name}+$1*$TeXpt;
+               }
+               $before = '';
+           }
+       }
+    $LaTeXERROR = 1 if (/^No pages of output./);
+    }
+
+    if ($LaTeXERROR) {
+       print STDERR "\n\n *** LaTeX produced no output ***\n"
+           . " *** no new images can be created\n"
+           . " *** Examine the  images.log  file.\n\n";
+       return;
+    }
+    print STDOUT "\n *** processing $image_counter images ***\n";
+    print STDOUT "\n *** LATEX LOG OK. ***\n" if ($VERBOSITY > 1);
+
+    if ($lengthsfound) {
+       $ODD_HMARGIN  = $hoffset + $oddsidemargin;
+       $EVEN_HMARGIN = $hoffset + $evensidemargin;
+       $VMARGIN = $voffset + $topmargin + $headheight + $headsep;
+        if ($dvi_mag >0 && $dvi_mag != 1000) {
+           $ODD_HMARGIN = int($dvi_mag /1000 * $ODD_HMARGIN);
+           $EVEN_HMARGIN = int($dvi_mag /1000 * $EVEN_HMARGIN);
+           $VMARGIN = int($dvi_mag /1000 * $VMARGIN);
+       }
+    } else {
+       $ODD_HMARGIN = 0;
+       $EVEN_HMARGIN = 0;
+       $VMARGIN = 0;
+    }
+    $ODD_HMARGIN  = int($ODD_HMARGIN*$TeXpt  + 72.5);
+    $EVEN_HMARGIN = int($EVEN_HMARGIN*$TeXpt + 72.5);
+    $VMARGIN = int($VMARGIN*$TeXpt + 72.5);
+    close(LOG);
+}
+
+sub extract_image { # clean
+    my ($page_num,$name) = @_;
+
+    # The followin come out of %img_params
+    my ($scale, $external, $thumbnail, $map, $psimage, $align, $usemap,
+         $flip, $aalias, $trans, $exscale, $alt, $exstr);
+
+    my ($lwidth, $val) = (0, '');
+    my ($custom_size,$color_depth,$height,$width,$croparg);
+
+    print STDOUT "\nextracting $name as $page_num\n" if ($VERBOSITY > 1);
+    # $global_num identifies this image in the original source file
+    # $new_num identifies this image in images.tex
+    my ($global_num, $new_num) = split(/#/, $page_num);
+    $name =~ s/\*/star/;
+    my ($env,$basename,$img) = ($name,"img$global_num",'');
+    $env =~ s/\d+$//;
+    $psname = sprintf("%s%.3d", "$TMPDIR$dd$IMAGE_PREFIX", $new_num);
+    if ( $EXTERNAL_IMAGES && $PS_IMAGES ) {
+       $img =  "$basename.ps";
+       L2hos->Copy("$psname.ps", "${PREFIX}$img");
+    } else {
+       $img = "$basename.$IMAGE_TYPE";
+       ($scale, $external, $thumbnail, $map, $psimage, $align, $usemap, 
+           $flip, $aalias, $trans, $exscale, $alt, $exstr) =
+            split('#', $img_params{$name});
+       $lwidth = ($align =~ s/nojustify/middle/) ? 0 : $LINE_WIDTH;
+       $alt = "ALT=\"$name\"" unless $alt;
+       $exscale = $EXTRA_IMAGE_SCALE unless($exscale);
+       if ($NO_IMAGES) {
+           L2hos->Symlink("image.$IMAGE_TYPE", "${PREFIX}$img");
+           if ($thumbnail) {
+               L2hos->Symlink("image.$IMAGE_TYPE", "${PREFIX}T$img");
+               $thumbnail = "${PREFIX}T$img";
+           }
+       } else {
+           # RRM: deal with size data
+           if ($width{$name} < 0) {
+               if ($exscale && $PK_GENERATION) {
+                   $height = int(                              
+                       $exscale*$height{$name}+        
+                       $exscale*$depth{$name} +.5);
+                   $width = int($exscale*$width{$name}-.5);
+               } else {
+                   $height = int($height{$name}+$depth{$name}+.5);
+                   $width = int($width{$name}-.5);
+               }
+               $custom_size = "${width}x$height";
+           } elsif ($width{$name}) {
+               if ($exscale && $PK_GENERATION) {
+                   $height = int( $height{$name} * $exscale +
+                       $depth{$name} * $exscale +.5);
+                   $width = int($width{$name} * $exscale +.5);
+               } else {
+                   $height = int($height{$name}+$depth{$name}+.5);
+                   $width = int($width{$name}+.5);
+               }
+               $custom_size = "${width}x$height";
+            } else {
+               $custom_size = '';
+           }
+            # MRO: add first overall crop
+           $croparg = '-crop a' . ($crop{$name} || '') . ' ';
+           $page_num  =~ s/^\d+#//o;
+           $custom_size .= " -margins "
+               . (($page_num % 2) ? $ODD_HMARGIN:$EVEN_HMARGIN)
+               . ",$VMARGIN" if ($custom_size);
+
+           #RRM: \special commands may place ink outside the expected bounds:
+           $custom_size = '' if ($tex_specials{$name});
+
+           # MRO: Patches for image conversion with pstoimg
+           # RRM: ...with modifications and fixes
+           L2hos->Unlink("${PREFIX}$img");
+           &close_dbm_database if $DJGPP;
+            print "Converting image #$new_num\n";
+
+           if ( ($name =~ /figure/) || $psimage || $scale || $thumbnail) {
+               $scale = $FIGURE_SCALE_FACTOR unless ($scale);
+               print "\nFIGURE: $name scaled $scale  $aalias\n" if ($VERBOSITY > 2);
+               (L2hos->syswait( "$PSTOIMG -type $IMAGE_TYPE "
+               . ($DEBUG ? '-debug ' : '-quiet ' )
+               . ($TMPDIR ? "-tmp $TMPDIR " : '' )
+               . (($DISCARD_PS && !$thumbnail && !$psimage)? "-discard " :'')
+               . (($INTERLACE) ? "-interlace " : '' )
+               . (((($ANTI_ALIAS)||($aalias))&&($aalias !~ /no|text/))? "-antialias ":'')
+               . (($ANTI_ALIAS_TEXT||(($aalias =~/text/)&&($aalias !~/no/)))?
+                       "-aaliastext ":'') 
+               . (($custom_size) ? "-geometry $custom_size ": '' )
+               . $croparg
+               . ($color_depth || '')
+               . (($flip) ? "-flip $flip " : '' )
+               . (($scale > 0) ? "-scale $scale " : '' )
+               . (((($TRANSPARENT_FIGURES && ($env =~ /figure/o))||($trans))
+                    &&(!($trans =~ /no/))) ? "-transparent " : '')
+               . (($WHITE_BACKGROUND) ? "-white " : '' )
+               . "-out ${PREFIX}$img $psname.ps"
+               ) ) # ||!(print "\nWriting image: ${PREFIX}$img"))
+                   && print "\nError while converting image: $!\n";
+
+               if ($thumbnail) { # $thumbnail contains the reduction factor
+                   L2hos->Unlink("${PREFIX}T$img");
+                   print "\nIMAGE thumbnail: $name" if ($VERBOSITY > 2);
+                   (L2hos->syswait( "$PSTOIMG -type $IMAGE_TYPE "
+                   . ($DEBUG ? '-debug ' : '-quiet ' )
+                   . ($TMPDIR ? "-tmp $TMPDIR " : '' )
+                   . (($DISCARD_PS && !$psimage) ? "-discard " : '' )
+                   . (($INTERLACE) ? "-interlace " : '' )
+                   . ((($ANTI_ALIAS||($aalias))&&(!($aalias =~/no/)))? "-antialias " :'')
+                   . (($ANTI_ALIAS_TEXT||(($aalias =~/text/)&&($aalias !~/no/)))?
+                       "-aaliastext ":'') 
+                   . (($custom_size) ? "-geometry $custom_size " : '' )
+                   . ($color_depth || '')
+                   . (($flip) ? "-flip $flip " : '' )
+                   . (($thumbnail > 0) ? "-scale $thumbnail " : '' )
+                   . ((($trans)&&(!($trans =~ /no/))) ? "-transparent " : '')
+                   . (($WHITE_BACKGROUND) ? "-white " : '' )
+                   . "-out ${PREFIX}T$img $psname.ps"
+                   ) ) # ||!(print "\nWriting image: ${PREFIX}T$img"))
+                       && print "\nError while converting thumbnail: $!\n";
+                   $thumbnail = "${PREFIX}T$img";
+               }
+           } elsif (($exscale &&(!$PK_GENERATION))&&($width{$name})) {
+               my $under = '';
+               my $mathscale = ($MATH_SCALE_FACTOR > 0) ? $MATH_SCALE_FACTOR : 1;
+               if (($DISP_SCALE_FACTOR > 0) &&
+                   ( $name =~ /equation|eqnarray|display/))
+                       { $mathscale *= $DISP_SCALE_FACTOR; };
+               if ($scale) {
+                   $scale *= $exscale if ($name =~ /makeimage|tab/);
+               } else {
+                   $scale = $mathscale*$exscale;
+                   $under = "d" if (($name =~/inline|indisplay/)&&($depth{$name}));
+               }
+               print "\nIMAGE: $name  scaled by $scale \n" if ($VERBOSITY > 2);
+               (L2hos->syswait( "$PSTOIMG -type $IMAGE_TYPE "
+               . ($DEBUG ? '-debug ' : '-quiet ' )
+               . ($TMPDIR ? "-tmp $TMPDIR " : '' )
+               . (($DISCARD_PS)? "-discard " : '' )
+               . (($INTERLACE)? "-interlace " : '' )
+               . ((($ANTI_ALIAS_TEXT||($aalias))&&($aalias !=~/no/))? 
+                   "-antialias -depth 1 " :'')
+               . (($custom_size)? "-geometry $custom_size " : '' )
+                . $croparg
+               . (($scale != 1)? "-scale $scale " : '' )
+               . ((($exscale)&&($exscale != 1)&&
+                   !($ANTI_ALIAS_TEXT &&($LATEX_COLOR)))? 
+                       "-shoreup $exscale$under " :'')
+               . ((($TRANSPARENT_FIGURES ||($trans))
+                    &&(!($trans =~ /no/)))? "-transparent " : '')
+               . (($WHITE_BACKGROUND && !$TRANSPARENT_FIGURES) ? "-white " : '' )
+               . "-out ${PREFIX}$img $psname.ps"
+               ) ) # ||!(print "\nWriting image: ${PREFIX}$img"))
+                   && print "\nError while converting image: $!\n";
+           } else {
+               print "\nIMAGE: $name\n" if ($VERBOSITY > 2);
+               my $under = '';
+               my $mathscale = ($MATH_SCALE_FACTOR > 0) ? $MATH_SCALE_FACTOR : 1;
+               if (($DISP_SCALE_FACTOR > 0) &&
+                   ( $name =~ /equation|eqnarray|display/))
+                       { $mathscale *= $DISP_SCALE_FACTOR; };
+               if (($scale)&&($exscale)) {
+                   $scale *= $exscale if ($name =~ /makeimage|tab/);
+               } elsif ($scale) {
+               } elsif (($mathscale)&&($exscale)) {
+                   $scale = $mathscale*$exscale;
+                   $under = "d" if (($name =~/inline|indisplay/)&&($depth{$name}));
+               } elsif ($mathscale) { $scale = $mathscale; }
+
+               (L2hos->syswait("$PSTOIMG -type $IMAGE_TYPE "
+               . ($DEBUG ? '-debug ' : '-quiet ' )
+               . ($TMPDIR ? "-tmp $TMPDIR " : '' )
+               . (($DISCARD_PS) ? "-discard " : '' )
+               . (($INTERLACE) ? "-interlace " : '' )
+               . ((($ANTI_ALIAS_TEXT||($aalias))&&(!($aalias =~ /no/)))?
+                   "-antialias -depth 1 " :'')
+               . ((($exscale)&&($exscale != 1)&&
+                   !($ANTI_ALIAS_TEXT &&($LATEX_COLOR)))? 
+                       "-shoreup $exscale " :'')
+               . (($scale ne 1) ? "-scale $scale " : '' )
+               . (($custom_size) ? "-geometry $custom_size " : '' )
+                . $croparg
+#              .  (($name =~ /(equation|eqnarray)/) ? "-rightjustify $lwidth " : '')
+#              .  (($name =~ /displaymath/) ? "-center $lwidth " : '')
+               . (($name =~ /inline|indisplay/ && (!($custom_size))&&$depth{$name}!= 0) ?
+                   do {$val=($height{$name}-$depth{$name})/($height{$name}+$depth{$name});
+                       "-topjustify x$val "} : '')
+               . ((($TRANSPARENT_FIGURES||($trans))
+                   &&(!($trans =~ /no/))) ? "-transparent " : '')
+               . (($WHITE_BACKGROUND && !$TRANSPARENT_FIGURES) ? "-white " : '' )
+               . "-out ${PREFIX}$img $psname.ps")
+               ) #|| !(print "\nWriting image: ${PREFIX}$img"))
+                   && print "\nError while converting image\n";
+           }
+           if (! -r "${PREFIX}$img") {
+               &write_warnings("\nFailed to convert image $psname.ps")
+           } else { } #L2hos->Unlink("$psname.ps") unless $DEBUG }
+           &open_dbm_database if $DJGPP;
+       }
+    }
+    print "\nextracted $name as $page_num\n" if ($VERBOSITY > 1);
+    &embed_image("${PREFIX}$img", $name, $external, $alt, $thumbnail, $map,
+        $align, $usemap, $exscale, $exstr);
+}
+
+sub extract_parameters {
+    local($contents) = @_;
+    local($_, $scale, $external, $thumbnail, $map, $psimage, $align,
+         $usemap, $flip, $aalias, $trans, $pagecolor, $alt, $exscale,
+         $cdepth, $htmlparams);
+
+    #remove the \htmlimage commands and arguments before...
+    $contents =~ s/$htmlimage_rx/$_ = $2;''/ego;
+    $contents =~ s/$htmlimage_pr_rx/$_ .= $2;''/ego;
+
+    # code adapted from original idea by Stephen Gildea:
+    # If the document specifies the ALT tag explicitly
+    # with \htmlimage{alt=some text} then use it.
+    s!alt=([^,]+)!$alt = $1;
+        $alt =~ s/^\s+|\s+$//g; $alt =~ s/"//g;
+        $alt="ALT=\"$alt\"";
+    ''!ie;
+
+  if (!$alt) {
+    #...catching all the code for the ALT text.
+    local($keep_gt)=1;
+    $alt = &flatten_math($contents); undef $keep_gt;
+    #RRM: too long strings upset the DBM. Truncate to <= 165 chars.
+    if ( length($alt) > 163 ) {
+       local($start,$end);
+       $start = substr($alt,0,80);
+       $end = substr($alt,length($alt)-80,80);
+       $alt = join('',$start,"...\n ...",$end);
+    }
+    s/ALT\s*=\"([\w\W]*)\"/$alt=$1;''/ie;
+    if ($alt) {
+       if ($alt =~ /\#/) {
+           $alt =~ s/^(\\vbox\{)?\#[A-Za-z]*\s*//;
+           $alt =~ s/\n?\#[A-Za-z]*\s*\}?$//s;
+           if ($alt =~ /\#/) { $alt = $` . " ... " };
+       }
+       $alt =~ s/\`\`/\\lq\\lq /g; $alt =~ s/\`/\\lq /g;
+       $alt =~ s/(^\s*|\s*$)//mg;
+       $alt = "ALT=\"$alt\"" if ($alt);
+    } else { $alt = 'ALT="image"' }
+  }
+
+    $psimage++ if ($contents =~ /\.ps/);
+#    $contents =~ s/\s//g;     # Remove spaces   Why ?
+    s/extrascale=([\.\d]*)/$exscale=$1;''/ie;
+    s/\bscale=([\.\d]*)/$scale=$1;''/ie;
+    s/(^|,\s*)external/$external=1;''/ie;
+    s/(^|,\s*)((no)?_?anti)alias(_?(text))?/$aalias = $2.$4;''/ie;
+    s/(^|,\s*)((no)?_?trans)parent/$trans = $2;''/ie;
+    s/thumbnail=([\.\d]*)/$thumbnail=$1;''/ie;
+    s/usemap=([^\s,]+)/$usemap=$1;''/ie;
+    s/map=([^\s,]+)/;$map=$1;''/ie;
+    s/align=([^\s,]+)/$align=$1;''/ie;
+    s/flip=([^\s,]+)/$flip=$1;''/ie;
+    s/color_?(depth)?=([^\s,]+)/$cdepth=$2;''/ie;
+    ($scale,$external,$thumbnail,$map,$psimage,$align
+     ,$usemap,$flip,$aalias,$trans,$exscale,$alt,$_);
+}
+
+
+# RRM: Put the raw \TeX code into the ALT tag
+# replacing artificial environments and awkward characters
+sub flatten_math {
+    local ($_) = @_;
+    $_ = &revert_to_raw_tex($_);
+    s/[ \t]+/ /g;
+    # MRO: replaced $* with /m
+    s/$tex2html_wrap_rx//gm;
+    s/(\\begin\s*\{[^\}]*\})(\s*(\[[^]]*\]))?[ \t]*/$1$3/gm;
+    s/(\\end\{[^\}]*\})\n?/$1/gm;
+    s/>(\w)?/($1)?"\\gt $1":"\\gt"/eg unless ($keep_gt); # replace > by \gt
+    s/\\\|(\w)?/($1)?"\\Vert $1":"\\Vert"/eg;  # replace \| by \Vert
+    s/\|(\w)?/($1)?"\\vert $1":"\\vert"/eg;    # replace | by \vert
+    s/\\\\/\\\\ /g;    # insert space after \\ 
+    s/\\"/\\uml /g;    # screen umlaut accents...
+    s/"/\'\'/g;                # replace " by ''
+    s/\\\#/\\char93 /g;        # replace \# by \char93 else caching fails
+#    s/"(\w)?/($1)?"\\rq\\rq $1":"\'\'"/eg;    # replace " by \rq\rq
+#    s/\&\\uml /\\\"/g;        # ...reinstate umlauts
+    $_;
+}
+
+sub scaled_image_size {
+    local($exscale,$_) = @_;
+    local($width,$height) = ('','');
+    /WIDTH=\"?(\d*)\"?\s*HEIGHT=\"?(\d*)\"?$/o;
+    $width=int($1/$exscale + .5);
+    $height=int($2/$exscale + .5);
+    "WIDTH=\"$width\" HEIGHT=\"$height\""
+}
+
+sub process_in_latex {
+    # This is just a wrapper for process_undefined_environment.
+    # @[0] = contents
+    $global{'max_id'}++;
+    &process_undefined_environment('tex2html_wrap',$global{'max_id'},$_[0]);
+}
+
+# MRO: cp deprecated, replaced by L2hos->Copy
+
+# Marcus Hennecke  6/3/96
+# MRO: test for existance
+sub copy_file {
+    local($file, $ext) = @_;
+    $file =  &fulltexpath("$FILE.$ext");
+    if(-r $file) {
+        print "\nNote: Copying '$file' for image generation\n"
+            if($VERBOSITY > 2);
+        L2hos->Copy($file, ".$dd${PREFIX}images.$ext");
+    }
+}
+
+sub rename_image_files {
+    local($_, $old_name, $prefix);
+    if ($PREFIX) {
+       foreach (<${PREFIX}*img*.$IMAGE_TYPE>) {
+           $old_name = $_;
+           s/\.$IMAGE_TYPE$/\.old/o;
+           L2hos->Rename($old_name, $_);
+           }
+       }
+    else {
+       foreach (<img*.$IMAGE_TYPE>) {
+           $old_name = $_;
+           s/\.$IMAGE_TYPE$/\.old/o;
+           L2hos->Rename($old_name, $_);
+       }
+       foreach (<Timg*.$IMAGE_TYPE>) {
+           $old_name = $_;
+           s/\.$IMAGE_TYPE$/\.old/o;
+           L2hos->Rename($old_name, $_);
+       }
+    }
+}
+
+
+############################ Processing Commands ##########################
+
+sub ignore_translate_commands {
+    local ($_) = @_;
+#   print "\nTranslating commands ...";
+
+    local(@processedC);
+    &replace_strange_accents;
+    local($before, $contents, $br_id, $after, $pattern, $end_cmd_rx);
+    s/$begin_cmd_rx/&replace_macro_expansion($`, $1, $&, $')/eg;
+}
+
+sub replace_macro_expansion {
+    push(@processedC,$_[1]);
+    $end_cmd_rx = &make_end_cmd_rx($_[2]);
+    $pattern = $_[3];
+    $_ = join('',$_[3],$_[4]);
+    $after = $_[4];
+    if (($before)&&(!($before =~ /$begin_cmd_rx/))) {
+       push(@processedC,$before);
+           $_ = join('',$pattern,$after); $before = '';
+       }
+       local($end_cmd_rx) = &make_end_cmd_rx($br_id);
+    
+}
+
+sub translate_aux_commands {
+    s/^(.*)$/&translate_commands($1)/s;
+}
+
+sub translate_commands {
+    local ($_) = @_;
+#   print "\nTranslating commands ...";
+
+    local(@processedC);
+    &replace_strange_accents;
+    for (;;) {                 # For each opening bracket ...
+       last unless ($_ =~ /$begin_cmd_rx/);
+       local($before, $contents, $br_id, $after, $pattern);
+       ($before, $br_id, $after, $pattern) = ($`, $1, $', $&);
+       if (($before)&&(!($before =~ /$begin_cmd_rx/))) {
+           push(@processedC,$before);
+           $_ = join('',$pattern,$after); $before = '';
+       }
+       local($end_cmd_rx) = &make_end_cmd_rx($br_id);
+       if ($after =~ /$end_cmd_rx/) { # ... find the the matching closing one
+           $NESTING_LEVEL++;
+           ($contents, $after) = ($`, $');
+           do {
+               local(@save_open_tags) = @$open_tags_R;
+               local($open_tags_R) = [ @save_open_tags ];
+               print STDOUT "\nIN::{$br_id}" if ($VERBOSITY > 4);
+               print STDOUT "\n:$contents\n" if ($VERBOSITY > 7);
+               undef $_;
+               $contents = &translate_commands($contents)
+                   if ($contents =~ /$match_br_rx/o);
+                # Modifies $contents
+               &process_command($single_cmd_rx,$contents)
+                   if ($contents =~ /\\/o);
+
+               $contents .= &balance_tags();
+           };
+
+           print STDOUT "\nOUT: {$br_id}" if ($VERBOSITY > 4);
+           print STDOUT "\n:$contents\n" if ($VERBOSITY > 7);
+           # THIS MARKS THE OPEN-CLOSE DELIMITERS AS PROCESSED
+           $_ = join("", $before,"$OP$br_id$CP", $contents,"$OP$br_id$CP", $after);
+           $NESTING_LEVEL--;
+       }
+       else {
+           $pattern = &escape_rx_chars($pattern);
+           s/$pattern//;
+           print "\nCannot find matching bracket for $br_id" unless $AUX_FILE;
+       }
+       last unless ($_ =~ /$begin_cmd_rx/o);
+    }
+    $_ = join('',@processedC) . $_;
+    # Now do any top level commands that are not inside any brackets
+    # MODIFIES $_
+    print $_ if ($VERBOSITY > 8);
+    &process_command($single_cmd_rx,$_);
+}
+
+#RRM: based on earlier work of Marcus Hennecke
+# makes sure the $open_tags_R at the end of an environment
+# is the same as @save_open_tags from the start,
+# ensuring that the HTML page indeed has balanced tags
+sub balance_tags {
+    local($tag_cmd, $tags, $save_tags, $open_tags, @reopen_tags);
+    $save_tags = join(',',@save_open_tags) if (@save_open_tags);
+    $open_tags = join(',',@$open_tags_R) if (@$open_tags_R);
+    if ($open_tags eq $save_tags) { return(); }
+    if ($save_tags =~ s/^$open_tags//) {
+       @reopen_tags = split (',',$');
+    } else {
+       @reopen_tags = @save_open_tags;
+       while (@$open_tags_R) {
+           $tag_cmd = pop (@$open_tags_R);
+           print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2;
+           $declarations{$tag_cmd} =~ m|</.*$|;
+           $tags .= $& unless ($` =~ /^<>$/);
+           $open_tags = join(',',@$open_tags_R) if (@$open_tags_R);
+           last if ( $save_tags =~ s/^$open_tags/
+                    @reopen_tags = split (',',$');''/e);
+       }
+    }
+    while (@reopen_tags) {
+       $tag_cmd = shift @reopen_tags;
+       if ($tag_cmd) {
+           push (@$open_tags_R, $tag_cmd) if ($tag_cmd);
+           print STDOUT "\n<$tag_cmd>" if $VERBOSITY > 2;
+           $declarations{$tag_cmd} =~ m|</.*$|;
+           $tags .= $` unless ($` =~ /^<>$/);
+       }
+    }
+    $tags;
+}
+
+sub close_all_tags {
+    return() if (!@$open_tags_R);
+    local($tags,$tag_cmd);
+    while (@$open_tags_R) {
+       $tag_cmd = pop (@$open_tags_R);
+       print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2;
+       $declarations{$tag_cmd} =~ m|</.*$|;
+       $tags .= $& unless ($` =~ /^<>$/);
+    }
+    $tags;
+}
+
+sub preserve_open_tags {
+    local(@save_open_tags) = @$open_tags_R;
+    local($open_tags_R) = [ @save_open_tags ];
+    # provides the markup to close and reopen the current tags
+    (&close_all_tags(), &balance_tags());
+}
+
+sub preserve_open_block_tags {
+    local($tag_cmd,$tags_open,$tags_close,$pre,$post,@tags);
+    while (@$open_tags_R) {
+       $tag_cmd = pop (@$open_tags_R);
+       print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2;
+       $declarations{$tag_cmd} =~ m|</.*$|;
+       ($pre,$post) = ($`,$&);
+       if ($post =~ /$block_close_rx/) {
+           # put it back and exit
+           push(@$open_tags_R,$tag_cmd);
+           last;
+       } else {
+           # leave it closed, collecting tags for it
+           $tags_close .= $post;
+           $tags_open = $pre . $tags_open;
+           unshift(@tags,$tag_cmd);
+       }
+    }
+    ($tags_close , $tags_open, @tags);  
+}
+
+sub minimize_open_tags {
+    local($this_tag, $close_only) = @_;
+    local($pre,$post,$decl);
+    $decl = $declarations{$this_tag};
+    if ($decl) {
+    # if it is a declaration, get the corresponding tags...
+       $decl =~ m|</.*$|;
+       ($pre,$post) = ($`,$&) unless ($` =~ /^<>$/);
+       if (!@$open_tags_R) { # when nothing else is open...
+            # pushing the style, when appropriate
+           push (@$open_tags_R, $this_tag)
+               unless ($close_only ||($post =~ /$block_close_rx/));
+           print STDOUT "\n<$this_tag>" if $VERBOSITY > 2;
+            # and return the tags
+           return($pre,$post) unless ($USING_STYLES);
+           local($env_id) = '' if ($env_id =~/^\w+$/);
+           $pre =~ s/>$/ $env_id>/ if ($env_id);
+           return($pre,$post);
+       }
+    } else { # ...else record the argument as $pre
+       $pre = $this_tag unless $close_only;
+    }
+    local($env_id) = '' if ($env_id =~/^\w+$/);
+    $pre =~ s/>$/ ID="$env_id">/ if ($USING_STYLES &&($env_id));
+
+    # return the tags, if nothing is already open
+    if (!@$open_tags_R) { 
+       return($pre,$post);
+    }
+#    elsif ($close_only) { push (@$open_tags_R, $this_tag) }
+
+    local($tags,$tag_cmd,$tag_open);
+    local($closures,$reopens,@tags);
+    local($tag_close,$tag_open);
+    local($size_cmd,$size_open);
+    local($font_cmd,$font_open);
+    local($fontwt_cmd,$fontwt_open);
+    local($color_cmd,$color_open);
+     if ($decl) {
+       if ($this_tag =~ /$sizechange_rx/) { 
+           $size_cmd = $this_tag;
+       } else {
+           if ($this_tag =~ /$fontchange_rx/) { 
+               $font_cmd = $this_tag }
+           if ($this_tag =~ /$fontweight_rx/) { 
+               $fontwt_cmd = $this_tag }
+       }
+    }
+    while (@$open_tags_R) {
+       ($tag_close,$tag_open) = ('','');
+       $tag_cmd = pop (@$open_tags_R);
+       print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2;
+       $declarations{$tag_cmd} =~ m|</.*$|;
+       ($tag_close,$tag_open) = ($&,$`) unless ($` =~ /<>/);
+       $closures .= $tag_close;
+
+       if ((!$size_cmd)&&($tag_cmd =~ /$sizechange_rx/)) {
+           $size_cmd = $tag_cmd;
+           $size_open = $tag_open;
+       }
+       elsif ((!$font_cmd)&&($tag_cmd =~ /$fontchange_rx/)) {
+           $font_cmd = $tag_cmd;
+           $font_open = $tag_open;
+       }
+       elsif ((!$fontwt_cmd)&&($tag_cmd =~ /$fontweight_rx/)) {
+           $fontwt_cmd = $tag_cmd;
+           $fontwt_open = $tag_open;
+       }
+       elsif ((!$color_cmd)&&($tag_cmd =~ /$colorchange_rx/)) {
+           $color_cmd = $tag_cmd;
+           $color_open = $tag_open;
+       } 
+       elsif ($tag_cmd =~ 
+            /$sizechange_rx|$fontchange_rx|$fontweight_rx|$colorchange_rx/) {
+       } else {
+           unshift (@tags, $tag_cmd);
+           print STDOUT "\n<<$tag_cmd>" if $VERBOSITY > 2;
+           $reopens = $tag_open . $reopens;
+       }
+    }
+    if ($USING_STYLES) {
+       local($TAG) = "DIV";
+       if ($pre =~ /^<(DIV|SPAN|PRE)/) { $TAG = $1 };
+       if (($pre =~ /^<$TAG/)&&($env_id =~ /^\s+(CLASS|ID)/)) {
+           $pre =~ s/<$TAG/<$TAG$env_id/;
+       } elsif ($pre =~ /<P>/) {
+           $TAG = 'P';
+       } else {
+       }
+#      $post .= "</$TAG>";
+    }
+    push (@$open_tags_R, @tags);
+    $tags .= $pre if ($pre && $post =~ /$block_close_rx/);
+    if ($font_cmd && !($font_cmd eq $this_tag)) {
+       push (@$open_tags_R,$font_cmd);
+       print STDOUT "\n<$font_cmd>" if $VERBOSITY > 2;
+       $tags .= $font_open;
+    }
+    if ($fontwt_cmd && !($fontwt_cmd eq $this_tag)) {
+       push (@$open_tags_R,$fontwt_cmd);
+       print STDOUT "\n<$fontwt_cmd>" if $VERBOSITY > 2;
+       $tags .= $fontwt_open;
+    }
+    if ($size_cmd && !($size_cmd eq $this_tag)) {
+       push (@$open_tags_R,$size_cmd);
+       print STDOUT "\n<$size_cmd>" if $VERBOSITY > 2;
+       $tags .= $size_open;
+    }
+    if ($color_cmd && !($color_cmd eq $this_tag)) {
+       push (@$open_tags_R,$color_cmd);
+       print STDOUT "\n<$color_cmd>" if $VERBOSITY > 2;
+       $tags .= $color_open;
+    }
+    $tags .= $pre unless ($pre && $post =~ /$block_close_rx/);
+    push (@$open_tags_R, $this_tag)
+       if ($decl &&!($post =~ /$block_close_rx|$all_close_rx/));
+    print STDOUT "\n<$this_tag>" if $VERBOSITY > 2;
+    ($closures.$reopens.$tags , $post );
+}
+
+
+sub declared_env {
+    local($decl, $_, $deferred) = @_;
+    local($after_cell,$pre,$post);
+    local($decls) = $declarations{$decl};
+    $decls =~ m|</.*$|;
+    ($pre,$post) = ($`,$&);
+    if ($USING_STYLES) {
+       $env_style{$decl} = " " unless ($env_style{$decl});
+       $pre =~ s/>$/$env_id>/ if ($env_id);
+    }
+    local($closing_tag) = 1 if ($pre =~ /^<>$/);
+    $pre = $post = '' if $closing_tag;
+    local($closures,$reopens);
+
+    local(@save_open_tags) = @$open_tags_R
+       unless ($closing_tag || $deferred);
+    local($open_tags_R) = [ @save_open_tags ]
+       unless ($closing_tag || $deferred );
+
+    if ($post =~ /$block_close_rx/) {
+       local($last_tag) = pop (@$open_tags_R);
+       local($ldecl) = $declarations{$last_tag};
+       if ($ldecl =~ m|</.*$|) { $ldecl = $& }
+       if (($last_tag)&&!($ldecl =~ /$block_close_rx/)) {
+           # need to close tags, for re-opening inside
+           push (@$open_tags_R, $last_tag);
+           ($closures,$reopens) = &preserve_open_tags();
+           $pre = join('', $closures, "\n", $pre, $reopens);
+           $post = join('', $closures, $post, $reopens);
+       } elsif ($last_tag) {
+           $pre = "\n".$pre;
+           push (@$open_tags_R, $last_tag);
+           undef $ldecl;
+       } else {
+       }
+
+       if ($deferred) {
+           if (defined $ldecl) {
+               print STDOUT "\n<<$decl>" if $VERBOSITY > 2;
+               unshift(@$open_tags_R, $decl);
+           } else {
+               print STDOUT "\n<$decl>" if $VERBOSITY > 2;
+               push(@$open_tags_R, $decl);
+           }
+           return ( $pre . $_ );
+       } else {
+           if (defined $ldecl) {
+               print STDOUT "\n<<$decl>" if $VERBOSITY > 2;
+               unshift(@$open_tags_R, $decl);
+           } else {
+               print STDOUT "\n<$decl>" if $VERBOSITY > 2;
+               push(@$open_tags_R, $decl);
+           }
+       }
+    } elsif ($post =~/$all_close_rx/) {
+       ($closures,$reopens) = &preserve_open_tags();
+       ($pre,$post) = &minimize_open_tags($decl,1);
+       $pre = join('', $closures, $pre);
+    } elsif ($closing_tag) {
+       $prev_open = $pre;
+       ($pre,$post) = &minimize_open_tags($decl,1);
+       $pre =~ s/<\/?>//g; $post =~ s/<\/?>//;
+    } else {
+       ($pre,$post) = &minimize_open_tags($decl); 
+    }
+    $_ =~ s/^\s+//s; #RRM:28/4/99 remove spaces at the beginning
+    $_ = &translate_environments($_);
+    $_ = &translate_commands($_) if (/\\/);
+    if ($post =~ /$block_close_rx/) {
+       s/^\n?/\n/o; 
+       if (defined $ldecl) {
+           $post = &close_all_tags();
+       } else {
+           $post = "\n";
+       }
+    } elsif ($post =~/$all_close_rx/) {
+    } else { $post = '' };
+
+    join('', $pre, $_, $post
+          , ($closing_tag ? '' : &balance_tags()) );
+}
+
+sub do_cmd_centering{&declared_env('center',$_[0],$tex2html_deferred)}
+sub do_cmd_raggedright{&declared_env('flushleft',$_[0],$tex2html_deferred)}
+sub do_cmd_raggedleft{&declared_env('flushright',$_[0],$tex2html_deferred)}
+
+sub do_env_verse { &declared_env('verse',@_) }
+sub do_env_quote { &declared_env('quote', @_) }
+sub do_env_quotation { &declared_env('quote', @_) }
+sub do_env_tex2html_preform { &declared_env('preform', @_) }
+sub do_env_tex2html_ord { &declared_env('ord', @_) }
+sub do_env_tex2html_unord { &declared_env('unord', @_) }
+sub do_env_tex2html_desc { &declared_env('desc', @_) }
+
+
+# Modifies $contents
+sub process_command {
+    # MRO: modified to use $_[1]
+    # local ($cmd_rx, *ref_contents) = @_;
+    local ($cmd_rx) = @_;
+    local($ref_before, $cmd , $pc_after);
+    local($cmd_sub, $cmd_msub, $cmd_trans, $mathentity);
+    local (@open_font_tags,@open_size_tags);
+    $_[1] = &convert_iso_latin_chars($_[1])
+       unless (($cmd =~ /(Make)?([Uu]pp|[Ll]ow)ercase/)||
+           ((!$cmd)&&($_[1] =~ /^\\(Make)?([Uu]pp|[Ll]ow)ercase/s)));
+
+    local(@ref_processed);
+    for (;;) {                 # Do NOT use the o option
+       last unless ($_[1] =~ /$cmd_rx/ );
+       print ".";
+       #JCL(jcl-del) - use new regexp form which handles white space
+       ($ref_before, $cmd, $pc_after) = ($`, $1.$2, $4.$');
+       push(@ref_processed,$ref_before);
+#print "\nAFTER:$1.$2:".$4."\n" if ($cmd_rx eq $single_cmd_rx);
+       print STDOUT "$cmd" if ($VERBOSITY > 2);
+       print STDOUT "\nIN: $_[1]\n" if ($VERBOSITY > 6);
+       #
+       if ( $cmd = &normalize($cmd,$pc_after) ) {
+           ($cmd_sub, $cmd_msub, $cmd_trans, $mathentity) =
+               ("do_cmd_$cmd", "do_math_cmd_$cmd"
+               , $declarations{$cmd}, $mathentities{$cmd});
+           if ($new_command{$cmd}||$renew_command{$cmd}) { 
+                # e.g. some \the$counter 
+               local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd});
+               &make_unique($body) if ($body =~ /$O/);
+               if ($argn) {
+                   do { 
+                       local($before) = '';
+                       local($_) = "\\$cmd ".$pc_after;
+                       # &substitute_newcmd  may need what comes after the $cmd
+                       # from the value of $after 
+                       #RRM: maybe best to pass it as a parameter ?
+                       my $keep_after = $after;
+                       $after = $pc_after;
+                       $pc_after = &substitute_newcmd;   # may change $after
+                       $pc_after =~ s/\\\@#\@\@/\\/o ;
+                       $pc_after .= $after;
+                       $after = $keep_after;
+                   }
+               } else {
+                   $pc_after = $body . $pc_after;
+               }
+           } elsif (defined &$cmd_sub) {
+               # $ref_before may also be modified ...
+               if ($cmd =~ /$sizechange_rx/o) {
+                   $pc_after = &$cmd_sub($pc_after, $open_tags_R);
+               } else {
+                   $pc_after = &$cmd_sub($pc_after, $open_tags_R);
+               };
+           } elsif ((defined &$cmd_msub)&&!$NO_SIMPLE_MATH) {
+#print "\nMCMD:$cmd_msub :  ";
+               # $ref_before may also be modified ...
+               $pc_after = &$cmd_msub($pc_after, $open_tags_R);
+               if ( !$math_mode ) {
+                   $pc_after = "<MATH>" . $pc_after . "</MATH>";
+                   ++$commands_outside_math{$cmd};
+               };
+           } elsif ($cmd_trans) { # One to one transform
+#print "\nCMD-DECL: $inside_tabular : $cmd_trans". join(',',@$open_tags_R);
+               if ($inside_tabular) {
+                   push (@ref_processed , "\\$cmd ")
+               } else {
+                   $cmd_trans =~ m|</.*$|;
+                   $pc_after = $` . $pc_after unless ($` =~ /^<>/);
+                   push(@$open_tags_R, $cmd)
+                       if ($cmd =~ /$fontchange_rx|$fontweight_rx|$sizechange_rx/o);
+               }
+           } elsif ($mathentity) {
+#print "\nM-ENT:$mathentity :  ";
+               if ( $math_mode ) {
+                   $pc_after = "&$mathentity#$cmd;" . $pc_after;
+               } elsif ($NO_SIMPLE_MATH) {
+                   $pc_after = "&$mathentity#$cmd;" . $pc_after;
+#                  ++$commands_outside_math{$cmd};
+               } else {
+                   $pc_after = "<MATH>&$mathentity#$cmd;</MATH>" . $pc_after;
+                   ++$commands_outside_math{$cmd};
+               }
+           } elsif ($ignore{$cmd}) { # Ignored command
+               print "\nignoring \\$cmd" if $VERBOSITY > 5;
+               $pc_after = join('', " ", $pc_after) if ($cmd eq " "); # catches `\ '
+               $pc_after = join(''," ", $pc_after)
+                   if (($cmd eq ',')&&($pc_after =~ /^\-/s)&&($ref_before =~/\-$/s));
+           } elsif ($cmd =~ /^the(.+)$/){
+               $counter = $1;
+               local($tmp)="do_cmd_$cmd";
+               if (defined &$tmp) { # Counter
+                   $pc_after = &do_cmd_thecounter($pc_after);
+               } else {
+                   if (defined $failed) {
+                       $failed = 1;
+#                      $ref_before .= "$cmd";
+                       push(@ref_processed,$cmd);  # $ref_before .= "$cmd";
+                   } else {  &declare_unknown_cmd($cmd) }
+#                  $ref_before .= "$cmd" if ($failed);
+               }
+           } elsif ($cmd eq "\n") { push(@ref_processed," ");  # $ref_before .= " "; 
+           } else {
+               # Do not add if reading an auxiliary file
+               if (defined $failed) { 
+                   $failed = 1;
+               } else { &declare_unknown_cmd($cmd) }
+           }
+       } else {
+           # &normalize should have already handled it adequately
+           # '\ ' (space) gets thru to here. Perhaps some others too ?
+#          print "\n ?? This should not happen: \\$cmd ??\n";
+       }
+#      $_[1] = join('', $ref_before, $pc_after);
+       $_[1] = $pc_after;
+       print STDOUT "\n-> $ref_before\n" if ($VERBOSITY > 6);
+    }
+    $_[1] = join('',@ref_processed).$_[1];
+}
+
+sub declare_unknown_cmd {
+    local($this_cmd) = @_;
+    local($tmp) = "wrap_cmd_$cmd";
+    do { ++$unknown_commands{$cmd};
+       print STDOUT "\n*** Unknown command[1]: \\$cmd *** \n" 
+           if ($VERBOSITY > 2);
+    } unless ($AUX_FILE||(defined &$tmp)||($image_switch_rx=~/\b\Q$cmd\E\b/));
+}
+
+
+# This makes images from the code for math-entities,
+# when $NO_SIMPLE_MATH is set and the  math  extension is loaded.
+#
+sub replace_math_constructions {
+    local($math_mode) = @_;
+    &make_math_box_images($math_mode) if (/<BOX>/);
+    &make_math_entity_images($math_mode) if (/\&\w+#\w+;/);
+}
+
+sub make_math_box_images {
+    local($math_mode) = @_;
+    local($pre,$this,$post,$tmp) = ('','','');
+    local($slevel,$blevel) = 0;
+
+    while (/<BOX>/) {
+       $pre .= $`; $tmp = $`; $this = ''; $post = $';  
+       # compute the super/sub-scripting level for each entity
+       $tmp =~ s/<(\/?)SU[BP]>/
+           if ($1) { $slevel--} else { $slevel++};''/eog;
+
+       $tmp = $post;
+       if ($tmp =~ /<(\/?)BOX>/o ) {
+           if ($1) { $this = $`; $post = $' }
+           else { $failed = 1 } # nested box, too complicated !
+       } else {
+           &write_warnings("\nLost end of a <BOX> ?");
+           $failed = 1;
+       }
+       last if ($failed);
+
+       ($this,$_) = &process_box_in_latex(
+                   $math_mode, $slevel, $this, $post);
+       $_ =~ s/^\s*//; # remove any leading spaces
+       $pre .= $this ."\001"; 
+    }
+    return  if ($failed);
+    $_ = $pre . $_;
+}
+
+sub make_math_entity_images {
+    local($math_mode) = @_;
+    local($pre,$this,$post,$tmp) = ('','','');
+    local($slevel) = 0;
+    # compute the super/sub-scripting level for each entity
+    while (/\&\w+#(\w+);/) {
+       $pre .= $`; $tmp = $`; $this = $1; $post = $';
+       $tmp =~ s/<(\/?)SU[BP]>/
+           if ($1) { $slevel--} else { $slevel++};''/eog; 
+       ($this,$_) = &process_entity_in_latex(
+               $math_mode, $slevel, $this, $post);
+       $_ =~ s/^\s*//; # remove any leading spaces
+       $pre .= $this ."\001"; 
+    }
+    $_ = $pre . $_;
+}
+
+
+#RRM:  Revert a math-entity to create image using LaTeX, together with
+# any super/sub-scripts (possibly nested or with \limits ).
+# Must also get the correct  \display/text/(script)script  style.
+#
+sub process_entity_in_latex {
+    local($mode,$level,$entity,$after) = @_;
+    local($math_style,$supsub,$rest) = ('','','');
+    $level++ if ($mode =~/box/); # for top/bottom of inline fractions, etc.
+
+    if ($level) {
+       $math_style = "\\". (($level > 1) ? "script" : "")."scriptstyle"
+    } else {
+       $math_style = "\\displaystyle" unless ($mode =~ /inline/);
+    }
+    while ($after =~ s/^\s*((\\limits|\&limits;)?\s*<SU(P|B)>)\s*/$supsub .= $1;''/eo) {
+       local($slevel) = 1;
+       local($aftersupb) = '';
+       while ($slevel) {
+           $after =~ s/(<(\/)SU(B|P)>)/($2)? $slevel-- : $slevel++;''/oe;
+           $supsub .= $`.$&;
+           $aftersupb = $';
+       }
+       $after = $aftersupb;
+    }
+
+    local($latex_code) = "\$$math_style\\$entity$supsub\$";
+
+    $global{'max_id'}++;
+    ( &process_undefined_environment('tex2html_wrap_inline'
+            ,$global{'max_id'}, $latex_code ) , $after);
+}
+
+sub process_box_in_latex {
+    local($mode,$level,$inside,$after) = @_;
+    local($math_style,$which,$pre,$post,$tmp) = ('','',"\{","\}");
+    
+    if ($level) {
+       $math_style = "\\". (($level > 1) ? "script" : "")."scriptstyle"
+    } else {
+       $math_style = "\\displaystyle" unless ($mode =~ /inline/);
+    }
+
+    if ($inside =~ /<((LEFT)|(RIGHT))>/ ) {
+       $pre = "\\left"; $post = "\\right";
+       if ($2) { 
+           $tmp = $`; $inside = $';
+           $pre .= (($tmp) ? $tmp : ".") . "\{";
+           if ( $inside =~ /<RIGHT>/ ) {
+               $tmp = $';
+               $inside = $`;
+               $post = "\}". (($tmp) ? $tmp : ".");
+           }
+       } else {
+           $pre .= ".\{"; $tmp = $'; $inside = $`;
+           $post = "\}". (($tmp) ? $tmp : ".");
+       }
+    }
+    if ( $inside =~ /<((OVER)|(ATOP)|(CHOOSE))>/ ) {
+       $pre .= $`;
+       $post = $' . $post ;
+       if ($2) { $which = "over " }
+       elsif ($3) { $which = "atop " }
+       elsif ($4) { $which = "atopwithdelims\(\)" }
+    }
+
+    local($latex_code) = join('', "\$" , $math_style , " ", $pre 
+         , (($which)? "\\$which" : "") , $post , "\$" );
+
+    if ($after =~ s/<SUP ALIGN=\"CENTER\">([^<]*)<\/SUP>/
+       $tmp =$1;''/eo ) {
+       $latex_code = join('', "\\stackrel" , $latex_code
+                          , "\{" , $tmp , "\}" );
+    }
+    
+    $global{'max_id'}++;
+    ( &process_undefined_environment('tex2html_wrap_inline'
+            ,$global{'max_id'}, $latex_code ) , $after);
+}
+
+####################### Processing Meta Commands ############################
+# This is a specialised version of process_command above.
+# The special commands (newcommand, newenvironment etc.)
+# must be processed before translating their arguments,
+# and before we cut up the document into sections
+# (there might be sectioning commands in the new definitions etc.).
+# \newtheorem commands are treated during normal processing by
+# generating code for the environments they define.
+
+sub substitute_meta_cmds {
+    local ($next_def);
+    local ($cmd, $arg, $argn, $opt, $body, $before, $xafter);
+    local ($new_cmd_no_delim_rx, $new_cmd_rx, $new_env_rx, $new_cmd_or_env_rx);
+    local ($new_end_env_rx);
+    &tokenize($meta_cmd_rx);   #JCL(jcl-del) - put delimiter after meta command
+    print "\nProcessing macros ..." if (%new_command || %new_environment);
+    # First complete any replacement left-over from the previous part.
+    if ($UNFINISHED_ENV) { 
+       s/$UNFINISHED_ENV/$REPLACE_END_ENV/;
+       $UNFINISHED_ENV = '';
+       $REPLACE_END_ENV = '';
+    }
+
+    local(@processed);
+    local($processed, $before, $after)=('', '', $_);
+    while ($after =~ /$meta_cmd_rx$EOL/o) {    # ... and uses the delimiter
+       ($cmd, $after) = ($1.$2, $');
+       $before .= $`;
+#      $next_def = '';
+       if (!($before =~ /$meta_cmd_rx$EOL/)) {
+           push(@processed, $before); $before = '';
+       }
+                
+       print ",";
+#      $next_def = "\\$cmd" unless (($cmd =~ /renewcommand/));
+       local($cmd_sub) = "get_body_$cmd";
+       if (defined &$cmd_sub) {
+#          $processed = &$cmd_sub(*after);
+           $processed = &$cmd_sub(\$after);
+#          if ($processed) { $after = $before . $processed; }
+#          $next_def = '' 
+#              if (($PREAMBLE > 1)&&($cmd =~ /(re)?newcommand/));
+#          &add_to_preamble($cmd, $next_def)
+#              unless ($next_def =~ /^\s*$/);
+### new style of handling meta-commands
+           if ($processed) { push(@processed, "\\".$processed) }
+       }
+       elsif ($before) {
+           # this shouldn't happen !!
+           print STDERR "\nCannot handle \\$cmd , since there is no $cmd_sub ";
+           $after = $before . $cmd . $after;
+           $before = '';
+       } else { 
+           push(@processed, "\\$cmd ") if $cmd;
+       }
+    }
+    print "\nmeta-commands: ". (0+@processed) ." found "
+       if ((@processed)&&($VERBOSITY > 1));
+    $_ = join('',@processed, $after); undef @processed;
+    if ($PREAMBLE) {
+       # MRO: replaced $* with /m
+        s/((\n$comment_mark\d*)+\n)//gm;
+        s/(\\par\b\s*\n?)+/\\par\n/gm;
+        s/(\\par\b\n?)+/\\par\n/gm;
+    }
+
+    # hard-code the new-command replacements for these
+    $new_command{'begingroup'} = "0:!:\\begin<<0>>tex2html_begingroup<<0>>:!:}";
+    $new_command{'endgroup'} = "0:!:\\end<<0>>tex2html_begingroup<<0>>:!:}";
+    $new_command{'bgroup'} = "0:!:\\begin<<0>>tex2html_bgroup<<0>>:!:}";
+    $new_command{'egroup'} = "0:!:\\end<<0>>tex2html_bgroup<<0>>:!:}";
+
+    # All the definitions have now moved to the $preamble and their bodies
+    # are stored in %new_command and %new_environment
+    #
+    # Now substitute the new commands and environments:
+    # (must do them all together because of cross definitions)
+    $new_cmd_rx = &make_new_cmd_rx(keys %new_command);
+    $new_cmd_no_delim_rx = &make_new_cmd_no_delim_rx(keys %new_command);
+    $new_env_rx = &make_new_env_rx;
+    $new_end_env_rx = &make_new_end_env_rx;
+#    $new_cnt_rx = &make_new_cnt_rx(keys %new_counter);
+    $new_cmd_or_env_rx = join("|", $new_cmd_no_delim_rx." ", $new_env_rx);
+#    $new_cmd_or_env_rx = join("|", $new_cmd_no_delim_rx." ", $new_env_rx, " ".$new_cnt_rx);
+    $new_cmd_or_env_rx =~ s/^ \||\|$//;
+
+    print STDOUT "\nnew commands:\n" if ($VERBOSITY > 2);
+    while (($cmd, $body) = each %new_command) {
+       unless ($expanded{"CMD$cmd"}++) {
+           print STDOUT ".$cmd " if ($VERBOSITY > 2);
+           $new_command{$cmd} = &expand_body;
+           print STDOUT " ".$new_command{$cmd}."\n" if ($VERBOSITY > 4);
+           &write_mydb("new_command", $cmd, $new_command{$cmd});
+       }
+    }
+
+    print STDOUT "\nnew environments:\n" if ($VERBOSITY > 2);
+    while (($cmd, $body) = each %new_environment) {
+       unless ($expanded{"ENV$cmd"}++) {
+           print STDOUT ".$cmd" if ($VERBOSITY > 2);
+           $new_environment{$cmd} = &expand_body;
+           &write_mydb("new_environment", $cmd, $new_environment{$cmd});
+       }
+    }
+
+    print STDOUT "\nnew counters and dependencies:\n" if ($VERBOSITY > 2);
+    &clear_mydb("dependent") if ($DEBUG);     #avoids appending to a previous version
+    while (($cmd, $body) = each %dependent) {
+       print STDOUT ".($cmd,$body)" if ($VERBOSITY > 2);
+        &write_mydb("dependent", $cmd, $dependent{$cmd});
+    }
+    &clear_mydb("img_style") if ($DEBUG);     #avoids appending to a previous version
+    while (($cmd, $body) = each %img_style) {
+        &write_mydb("img_style", $cmd, $img_style{$cmd});
+    }
+
+    &clear_mydb("depends_on") if ($DEBUG);     #avoids appending to a previous version
+    while (($cmd, $body) = each %depends_on) {
+       print STDOUT ".($cmd,$body)" if ($VERBOSITY > 2);
+        &write_mydb("depends_on", $cmd, $depends_on{$cmd});
+    }
+
+
+    &clear_mydb("styleID") if ($DEBUG);     #avoids appending to a previous version
+    while (($cmd, $body) = each %styleID) {
+        &write_mydb("styleID", $cmd, $styleID{$cmd});
+    }
+
+    &clear_mydb("env_style") if ($DEBUG);     #avoids appending to a previous version
+    while (($cmd, $body) = each %env_style) {
+        &write_mydb("env_style", $cmd, $env_style{$cmd});
+    }
+    &clear_mydb("txt_style") if ($DEBUG);     #avoids appending to a previous version
+    while (($cmd, $body) = each %txt_style) {
+        &write_mydb("txt_style", $cmd, $txt_style{$cmd});
+    }
+
+    print STDOUT "\ntheorem counters:\n" if ($VERBOSITY > 2);
+    &clear_mydb("new_theorem") if ($DEBUG);     #avoids appending to a previous version
+    while (($cmd, $body) = each %new_theorem) {
+       print STDOUT ".($cmd,$body)" if ($VERBOSITY > 2);
+        &write_mydb("new_theorem", $cmd, $new_theorem{$cmd});
+    }
+
+
+    print "+";
+    if (length($new_env_rx)) {
+       local(@pieces);
+        print STDOUT "\nsubstituting new environments: $new_env_rx\n" if ($VERBOSITY > 3);
+#      while (/\n?$new_env_rx/ && (($before, $cmd, $after) = ($`, $2, $'))) {
+       while (/$new_env_rx/ && (($before, $cmd, $after) = ($`, $2, $'))) {
+           print STDOUT ",";
+           print STDOUT "{$cmd}" if ($VERBOSITY > 1);
+           if (!($before =~ /$new_env_rx/)) {
+               push (@pieces, $before); $before = ''; print "{}";
+           }
+           $_ = join('',$before, &substitute_newenv);
+       }
+       print "\n ".(0+@pieces). " new environments replaced\n" if (@pieces);
+       $_ = join('', @pieces, $_); undef @pieces;      
+    }
+
+
+    print "+";
+    if (length($new_cmd_rx)) {
+       print STDOUT "\ntokenizing: $new_cmd_rx\n" if ($VERBOSITY > 2);
+       &tokenize($new_cmd_rx); # Put delimiter after the new commands
+
+       # and use the delimiter.
+       print STDOUT "\nsubstituting new commands: $new_cmd_rx\n" if ($VERBOSITY > 2);
+       print STDOUT "\ninitial size: ".length($after) if ($VERBOSITY > 1);
+       # store processed pieces in an array
+       local($this_cmd, @pieces);
+       # speed-up processing of long files by splitting into smaller segments
+       # but don't split within the preamble, else \newenvironment may break
+       local($pre_segment,@segments); &make_sections_rx;
+       local($within_preamble,$this_section) = 1 if ($PREAMBLE>1);
+       while (/$sections_rx/) {
+           $pre_segment .= $`; $_ = $'; $this_section = $&;
+           do {
+               push(@segments,$pre_segment);
+               $pre_segment = '';
+           } unless ($within_preamble);
+           $within_preamble = 0 if ($within_preamble && ($pre_segment =~ 
+                   /\\(startdocument|begin\s*($O\d+${C})\s*document\s*\2)/));
+           $pre_segment .= $this_section;
+       }
+       push(@segments,$pre_segment.$_);
+       local($replacements,$seg) ; $before = ''; # count the segments
+       local($within_preamble) = 1 if ($PREAMBLE>1);
+       foreach $after (@segments) {
+         while ($after =~ /(\\(expandafter|noexpand)\b\s*)?$new_cmd_no_delim_rx\b\s?/) {
+           ($before, $xafter, $cmd, $after) = ($`, $2, $3, $');
+           $within_preamble = 0
+               if ($before =~ /\\(startdocument|begin\s*($O\d+${C})\s*document\s*\2)/);
+           push(@pieces, $before);
+           print "."; ++$replacements;
+           print STDOUT "$cmd" if ($VERBOSITY > 2);
+           if ($xafter =~ /no/) { $this_cmd = "\\\@#\@\@".$cmd  }
+           elsif (($xafter =~ /after/)&&($after =~ /^\s*\\/)) {
+               local($delayed) = $cmd;
+               local($nextcmd);
+               $after =~ s/^\s*\\([a-zA-Z]+|.)/$nextcmd = $1;''/eo;
+               ($cmd,$nextcmd) = ($nextcmd, "do_cmd_$nextcmd");
+               if (defined &$nextcmd) { $after = &$nextcmd($after); }
+               elsif ($new_command{$cmd}) { 
+                   local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd});
+                   &make_unique($body) if ($body =~ /$O/);
+                   if ($argn) {
+                       do { 
+                           local($before) = '';
+                           $after = join('',&substitute_newcmd, $after);
+                           $after =~ s/\\\@#\@\@/\\/o ;
+                       };
+                   } else { $after = $body . $after; }
+               } else { print "\nUNKNOWN COMMAND: $cmd "; }
+               $cmd = $delayed;
+               if ($new_command{$cmd}) {
+                   if ($renew_command{$cmd}) {
+#                      # must wrap it in a deferred environment
+#                      $this_cmd = join('', &make_deferred_wrapper(1)
+#                              ,"\\$cmd".(($cmd =~ /\w$/)? " ":'')
+#                              , &make_deferred_wrapper(0));
+#                      push(@pieces, $this_cmd); $this_cmd = '';
+                       push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":''));
+                       $this_cmd = '';
+                   } elsif ($provide_command{$cmd}&&$within_preamble) {
+                       # leave it alone
+                       push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":''));
+                       $this_cmd = '';
+                   } else {
+                       # do the substitution
+                       $this_cmd = &substitute_newcmd;
+                   }
+               }
+           } elsif ($renew_command{$cmd}) {
+               # leave it alone
+               push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":''));
+               $this_cmd = '';
+           } elsif (($provide_command{$cmd})&&($within_preamble)) {
+               # leave it alone
+               push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":''));
+               $this_cmd = '';
+           } else {
+               # do the substitution
+               $this_cmd = &substitute_newcmd if ($new_command{$cmd});
+           }
+           if ($this_cmd =~ /(\\(expandafter|noexpand)\s*)?$new_cmd_no_delim_rx\b\s?/)
+               { $after = $this_cmd . $after }
+           elsif ($this_cmd) { push(@pieces, $this_cmd) }
+         }
+         push(@pieces, $after);
+               # after the first segment we should no longer be in the preamble
+               $within_preamble = 0;
+       }
+       print " $replacements new-command replacements\n"
+           if (($VERBOSITY>1) && $replacements);
+       # recombine the processed pieces
+       $_ = join('', @pieces); undef @pieces;
+        print STDOUT ", resulting size: ".length($_)." " if ($VERBOSITY > 1);
+       $_ =~ s/\\\@#\@\@/\\/go;
+    }
+
+    print STDOUT "\n *** substituting metacommands done ***\n" if ($VERBOSITY > 3);
+}
+
+sub insert_command_expansion {
+    ($xafter, $cmd) = @_;
+#   push(@pieces, $_[1]);
+    print ".$cmd";
+    print STDOUT "$_[3]" if ($VERBOSITY > 2);
+#   $xafter = $_[2];
+#   $cmd = $_[3];
+    if ($xafter =~ /no/) { $this_cmd = "\\\@#\@\@".$cmd }
+    elsif (($xafter =~ /after/)&&($after =~ /^\s*\\/)) {
+       local($delayed,$nextcmd) = ($_[3],'');
+
+       $after =~ s/^\s*\\([a-zA-Z]+|.)/$nextcmd = $1;''/eo;
+       ($cmd,$nextcmd) = ($nextcmd, "do_cmd_$nextcmd");
+       if (defined &$nextcmd) { $after = &$nextcmd($after); }
+       elsif ($new_command{$cmd}) { 
+           local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd});
+           &make_unique($body) if ($body =~ /$O/);
+           if ($argn) {
+               do { 
+                   local($before) = '';
+                   $after = join('',&substitute_newcmd, $after);
+                   $after =~ s/\\\@#\@\@/\\/o ;
+               };
+           } else { $after = $body . $after; }
+       } else { print "\nUNKNOWN COMMAND: $cmd "; }
+       $cmd = $delayed;
+       $this_cmd = &substitute_newcmd if ($new_command{$cmd});         
+    } else {
+       $this_cmd = &substitute_newcmd if ($new_command{$cmd});
+    }
+#   if ($this_cmd =~ /(\\(expandafter|noexpand)\s*)?$new_cmd_no_delim_rx\s?/){
+#      $after = $this_cmd . $after
+#   } else { push(@pieces, $this_cmd); }
+    $this_cmd;
+}
+
+
+sub expand_body {
+    return unless length($new_cmd_or_env_rx);
+    local($_) = $body;
+    local($cmd,$saveafter,$avoid_looping);
+    # Uses $before, $body, $arg, etc. of the caller, but not $cmd.
+    # Uses $new_cmd_rx (resp. $new_cmd_no_delim_rx) and $new_env_rx
+    # set in the caller, of which one might be empty.
+
+    # Puts delimiter after the new commands ...
+    &tokenize($new_cmd_rx) if length($new_cmd_rx);
+
+    while (/$new_cmd_or_env_rx/) {
+       # $new_cmd_rx binds $1, and $new_env_rx binds $3.
+       ($before,$cmd,$after,$saveafter) = ($`,$1.$3,$',$');
+       if (length($new_command{$cmd})) { # We have a command
+           # this tokenizes again
+           local($replace) = &substitute_newcmd; # sets $_, changes $after
+           if (!($replace)) {
+               # protect name of unexpanded macro
+               $_ = join('', $before ,"\\@#@@", $cmd, $saveafter );
+           } else {
+               $_ = join('', $before , $replace, $after );
+           }
+       } elsif (length($new_environment{$cmd})) {
+           $_ = join('',$before, &substitute_newenv);
+       }
+       last if $avoid_looping;
+    }
+    # remove protection from unreplaced macro names
+    s/\\\@#\@\@/\\/go;
+
+    # remove trivial comments
+    s/(\\\w+)$comment_mark\d*\n[ \t]*/$1 /go;
+    s/$comment_mark\d*\n[ \t]*//go;
+#    s/($O\d+$C)?($comment_mark\n)[ \t]*/($1 ? $1.$2 : '')/eg;
+
+    $_;
+}
+
+
+sub substitute_newcmd {
+    # Modifies $after in the caller
+    # Get the body from the new_command array
+    local($tmp,$cnt,$saved, $arg, $isword) = ('',0,$cmd);
+    local($argn, $_, $opt) = split(/:!:/, $new_command{$cmd});
+    $avoid_looping = 1 if ($new_command{$cmd} =~ /\\$cmd\b/);
+
+    &tokenize($new_cmd_rx); # must do it again for newly inserted cmd bodies
+    print STDOUT "\nNEW:$cmd:$_" if ($VERBOSITY > 5);
+    foreach $i (1..$argn) {
+       $arg = $isword = '';
+       if ($i == 1 && $opt ne '}') {
+           $arg = ($after =~ s/$optional_arg_rx//o) ? $1 : $opt;
+       }
+       else {
+           # Get the next argument, if not in braces, get next character
+           #RRM: allow also for processed braces, in case substitution
+           #     was delayed; e.g. by \renewcommand
+           if (!(($after =~ s/$next_pair_rx/$arg = $2;''/e)
+                 ||($after =~ s/$next_pair_pr_rx/$arg = $2;''/e))) {
+               $after =~ s/^\s*(\\[a-zA-Z]+|.)/$arg = $1;''/e;
+           }
+           if ($arg eq '#') { 
+               &write_warnings("\nSubstitution of arg to $cmd delayed."); 
+               $_ = "\\\@#\@\@$saved";
+               return ();
+           };
+       }
+       $arg =~ s/(^|\G|[^\\])\\\#/$1$hash_mark/gs;
+       $arg =~ s/\#/$param_mark/gs;
+
+       #RRM: Substitute the arguments in the body one at a time
+       #     else multiple instances would fail in  &make_unique
+
+       # First protect ## parameters in TeX-like substitutions
+       # suggested by Dirk Pleiter (Berlin)
+       s/((^|[^\\])(\\\\)*)\#\#$i/$1$protected_hash/gs;
+       $tmp = $_;
+       $cnt = $tmp =~ s/\#$i//g ;
+       $isword = 1 if ($arg =~ /^\w/);
+       if ($cnt > 1 ) {
+           $tmp = $_;
+           while ($cnt > 1) {
+               if ( s/(\\\w+)?\#$i/(($1&&$isword)? $1.' ': '').$arg/e) { 
+                   &make_unique($_) if ($arg =~ /$O/ ); 
+                   &make_unique_p($_) if ($arg =~ /$OP/ );
+               }
+               $cnt--;
+           }
+           $tmp = $_;
+       }
+#      s/(\\\w+)?\#$i/(($1&&$isword)? $1.' ': '').$arg/e ;
+       s/(\\\w+)?\#$i/$1.(($1&&$isword)? ' ': '').$arg/e ;
+       print "\n *** substitution: $arg \nfor \#$i in \\$cmd did not take ***\n"
+          if (/\#$i/);
+       &write_warnings("incomplete substitution in a \\$cmd command:\n$_") if (/\#$i/);
+       s/$protected_hash/\#$i/g;
+    }
+    s/$param_mark/\#/g;
+    s/$hash_mark/\\\#/g;
+    s/(\\\w+)$/$1 /s;
+
+    # Make the body unique (give unique id's to the brackets),
+    # translate, and return it
+    &make_unique($_);
+    if ($avoid_looping) {
+       s/\\$cmd\b/\\csname $cmd\\endcsname/g;
+       print STDERR "\n *** possible looping with new-command \\$cmd ***\n";
+       &write_warnings("\npossible looping with new-command \\$cmd ");
+    }
+    print STDOUT "\nOUT:$cmd:$_" if ($VERBOSITY > 5);
+
+# Insert a space to prevent letters from clashing together with a
+# letter command. Consider this:
+# New command substitution is restricted to commands introduced by
+# \newcommand etc. (so-called meta commands), but it is not done
+# for already defined commands, eg. \large.
+# But new command, as well as new environment, substitution is done
+# prior to any other substitution.
+# So \newcommand{\this}{...} {\large\this b} will get expanded the
+# following way:
+# 1. \newcommand{\this}{...}
+#    is handled by &substitute_meta_cmds, it gets the definition
+#    of \this and stores it within a table, %new_command.
+#    After all new commands are recognized, &expand_body is called
+#    to expand one command body from each other. That's O(n*n)!
+# 2. A regular expression $new_cmd_rx is built containing a pattern
+#    that matches all occurrences of a properly delimited \this
+#    macro. When matching, ensuing white space gets lost.
+#    (But only for letter commands, see also &make_new_cmd_rx.)
+#    Another regular expression called $new_cmd_no_delim_rx is built
+#    which matches exact the \this, and would also match the prefix
+#    of \thisx.
+# 3. The *whole* text is tokenized using $new_cmd_rx, with separates
+#    \this from the ensuing text by one white space.
+# 4. Then $new_cmd_no_delim_rx together with the delimiting space
+#    is used to substitute \this with its body.
+# 5. The following situations may occur:
+#  a) ... is some text (no macros) => {\large<text>yyy}
+#     Then we must prevent that the text clashes into \large.
+#     This is only dangerous when <text> begins with a letter.
+#  b) ... contains another, not expanded new command.
+#     This happens during &expand_body.
+#     In this case, make sure to &tokenize the body before giving
+#     the result to the caller. Also take care that leading letters
+#     of the body cannot clash into \large.
+#  e) ... contains a macro not known as new command:
+#     Make sure that the macro cannot clash with the ensuing yyy.
+#  f) ... is empty:
+#     Make sure that \large cannot clash with yyy.
+# 6. We prevent clashing by inserting a delimiting blank.
+#    Out of the scetched situation, there are three conditions to
+#    take care of:
+#  a) empty body, left a letter command, right a letter => blank
+#  b) body starts with letter, left a letter command    => blank
+#  c) body ends with letter command, right a letter     => blank
+#  d) else => no blank, clash all together, it will work.
+# 7. With this rules, the expansion should work quite well,
+#    concerning letter/non-letter commands and white space
+#    handling.
+# 8. Deficiencies:
+# 8.1 Consider \this<CR>that. It's handled this way:
+#  a) The \this swallows the <CR> in LaTeX, but what LaTeX2HTML does
+#     is to &tokenize the expression into \this <CR>that.
+#  b) If ... is some text, it results in <text><CR>that.
+#  c) If ... is a macro (or command, or control sequence, these
+#     terms are often mixed up, but effectively mean the same),
+#     then if the macro later takes at least one argument, the <CR>
+#     might get swallowed, this depends on the grace of $next_pair_rx
+#     resp. $next_pair_pr_rx.
+#     If the macro takes no arguments, the <CR> remains in the text.
+#  d) If ... ends in another new command, the problem repeats.
+# 8.2 The new commands are substituted in a very insensitive way.
+#     If \this occurs within an environment which sees \this
+#     totally different, there's no chance to substitute \this in
+#     a different way.
+# 8.3 In relation to 8.2 a similar problem arises when the meta
+#     command, or several meta commands redefining \this, occur
+#     amongst several \this macros.
+# 8.4 In raw TeX like environments it is not possible to revert the
+#     expansion of \this, but \this probably *must* occur in its
+#     raw form.
+
+# Handle the cases as depicted in the description of new command
+# substitution.
+    local($befdel,$aftdel);
+    $befdel = ' '
+       if ($before=~/(^|[^\\])\\[a-zA-Z]+$/ && /^$/ && $after=~/^[a-zA-Z]/) ||
+           ($before=~/(^|[^\\])\\[a-zA-Z]+$/ && /^[a-zA-Z]/);
+    $aftdel = ' '
+       if /(^|[^\\])\\[a-zA-Z]+$/s && $after=~/^[a-zA-Z]/;
+    join('', $befdel, $_, $aftdel);
+}
+
+#RRM:  use this to test whether a specific command is substituting correctly
+sub trace_cmd {
+    local($this) = @_;
+    if ($cmd eq $this) { print "\n$1=>$id:$2::"}
+}
+
+# Make the text unique (give unique id's to the brackets).
+# The text shouldn't contain processed brackets.
+sub make_unique {
+    # MRO: Change to references $_[0]
+    # local(*_) = @_;
+    my $id = $global{'max_id'};
+    # MRO: replaced $* by /m
+    # this looks quite funny but is optimized
+    1 while($_[0] =~ s/$O(\d+)$C([\w\W]*)$O\1$C/$id++;"\000$id $2\000$id "/geom);
+    $_[0] =~ s/\000(\d+) /$O$1$C/gom;
+    $global{'max_id'} = $id;
+}
+
+#RRM: this shouldn't be needed, but just in case...
+sub make_unique_p {
+    # MRO: Change to references $_[0]
+    my $id = $global{'max_id'};
+    # MRO: replaced $* by /m
+    # this looks quite funny but is optimized
+    1 while($_[0] =~ s/$OP(\d+)$CP([\w\W]*)$OP\1$CP/$id++;"\000$id $2\000$id "/geom);
+    $_[0] =~ s/\000(\d+) /$OP$1$CP/gom;
+    $global{'max_id'} = $id;
+}
+
+
+sub substitute_newenv {
+    # Modifies $cmd and $after in the caller
+    # Get the body from the new_environment array
+    local($argn, $begdef, $enddef, $opt) = split(/:!:/, $new_environment{$cmd});
+    local($arg,$new_def_rx,$tmp,$cnt);
+
+    # Note that latex allows argument substitution only in the
+    # \begin part of the new definition
+    foreach $i (1..$argn) {    # Process the arguments
+       if (($i == 1) && ($opt ne '}')) {
+           $after =~ s/$optional_arg_rx/$arg = $1;''/eo;
+           $arg = $opt unless $arg;
+       }
+       else {
+           $after =~ s/$next_pair_rx/$arg = $2;''/eo;
+       }
+       $arg =~ s/(^|[^\\])\\\#/$1$hash_mark/g;
+       $arg =~ s/\#/$param_mark/g;
+
+        #RRM: multiple instances can fail later in  &make_unique
+#       s/\#$i/$arg/g;          # Substitute the arguments in the body
+        #RRM: ...so do one at a time and  &make_unique_p
+        $tmp = $begdef;
+        $cnt = $tmp =~ s/\#$i//g ;
+        if ($cnt > 1) {
+            $tmp = $begdef;
+            while ($cnt > 1) {
+               if ( $begdef =~ s/\#$i/$arg/) { 
+                   &make_unique($begdef) if ($arg =~ /$O/ ); 
+                   &make_unique_p($begdef) if ($arg =~ /$OP/ );
+               }
+                $cnt--;
+            }
+            $tmp = $_;
+        }
+        $begdef =~ s/\#$i/$arg/ ;
+        print "\n *** substitution: $arg \nfor \#$i in {$cmd} did not take ***\n"
+           if ($begdef =~ /\#$i/);
+       &write_warnings("incomplete substitution in a {$cmd} environment:\n$begdef")
+           if ($begdef =~ /\#$i/);
+    }
+    $begdef =~ s/$param_mark/\#/g;
+    $begdef =~ s/$hash_mark/\\\#/g;
+    $begdef =~ s/(\\\w+)$/$1 /s;
+
+    # Make the body unique (Give unique id's to the brackets),
+    # translate, and return it
+#RRM: when are these needed ?
+#    $_ = &revert_to_raw_tex($_);
+#    &pre_process;
+
+    &make_unique($begdef);             # Make bracket IDs unique   
+    print STDOUT "\nBEGIN:$cmd:$begdef" if ($VERBOSITY > 4);
+
+    # Now substitute the \end part:
+#RRM: when are these needed ?
+#    $_ = &revert_to_raw_tex($enddef);
+#    &pre_process;
+
+    &make_unique($enddef);             # Make bracket IDs unique
+    print STDOUT "\nEND:$cmd:$enddef" if (($enddef)&&($VERBOSITY > 4));
+    $enddef =~ s/(\\\w+)$/$1 /s;
+
+    local($new_end_def_rx) = &make_end_env_rx($cmd);
+    if (($enddef)&&!($after =~ s/\n?$new_end_def_rx/$enddef/ )) {
+        $UNFINISHED_ENV = $new_end_def_rx;
+        $REPLACE_END_ENV = $enddef;
+    };
+    join('',$begdef,$after);
+}
+
+sub substitute_pars {
+    s/((\%|$comment_mark\d*)|.)(\r*\n[ \t]*){2,}[ \t]*/$1\n\\par \n/og;
+#    s/((\%|$comment_mark\d*)|\d|.)[\r\n\015]{2,}/print "\nPAR:".$`.$&;"$1\n\\par \n"/egs;
+}
+
+sub do_cmd_end { #RRM:  catches the end of any unclosed environments
+    local($_) = @_;
+    &missing_braces unless (
+       (s/$next_pair_pr_rx//o)||(s/$next_pair_rx//o));
+    s/^\n//;
+    $_;
+}
+
+# Removes the definition from the input string, 
+# adds to the preamble unless it is part of the preamble already
+# and stores the body in %new_command;
+sub get_body_newcommand {
+    local($newed, $n_after) = &process_body_newcommand(0,@_);
+    (($PREAMBLE)? "newed".$newed : '');
+}
+
+sub process_body_newcommand {
+#    local($renewed,*_) = @_;
+    local($renewed,$after_R) = @_;
+    local($_) = $$after_R;
+    local($no_change) = $_;
+    local($argn,$newcmd,$cmd_br,$body,$body_br,$tmp,$tmp1,$opt,$pat);
+    local($new_cmd) = 'command';
+    if ($renewed =~ /provide/||$renewed == 2) {
+       # $newcmd = &missing_braces unless (
+       ($newcmd,$pat) = &get_next(1) unless (
+               (s/$next_pair_pr_rx/$pat=$&;$newcmd=$2;''/e)
+               ||(s/$next_pair_rx/$pat=$&;$newcmd=$2;''/e));
+       if (!$pat) {
+           local($br_id) = ++$global{'max_id'};
+           $pat = "$O$br_id$C".$newcmd."$O$br_id$C";
+       }
+    } else {
+       ($newcmd,$pat) = &get_next(1); # Get command name
+    }
+    $pat =~ s/\\//; $new_cmd .= $pat;
+    $newcmd =~ s/^\s*\\//;
+    ($argn,$pat) = &get_next(0);       # Get optional no. of args
+    $argn = 0 unless $argn; $new_cmd .= $pat if $argn;
+    local($cmd) = $newcmd;
+
+    # Get the body of the code and store it with the name and number of args
+    # UNLESS THE COMMAND IS ALREADY DEFINED
+    # ...in which case $ALLOW_REDEFINE must also have been set.  # RRM
+    # (This is the mechanism with which raw html can be ignored in a Latex document
+    # but be recognised as such by the translator).
+    $opt = '}';                        # Flag for no optional arg
+    local($bodyA) = '';
+    if (/^\[/) {
+       ($opt,$pat) = &get_next(0);
+       $new_cmd .= $pat;
+       $bodyA .= "\n".'($dummy, $pat) = &get_next_optional_argument;' .
+                    "\n". '$args .= $pat;';
+    }
+    local($nargs) = $argn;
+    while ($nargs > 0) { $nargs--;
+       $bodyA .=
+           "\n".'$args .= $`.$& if ((s/$next_pair_pr_rx//o)||(s/$next_pair_rx//o));';
+    }
+    if ($renewed =~ /provide/||$renewed == 2 ) {
+        $body = &missing_braces unless (
+               (s/$next_pair_pr_rx/$pat=$&;$body=$2;''/e)
+               ||(s/$next_pair_rx/$pat=$&;$body=$2;''/e));
+       $new_cmd .= $pat;
+    } else {
+       ($body,$pat) = &get_next(4);  #get the body
+       $new_cmd .= $pat;
+    }
+
+    local($thisone);
+#    $thisone = 1 if ($cmd =~ /div|vec/);  # for debugging
+
+    $tmp = "do_cmd_$cmd";
+    local($wtmp) = "wrap_cmd_$cmd";
+    if ((defined &$tmp)||(defined &$wtmp)){
+       # command already exists, so \providecommand  does nothing
+       # but may still be needed in  images.tex
+       $$after_R = $_;
+       return ($new_cmd) if ($renewed =~ /provide/);
+
+       print "\n*** redefining \\$cmd ***\n";
+       &write_warnings("\nredefining command \\$cmd ");
+       if (!$ALLOW_REDEFINE) {
+           print "*** overriding previous meaning ***\n";
+           &write_warnings("\nprevious meaning of \\$cmd will be lost");
+       }
+#      local($code) = "undef \&$tmp"; eval ($code);
+#      if ($@) {print "\n*** undef \&$cmd failed \n"}
+       if ((!$PREAMBLE)||($renewed>1)) {
+           $new_command{$cmd} = join(':!:',$argn,$body,$opt);
+#          local($code) = "sub $tmp\{\&replace_new_command(\"$cmd\");\}";
+#          eval $code;
+#          print STDERR "\n*** sub do_cmd_$cmd failed:\nPERL: $@\n" if ($@);
+#          &replace_new_command($cmd);
+       }
+
+       $renew_command{$cmd} = 1;
+       &write_mydb("renew_command", $cmd, $renew_command{$cmd});
+        local($padding) = " ";
+        $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/));
+        # Generate a new subroutine
+        local($codeA) = "sub wrap_cmd_$cmd {" . "\n"
+            .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";'
+            . $bodyA
+           . (($thisone)? "\nprint \"\\nwrap $cmd:\".\$args.\"\\n\";" : '')
+            . "\n".'(&make_deferred_wrapper(1).$cmd.'
+            . "\"$padding\"".'.$args.&make_deferred_wrapper(0),$_)}'
+            . "\n";
+        print "\nWRAP_CMD: $codeA " if ($thisone); # for debugging
+        eval $codeA;
+        print STDERR "\n\n*** sub wrap_cmd_$cmd  failed: $@\n" if ($@);
+       $raw_arg_cmds{$cmd} = 1;
+
+    } elsif (($ALLOW_REDEFINE)&&($PREAMBLE < 2)) {
+       print "\n*** redefining \\$cmd ***\n";
+       &write_warnings("\ncommand \\$cmd had no previous definition")
+           if (!($new_command{$cmd}));
+    }
+    if ($renewed && ($PREAMBLE > 1) &&($new_command{$cmd})) {
+       $raw_arg_cmds{$cmd} = 1 ;
+       $renew_command{$cmd} = 1;
+        local($padding) = " ";
+        $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/));
+        # Generate a new subroutine
+        local($codeA) = "sub wrap_cmd_$cmd {" . "\n"
+            .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";'
+            . $bodyA
+           . (($thisone)? "\nprint \"\\nwrap $cmd:\".\$args.\"\\n\";" : '')
+            . "\n".'(&make_deferred_wrapper(1).$cmd.'
+           . "\"$padding\"".'.$args.&make_deferred_wrapper(0),$_)}'
+            . "\n";
+        print "\nWRAP_CMD: $codeA " if ($thisone); # for debugging
+        eval $codeA;
+        print STDERR "\n\n*** sub wrap_cmd_$cmd  failed: $@\n" if ($@);
+
+       &write_mydb("renew_command", $cmd, $renew_command{$cmd});
+    } elsif ($renewed) {
+        $new_command{$cmd} = join(':!:',$argn,$body,$opt);
+    } else {
+       $new_command{$cmd} = join(':!:',$argn,$body,$opt)
+           unless (($PREAMBLE > 1)&&($renew_command{$cmd}));
+    }
+
+    local($this_cmd);
+    $this_cmd = join(''
+       , "command{\\$cmd}"
+       , ($argn ? "[$argn]" :'') 
+       , (($opt =~ /^}$/) ? '' : "[$opt]" )
+       , "{", $body , "}" );
+    $this_cmd = &revert_to_raw_tex($this_cmd);
+    if ($renewed) {
+       if ($renewed=~/provide/){
+           $provide_command{$cmd} = 1;
+           &write_mydb("provide_command", $cmd, $provide_command{$cmd});
+#      } else {
+#          print "\n ** marking $cmd as renewed **";
+#          $renew_command{$cmd} = 1;
+       };
+       if ((!$PREAMBLE)&&($renewed>1)) {
+#          local($this_cmd) = join(''
+#              , "\n\\renewcommand{\\$cmd}"
+#              , ($argn ? "[$argn]" :'') 
+#              , (($opt =~ /^}$/) ? '' : "[$opt]" )
+#              , "{", $body , "}\n" );
+#          $latex_body .= &revert_to_raw_tex($this_cmd);
+           $latex_body .= "\n\\renew". $this_cmd."\n";
+       } else {
+##         &add_to_preamble('command',"\\" . $this_cmd);
+       }
+    } else {
+       &add_to_preamble('command',"\\new" . $this_cmd)
+           unless ($PREAMBLE);
+    }
+    undef $body;
+    if ($renewed == 2) {
+       # there is no output to return
+       $$after_R = $_;
+       return();
+    } 
+
+    if (!$PREAMBLE) {
+       $$after_R = $_;
+       return ($new_cmd) if ($renewed);
+#          $cmd_br =~ s/\\//;
+#      ( join ('', &make_deferred_wrapper(1)
+#          , "\\". ($renewed ? (($renewed =~ /provide/)? 'provid' : 'renew')
+#              : 'new')."edcommand"
+#          , $cmd_br , ($argn ? "[$argn]" :'') 
+#          , ( ($opt =~ /^\}$/ ) ? '' : "[$opt]" ) , $body_br
+#          , &make_deferred_wrapper(0)) , $_ );
+       $new_cmd = join('', "command{\\$cmd}"
+                        , ($argn ? "[$argn]" :'') 
+                        , (($opt =~ /^\}$/) ? '' : "[$opt]" )
+                        , "{", $body , "}" );
+       $new_cmd = &revert_to_raw_tex($new_cmd);
+       &add_to_preamble('command', "\\provide".$new_cmd );
+       $$after_R = $_;
+       return();
+    }
+    $new_cmd =~ s/\\$cmd([\d\W]|$)/$cmd$1/s;
+    $$after_R = $_;
+    $new_cmd;
+}
+
+sub replace_new_command {
+    local($cmd) = @_;
+    local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd});
+    do { ### local($_) = $body;
+        &make_unique($body);
+        } if ($body =~ /$O/);
+    $body =~ s/(^|[^\\])\~/$1\\nobreakspace /g;
+    if ($argn) {
+       do { 
+           local($before) = '';
+           local($after) = "\\$cmd ".$_;
+           $after = &substitute_newcmd;   # may change $after
+           $after =~ s/\\\@#\@\@/\\/o ;
+       };
+    } elsif ($body =~ /\\/) {
+       $body = &translate_commands($body);  # ???
+       $_ = $body . $_;
+    } else { $_ = $body . $_; }
+    $_;
+}
+
+sub get_body_let {
+#    local(*_) = @_;
+    local($_) = @_;
+    local($cmd,$body,$replace,$tmp,$pat);
+    ($cmd,$body) = &get_next_tex_cmd;
+    s/^\s*=?\s*/$body .= $&;''/e;
+    ($replace,$pat) = &get_next_tex_cmd;
+#    return() if ($replace eq $cmd);
+    $body .= $pat;
+    $body = &revert_to_raw_tex($body);
+    &add_to_preamble('', "\\let ".$body );
+    $_[0] = $_;
+    if (($replace eq $cmd)||($cmd="\\")||($cmd =~/(style|size)$/)) {
+       "let ".$body
+    } else {
+       $new_command{$cmd} = join(':!:','',"\\$replace ",'}');
+       '';
+    }
+}
+
+
+#  do not remove the \renewcommand code, since it may be needed
+#  within images. Instead replace it with \renewedcommand;
+#  This will be reverted in &revert_to_raw_tex
+sub get_body_renewcommand {
+    local($ALLOW_REDEFINE) = 1;
+    local($renew, $n_after) = &process_body_newcommand(1,@_);
+    ($renew ? 'renewed' . $renew : '');
+}
+
+sub do_cmd_renewedcommand {
+    local($_) = @_;
+    local($ALLOW_REDEFINE) = 1;
+    &process_body_newcommand(2,\$_);
+    $_ ;
+}
+
+sub get_body_providecommand {
+    local($provide, $n_after) = &process_body_newcommand('provide',@_);
+    (($PREAMBLE && $provide) ? 'provided'.$provide : '');
+}
+
+sub do_cmd_providedcommand{ &do_cmd_renewedcommand(@_) }
+
+sub get_body_DeclareRobustCommand {
+    local($provide, $n_after) = &process_body_newcommand('provide',@_);
+    (($PREAMBLE && $provide) ? 'provided'.$provide : '');
+}
+
+sub get_body_DeclareMathOperator {
+    local($after_R) = @_;
+    local($_) = $$after_R;
+    my $star;
+    s/^\\DeclareMathOperator\s*(\*|star)/$star = $1;''/s;
+    my ($mcmd,$patA) = &get_next(1);
+    my ($mop,$patB) = &get_next(1);
+    if ($star) {
+       $patA .= "${O}0$C\\mathop${O}1$C\\mathrm${patB}${O}1$C${O}0$C".$_;
+    } else {
+       $patA .= "${O}0$C${O}1$C\\mathrm${patB}${O}1$C${O}0$C".$_;
+    }
+    local($provide, $n_after) = &process_body_newcommand('provide',\$patA);
+    $$after_R = $patA;
+    (($PREAMBLE && $provide) ? 'provided'.$provide : '');
+}
+
+sub get_body_DeclareMathOperatorstar {
+    local($after_R) = @_;
+    local($_) = $$after_R;
+    my $star;
+    s/^\\DeclareMathOperator\s*(\*|star)/$star = $1;''/s;
+    my ($mcmd,$patA) = &get_next(1);
+    my ($mop,$patB) = &get_next(1);
+    $patA .= "${O}0$C\\mathop${O}1$C\\mathrm${patB}${O}1$C${O}0$C".$_;
+    local($provide, $n_after) = &process_body_newcommand('provide',\$patA);
+    $$after_R = $patA;
+    (($PREAMBLE && $provide) ? 'provided'.$provide : '');
+}
+
+
+# Removes the definition from the input string, adds to the preamble
+# and stores the body in %new_environment;
+sub get_body_newenvironment {
+    local($newed,$after) = &process_body_newenvironment(0,@_);
+    ( $PREAMBLE ? "newed".$newed : '');
+}
+
+sub process_body_newenvironment {
+#    local($renew,*_) = @_;
+    local($renew,$after_R) = @_;
+    local($_) = $$after_R;
+    local($no_change) = $_;
+    local($argn,$env,$begin,$end,$tmp,$opt,$pat);
+    local($new_env) = 'environment';
+    if ($renew == 2) {
+        $env = &missing_braces unless (
+               (s/$next_pair_pr_rx/$pat=$&;$env=$2;''/e)
+               ||(s/$next_pair_rx/$pat=$&;$env=$2;''/e));
+       $new_env .= $pat;
+    } else {
+       ($env,$pat) = &get_next(1);     # Get the environment name
+       $env =~ s/^\s*\\//; $new_env .= $pat;
+    }
+    ($argn,$pat) = &get_next(0);       # Get optional no. of args
+    $argn = 0 unless $argn; $new_env .= $pat if $argn;
+
+    # Get the body of the code and store it with the name and number of args
+    # UNLESS THE COMMAND IS ALREADY DEFINED (see get_body_newcommand)
+    # ...in which case $ALLOW_REDEFINE must also have been set.  # RRM
+    $opt = '}';                        # Flag for no optional arg
+    if (/^\[/) {
+       ($opt,$pat) = &get_next(0);
+       $new_env .= $pat;
+    }
+    $tmp = "do_env_$env";
+
+    if ($renewed == 2 ) {
+        $begin = &missing_braces unless (
+               (s/$next_pair_pr_rx/$pat=$&;$begin=$2;''/e)
+               ||(s/$next_pair_rx/$pat=$&;$begin=$2;''/e));
+       $new_env .= $pat;
+       $end = &missing_braces unless (
+               (s/$next_pair_pr_rx/$pat=$&;$end=$2;''/e)
+               ||(s/$next_pair_rx/$pat=$&;$end=$2;''/e));
+       $new_env .= $pat;
+    } else {
+       ($begin,$pat) = &get_next(1); $new_env .= $pat;
+       ($end,$pat) = &get_next(1); $new_env .= $pat;
+    }
+    if ((defined &$tmp)&&($ALLOW_REDEFINE)) {
+       print STDOUT "\n*** redefining environment {$env} ***\n";
+       &write_warnings("\nredefined environment {$env} ");
+    }
+    $new_environment{$env} = join(':!:', $argn, $begin, $end, $opt)
+       unless ((defined &$tmp)&&(! $ALLOW_REDEFINE));
+
+    if (!$PREAMBLE) {
+       $new_env = join ('', 
+           , "environment{$env}" 
+           , ($argn ? "[$argn]" : '')
+           , (($opt ne '}')? "[$opt]" : '')
+           , "{$begin}{$end}"
+           );
+       &revert_to_raw_tex($new_env);
+       if ($renew == 2) {
+           $latex_body .= "\n\\".($renew ? 're':'').'new'.$new_env."\n";
+       } else {
+           &add_to_preamble ('environment'
+               , "\\".($renew ? 're':'').'new'.$new_env );
+       }
+       $$after_R = $_;
+       return();
+    }
+    if ($new_env =~ /$sections_rx/) {
+       $new_env = join('', $`,'\csname ',$2,'\endcsname',$3,$');
+    }
+    $new_env =~ s/$par_rx/\\par /g;
+    $$after_R = $_;
+    $new_env;
+}
+
+sub get_body_renewenvironment {
+    local($ALLOW_REDEFINE) = 1;
+    local($renewed, $after) = &process_body_newenvironment(1,@_);
+    'renewed'.$renewed;
+}
+
+sub do_cmd_renewedenvironment {
+    local($ALLOW_REDEFINE) = 1;
+    local($_) = @_;
+    &process_body_newenvironment(2,\$_);
+    $_;
+}
+
+# Instead of substituting as with newcommand and newenvironment,
+# or generating code to handle each new theorem environment,
+# it now does nothing. This forces theorem environments to be passed
+# to latex. Although it would be possible to handle theorem
+# formatting in HTML as it was done previously it is impossible
+# to keep the theorem counters in step with other counters (e.g. equations)
+# to which only latex has access to. Sad...
+sub get_body_newtheorem {
+#    local(*_) = @_;
+    local($after_R) = @_;
+    local($_) = $$after_R;
+    my ($orig, $body) = ($_, '');
+    my ($title, $env, $ctr, $within, $cmd, $tmp, $begin, $end, $pat);
+    my ($new_thm) = 'theorem';
+    # Just chop off the arguments and append to $next_def
+    ($env,$pat) = &get_next(1); $new_thm .= $pat;
+    ($ctr,$pat) = &get_next(0); $new_thm .= $pat;
+    ($title,$pat) = &get_next(1); $new_thm .= $pat;
+    ($within,$pat) = &get_next(0); $new_thm .= $pat;
+
+    #check the style parameters
+    my ($hfont,$bfont,$thm_style);
+    my ($before_thm) = join('',@processed);
+    my ($which,$cmds);
+    while ($before_thm =~ /$theorem_cmd_rx/) {
+       $which = $1;
+       $before_thm = $';
+       $before_thm =~ s/$next_pair_rx/$cmds = $2;''/e;
+       $cmds =~ s/\\/\|/g;  # escape any backslash
+       if ($which =~ /style/) { $thm_style = $cmds }
+       elsif ($which =~ /header/) { $hfont = $cmds }
+       elsif ($which =~ /body/)   { $bfont = $cmds }
+    }
+    $hfont = '['.$hfont.']';
+    $bfont = '['.$bfont.']';
+    $thm_style = '['.$thm_style.']';
+    undef $before_thm;
+
+    if (!($ctr)) {
+       # define the new counter
+       $ctr = $env;
+       do {
+###        local($_) = "\\arabic<<1>>$ctr<<1>>";
+###        $_ = join('',"\\the$within", "." , $_) if ($within);
+           $body = "\\arabic<<1>>$ctr<<1>>";
+           $body = join('',"\\the$within", "." , $body) if ($within);
+           &make_unique($body);
+           $cmd = "the$ctr";
+           $tmp = "do_cmd_$cmd";
+           do {
+                $new_command{$cmd} = join(':!:',0,$body,'}') 
+           } unless (defined &$tmp);
+           &write_mydb("new_command", $cmd, $new_command{$cmd});
+           eval "sub do_cmd_$cmd {\n"
+               . 'local($_,$ot) = @_;'."\n"
+               . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'."\n"
+               . '&translate_commands(' . "\"$body\"" . ");\n}\n";
+           print STDERR "\n*** sub $tmp failed:\n$@\n" if ($@);
+           $raw_arg_cmds{$cmd} = 1;
+           undef $body;
+       };
+       &do_body_newcounter($ctr);
+    } else {
+       do {
+###        local($_) = "\\arabic<<1>>$ctr<<1>>";
+           $body = "\\arabic<<1>>$ctr<<1>>";
+           &make_unique($body);
+           $cmd = "the$env";
+           $tmp = "do_cmd_$cmd";
+           do {
+                $new_command{$cmd} = join(':!:',0,$body,'}') 
+           } unless (defined &$tmp);
+           &write_mydb("new_command", $cmd, $new_command{$cmd});
+           eval "sub do_cmd_$cmd {\n"
+               . 'local($_,$ot) = @_;'
+               . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'
+               . '&translate_commands(' . "\"$body\"" . ");\n}\n";
+           print STDERR "\n*** sub $tmp failed:\n$@\n" if ($@);
+           $raw_arg_cmds{$cmd} = 1;
+           undef $body;
+       };
+    }
+
+    # record the counter dependency
+    &addto_dependents($within,$ctr) if ($within);
+
+    # save the text-label in the %new_theorem hash
+    $new_theorem{$env} = $title;
+
+    # define a new environment
+    my ($id) = ++$global{'max_id'};
+    $begin = "\\begin<<$id>>theorem_type<<$id>>"
+       . "[$env][$ctr][$within]$thm_style$hfont$bfont\n";
+    $id = ++$global{'max_id'};
+    $end = "\\end<<$id>>theorem_type<<$id>>\n";
+    $tmp = "do_env_$env";
+    if ((defined &$tmp)&&($ALLOW_REDEFINE)) {
+       print STDOUT "\n*** redefining theorem environment {$env} ***\n";
+    }
+    $new_environment{$env} = join(':!:', '', $begin, $end, '')
+       unless ((defined &$tmp)&&(! $ALLOW_REDEFINE));
+
+    if (!$PREAMBLE) {
+       my ($new_cmd) = join(''
+           , 'theorem{}' );
+       &add_to_preamble('theorem', "\\new".$new_cmd );
+       $$after_R = $_;
+       return();
+    }
+    $$after_R = $_;
+    'newed'.$new_thm;
+}
+
+sub do_cmd_theoremstyle {
+    local($_) = @_;
+    local($thm_type);
+    $thm_type = &missing_braces unless (
+       (s/$next_pair_pr_rx/$thm_type=$2;''/e)
+       ||(s/$next_pair_rx/$thm_type=$2;''/e));
+#   $THM_STYLE = $thm_type;
+    $_;
+}
+sub do_cmd_theoremheaderfont {
+    local($_) = @_;
+    local($thm_type);
+    $thm_type = &missing_braces unless (
+       (s/$next_pair_pr_rx/$thm_type=$2;''/e)
+       ||(s/$next_pair_rx/$thm_type=$2;''/e));
+#   $THM_HFONT = $thm_type;
+    $_;
+}
+sub do_cmd_theorembodyfont {
+    local($_) = @_;
+    local($thm_type);
+    $thm_type = &missing_braces unless (
+       (s/$next_pair_pr_rx/$thm_type=$2;''/e)
+       ||(s/$next_pair_rx/$thm_type=$2;''/e));
+#   $THM_BFONT = $thm_type;
+    $_;
+}
+
+sub do_env_theorem_type {
+    local($_) = @_;
+    local($dum,$env,$ctr,$within, $label, $name, $title, $text, $index);
+    ($env, $dum) = &get_next_optional_argument;
+    ($ctr, $dum) = &get_next_optional_argument;
+    ($within, $dum) = &get_next_optional_argument;
+
+    local($thm_num, $thm_style);
+    # defaults for plain theorem-style
+    my ($hfont,$bfont) = ('','');
+
+    ($thm_style, $dum) = &get_next_optional_argument;
+    ($hfont, $dum) = &get_next_optional_argument;
+    $hfont =~ s/\|/\\/og;
+    ($bfont, $dum) = &get_next_optional_argument;
+    $bfont =~ s/\|/\\/og;
+
+    # the pre-defined alternative theorem-styles
+    if ($thm_style =~ /definition/) {
+       $bfont = '\normalfont' unless $bfont;
+    } elsif ($thm_style =~ /remark/) {
+       $hfont = '\itshape' unless $hfont;
+       $bfont = '\normalfont' unless $bfont;
+    }
+
+    # defaults for plain theorem-style
+    $hfont = '\bfseries' unless $hfont;
+    $bfont = '\itshape' unless $bfont;
+
+    ($name, $dum) = &get_next_optional_argument;
+    $name = &translate_environments("${O}0$C".$name."${O}0$C") if $name;
+    $name = &translate_commands($name) if ($name =~ /\\/);
+
+    $index = $section_commands{$ctr};
+    if ($index) { 
+       # environment actually starts a new (sub-)section
+       $curr_sec_id[$index]++;
+       local($this) = &translate_commands("\\the$ctr");
+       local($hash) = &sanitize($name." $this");
+       local($section_tag) = join('', @curr_sec_id);
+       $encoded_section_number{$hash} = join($;, $section_tag);
+       &reset_dependents($ctr) if ($dependent{$ctr});
+       $thm_num = &translate_commands("\\the$ctr");
+       $thm_num =~ s/(\w)\.(\.\w)/$1$2/g;
+
+       # construct the sectioning title from the counter values
+       $title = join( '', $new_theorem{$env}, " "
+           , &translate_commands("\\the$ctr") );
+       $toc_section_info{join(' ',@curr_sec_id)} = \
+           "$current_depth$delim$CURRENT_FILE$delim$title"
+               if ($current_depth <= $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH);
+       $section_info{join(' ',@curr_sec_id)} = \
+           "$current_depth$delim$CURRENT_FILE$delim$title$delim";
+       $title = join('',"<A NAME=\"SECTION$section_tag\"><B>"
+                     , $title , "</B></A>" );
+    } else {
+       if ($ctr) {
+           print STDOUT "\nSTP:$ctr:+1" if ($VERBOSITY > 3);
+           $global{$ctr}++;
+           print STDOUT "=".$global{$ctr}." " if ($VERBOSITY > 3);
+           &reset_dependents($ctr) if ($dependent{$ctr});
+           $thm_num = "\\the$ctr ";
+       } else { $thm_num = ''; }
+
+       # construct the full title from the counter values
+       $title = $new_theorem{$env};
+       if (($thm_style =~ /margin/)&&($HTML_VERSION > 2.1)) {
+           # don't use the number yet
+       } elsif ($thm_style =~ /change/) {
+           $title = join(' ', $thm_num, "\\space", $title)
+       } else {
+           $title = join(' ', $title, "\\space", $thm_num);
+       }
+
+       if ($hfont) {
+           $title = join('',$O,++$global{'max_id'},$C,$hfont," "
+                     , $title, $O,++$global{'max_id'},$C);
+           $title = &translate_environments($title);
+           $title = &translate_commands($title);
+       } else {
+           $title = join('',"<B>",&translate_commands($title),"</B>");
+       }
+       $title =~ s/(\w)\.(\.\w)/$1$2/g;
+    }
+    # extract any name or label that may occur at the start
+    s/^\s*(\\label(($O|$OP)\d+($C|$CP))([^<]*)\2)?\s*(\(([^\)]*)\))?/
+       $label=$1; $text=$5; $name=$7 if ($7); ''/eo;
+    if ($label) {
+       $label = &anchor_label($text,$CURRENT_FILE,'');
+       $label =~ s/$anchor_mark/$title/;
+       $title = $label;
+    }
+    if ($name) {
+       $name =~ s/^\s*|\s*$//g; 
+       $name = join('', " (", $name, ") ") if $name;
+    }
+    local($attribs, $border);
+    if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+    elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+
+    $_ = join('', $O,++$global{'max_id'},$C, $bfont
+           , " ", $_ ,$O,++$global{'max_id'},$C) if ($bfont);
+
+    my($cmd) = 'do_thm_'.$env;
+    if (defined &$cmd) {
+       $_ = &$cmd($ctr, $title, $_);
+    } else {
+       $_ = &translate_environments($_);
+       $_ = &translate_commands($_);
+    }
+
+    if ($thm_style =~ /margin/) {
+       local($valign);
+       $valign = ($NETSCAPE_HTML ? ' VALIGN="BASELINE"':'');
+       if ($hfont) {
+           $thm_num = join('',$O,++$global{'max_id'},$C,$hfont," "
+                     , $thm_num, $O,++$global{'max_id'},$C);
+           $thm_num = &translate_environments($thm_num);
+           $thm_num = &translate_commands($thm_num);
+       } else {
+           $thm_num = join('',"<B>",&translate_commands($thm_num),"</B>");
+       }
+       $thm_num =~ s/(\w)\.(\.\w)/$1$2/g;
+
+       # code copied from  &make_table
+       local($Tattribs);
+       if ($attribs) {
+           if (!($attribs =~ /=/)) {
+               $Tattribs = &parse_valuesonly($attribs,"TABLE");
+           } else {
+               $Tattribs = &parse_keyvalues($attribs,"TABLE");
+           }
+           $Tattribs = ' '.$Tattribs if ($Tattribs);
+       }
+       $_ = join ('', "\n<P><DIV$env_id><TABLE"
+               , (($border) ? " BORDER=\"$border\"" : '')
+               , $Tattribs , ">\n<TR VALIGN=\"TOP\">"
+               , "<TD$valign>", &translate_commands($thm_num)
+               , "</TD>\n<TD>", $title, $name
+               , (($thm_style =~ /break/)? "\n<BR>":" \&nbsp; \n")
+               , $_ , "\n</TD></TR></TABLE></DIV>");
+    } else {
+       $_ = join('', "<P><DIV$env_id>"
+               , $title, $name
+               , (($thm_style =~ /break/)? "\n<BR>":" \&nbsp; \n")
+               , $_
+               ,"</DIV><P></P>\n");
+       if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 
+           &make_table( $border, $attribs, '', '', '', $_ ) 
+       } else { $_ }
+    }
+}
+
+# Modifies $_ in the caller and as a side-effect it modifies $next_def
+# which is local to substitute_meta_cmds
+sub get_next {
+    local($what) = @_;
+    local($next, $pat, $tmp);
+    if ($what == 1) {
+       ($next, $tmp, $pat) = &get_next_argument;
+    }
+    elsif ($what == 2) {
+       ($next, $pat) = &get_next_tex_cmd;
+    }
+    elsif ($what == 3) {
+       ($next, $pat) = &get_next_def_arg;
+    }
+    elsif ($what == 4) {
+       ($next, $tmp, $pat) = &get_next_argument;
+    }
+    else {
+       ($next, $pat) =  &get_next_optional_argument;
+    }
+    do {
+       $next_def .= &revert_to_raw_tex($pat) if $pat;
+    } unless ($renewed); # don't add \renewcommand to preamble
+#    $next =~ s/(^\s*)|(\s*$)//g unless ($what == 4); #don't lose white space on body
+    $next =~ s/(^\s*)|(\s*$)//g unless ($what =~ /[14]/); #retain white space in body
+    ($next, $pat);
+}
+
+# The following get_next_<something> ARE ALL DESTRUCTIVE.
+sub get_next_argument {
+    local($next, $br_id, $pat);
+    if (!(s/$next_pair_rx/$br_id=$1;$next=$2;$pat=$&;''/seo)) {
+       print " *** Could not find argument for command \\$cmd ***\n";
+       print "$_\n";
+    };
+    ($next, $br_id, $pat);
+}
+
+sub get_next_pair_or_char_pr {
+    local($next, $br_id, $pat, $epat);
+    if ( /^\{([^\}]*)\}/o && (! $`)) {
+       ($next, $pat) = ($1, $&);
+    } elsif ( (/^\s*([^\s\\<])/o && (! $`))) {
+       ($next, $pat) = ($1, $&);
+    } elsif ( /$next_pair_pr_rx/o && (! $`)) {
+       ($next, $br_id, $pat) = ($2, $1, $&);
+    };
+    $epat = &escape_rx_chars($pat);
+    s/$epat// if $pat;
+    ($next, $br_id, $pat);
+}
+
+sub get_next_optional_argument {
+    local($next, $pat);
+    s/$optional_arg_rx/$next=$1;$pat=$&;''/eo
+       if (/\s*[[]/ && (! $`)); # if the first character is a [
+    #remove trailing spaces and/or comments
+    s/^($comment_mark(\d+\n?)?|$EOL)//gos;
+
+    # if  nested inside {}s  we need to get more tokens  
+    if ($pat) {
+       # check for \item, indicating something has gone wrong
+       if ($pat =~ /\\item\b/ ) {
+           print "\n*** optional argument badly formed:\n" . $pat . "\n\n";
+           $_ = $pat . $_;
+           return('','');
+       }
+       # check for being nested inside {}s
+       local($found) = $pat;
+       while ($found =~ s/$O(\d+)$C[\s\S]*$O\1$C//g) {
+           if ($found =~ /$O(\d+)$C/) {
+               local($br_id) = $1;
+               if (s/$O$br_id$C//) {
+                   $found .= $`.$&;
+                   $pat .= "]".$`.$&;
+                   $next .= "]".$`.$&;
+                   $_ = $';
+                   s/^([^]]*)\]/$next.=$1;$pat.=$&;''/e;
+                   $found .= $&;
+               } else { last } # give up if no closing brace
+           }
+       }
+    } else {
+       s/^\s*\[\]/$pat=$&;''/e; # This is not picked by $optional_arg_rx
+    }
+    ($next, $pat);
+}
+
+#JCL(jcl-del) - use new form of $single_cmd_rx.
+sub get_next_tex_cmd {
+    local($next, $pat);
+    s/^\s*\=?\s*$single_cmd_rx/$4/;
+    ($next, $pat) = ($1.$2,"\\".$1.$2);
+}
+
+sub get_next_def_arg {
+    local($next, $pat);
+
+    # Sets is_simple_def for caller.  Start by turning it off, then
+    # turn it on if we find one of the "simple" patterns.
+
+    # This has got to be hit-or-miss to an extent, given the
+    # thoroughly incestuous relationship between the TeX macroprocessor
+    # ('mouth') and typesetting back-end ('stomach').  Anything which
+    # even does catcode hacking is going to lose BAD.
+
+    s/^\s*//so;                        # Remove whitespace
+
+    $is_simple_def = 0;
+
+    # no arguments
+
+    if (/^$O/ && (! $`)) { $next=0; $pat=''; $is_simple_def=1; }
+
+    # 'simple' arguments
+
+    if (! $is_simple_def && /$tex_def_arg_rx/o && (! $`)) {
+       s/$tex_def_arg_rx/$next=$1; $pat=$&; $is_simple_def=1; $2/seo; }
+
+    # MESSY arguments
+
+    if (! $is_simple_def) {
+       print "Arguments to $cmd are too complex ...\n";
+       print "It will not be processed unless used in another environment\n";
+       print "which is passed to LaTeX whole for processing.\n";
+
+       s/^[^<]*(<[^<]+)*<</$next=''; $pat=$&; $O/seo;
+    }
+
+    $pat =~ s/$O$//so;
+
+    ($next, $pat);
+}
+
+#### Key-value parsing added by RRM
+#
+#   This cleans-up the key-value pairs for a given tag, 
+#   by removing unnecessary spaces and commas, inserting quotes
+#   around the value and puts a preceding space.
+#   The key becomes upper-case, while the value becomes lower-case.
+#   If specific `tags' are provided, then checking is done to verify 
+#   that the keys and values are valid for these tags, eliminating
+#   any that are not; unmatched keys or values are handled as well.
+#   If no tags are provided, then just a list of pairs is returned.
+#
+sub parse_keyvalues {
+    local($_,@tags) = @_;
+    local($key,$KEY,$attribs,$atts,%attributes)=('','','','');
+
+    # beware active " in german
+    local($is_german);
+    if (s/\&#34;/'/g) { 
+       $is_german=1;
+       s/(^|[\s,=])(\&\#\d\d\d;)/$1'$2/g
+    }
+    local($saved) = &revert_to_raw_tex(&translate_commands($_));
+    print "\nATTRIBS: $saved\n" if ($VERBOSITY > 6);
+
+    $saved =~ s/$percent_mark/%/g;
+    $saved =~ s/((^|[\s,=])')\\\W{(\w)}/$1$3/g
+       if $is_german;  #unwanted accents, from active "
+    if (@tags) {
+       foreach $tag (@tags) {
+           $_ = $saved;
+           local($name)= $tag."_attribs";
+           $taglist = $$name;
+           $name .= "_rx_list";
+           $taglist .= $$name;
+           $taglist =~ s/,,/,/;
+#          s/(^|,)\s*([a-zA-Z]+)\s*\=\s*"?([\#\%\w\d]+)"?\s*/$attributes{$2}="$3";''/eg;
+#          s/(^|,)\s*([a-zA-Z]+)\s*\=\s*(\"([^"]*)\"|\'([^\']*)\'|([#%\w\d]*))\s*/
+#          s/(^|,)\s*([a-zA-Z]+)\s*\=\s*(\"([^"]*)\"|\'([^\']*)\'|([#%&@;:+-\/\w\d]*))\s*/
+           s/(^|,)\s*([a-zA-Z]+)\s*\=\s*(\"([^"]*)\"|\'([^\']*)\'|([^<>,=\s]*))\s*/
+               $attributes{$2}=($4?$4:($5?$5:$6));' '/eg;
+           foreach $key (keys %attributes){ 
+               $KEY = $key;
+               $KEY =~ tr/a-z/A-Z/;
+               if ($taglist =~ /,$KEY,/i) {            
+                   local($keyname) = $tag."__".$KEY; 
+                   local($keyvalues) = '';
+                   if ($$keyname) {
+                       $keyvalues = $$keyname;
+                       $atts = $attributes{$key};
+                       if ($keyvalues =~ /\,$atts\,/i ) {
+#                          $atts =~ tr/A-Z/a-z/;
+                           $attribs .= " $KEY=\"$atts\"";
+                           print "\n$KEY=$atts " if ($VERBOSITY > 3);
+                       } else { &invalid_tag($tag,$KEY,$atts); }
+                   } else {    # test for a regular expression
+                       $keyname = $keyname."_rx";
+                       if ($$keyname) {
+                           $keyvalues = $$keyname;
+                           $atts = $attributes{$key};
+                           if ($atts =~ /$keyvalues/) {
+#                              $atts =~ tr/A-Z/a-z/;
+                               $attribs .= " $KEY=\"$atts\"";                          
+                               print "\n$KEY=$atts " if ($VERBOSITY > 3);
+                           } else { &invalid_tag($tag,$KEY,$atts) }
+                       } else {
+                           $atts = $attributes{$key};
+#                          $atts =~ tr/A-Z/a-z/;
+                           $attribs .= " $KEY=\"$atts\"";
+                           print "\n$KEY=$atts " if ($VERBOSITY > 3);
+                       }
+                   }
+               } else {
+                   print "\n$key not in $taglist for $tag" if ($VERBOSITY > 3);
+               }
+           }
+       }
+        s/(^|\s,)\'([^\s,]*)\'(\s|$)/$1$2 /g if $is_german;
+       $attribs .= &parse_valuesonly($_,@tags);
+    } else {
+       # with no tags provided, just list the key-value pairs
+       $_ = $saved;
+       s/\s*(\w+)\s*=\s*\"?(\w+)\"?\s*,?/$attributes{$1}=$2;''/eg;
+       foreach $key (keys %attributes){ 
+           $KEY = $key;
+           $KEY =~ tr/a-z/A-Z/;
+           $atts = $attributes{$key};
+           $atts =~ tr/A-Z/a-z/;
+           $attribs .= " $KEY=\"$atts\"";
+       }
+    }
+    $attribs;
+}
+
+sub invalid_tag {
+    local($tag,$key,$value) = @_;
+    &write_warnings("$key=$value is an invalid value in the <$tag> tag\n");
+}
+
+# RRM
+#   This creates key-value pairs from values only, 
+#   by checking whether the data matches any key to the provided tags.
+#   Only the first match found is retained.
+#   Attributes with no values are also recognised here.
+#
+sub parse_valuesonly {
+    local($values,@tags) = @_;
+    local($i,$tag,$key,$KEY,$attribs,$atts)=(0,'','','','','');
+    local($saved) = &revert_to_raw_tex(&translate_commands($values));
+    $saved =~ s/$percent_mark/%/g;
+    foreach $tag (@tags) {
+       local($name)= $tag."_attribs";
+       $taglist = $$name;
+       $values = $saved;
+        $values =~ s/\s*\"?([^,\s\"]+)\"?\s*,?/$i++;$attributes{$i}=$1;''/eg;
+        local($j) = 0;
+       while ($j < $i) {
+           $j++;
+           $key = $attributes{$j};
+           if ($taglist =~ /,$key,/i) {
+               $KEY = $key;
+               $KEY =~ tr/a-z/A-Z/;
+               $attribs .= " $KEY";
+               print " $KEY" if ($VERBOSITY > 3);
+           } else {
+               $atts = $attributes{$j};
+               $key = &find_attribute($key,$tag);
+               if ($key) {
+                   $KEY = $key;
+                   $KEY =~ tr/a-z/A-Z/;
+                   $atts =~ tr/A-Z/a-z/;
+                   $attribs .= " $KEY=\"$atts\"";
+                   print " $KEY = $atts" if ($VERBOSITY > 3);
+               } else { }
+           }
+       }
+    }
+    $attribs;
+}
+
+# RRM
+#   Extracts key-value pairs using a supplied (comma-separated) list.
+#   When no list is given, it checks for a pre-defined list for the tag.
+#   
+sub extract_attributes {
+    local($tag,$taglist,$_) = @_;
+    local($key,$attribs,$unused,%attributes);
+    if (! ($taglist)) {
+       local($name) = "$tag"."_attribs";
+       if ($$name) { $taglist = $$name }
+    }
+    s/\s*(\w+)\s*=\s*\"?(\w+)\"?\s*,?/$attributes{$1}=$2;''/eg;
+    foreach $key (keys %attributes){ 
+       if ($taglist =~ /\,$key\,/) {
+           $attribs .= " $key=\"$attributes{$key}\"";
+           &write_warnings("valid attribute $key for $tag\n");
+       } else {
+           &write_warnings("unknown attribute $key for $tag\n");
+           $unused .= " $key=\"$attributes{$key}\"";
+       }
+    }
+    ($attribs,$unused);
+}
+
+# RRM
+#   Finds the attribute of a given tag, for which a given value is valid.
+#   Requires variables: <tag>_<key> to be a comma-separated list of keys.
+#   So far it cannot recognise data-types, only names.
+#
+sub find_attribute {
+    local($key,$attrib,$tag) = ('',@_);
+    local($name) = $tag."_attribs";
+    local($attrib_list)=$$name;
+    if ($attrib_list) {
+       $attrib_list =~ s/^\,//o;
+       $attrib_list =~ s/\,$//o;
+       local(@keys) = split(',',$attrib_list);
+       local($attrib_vals) = '';
+       foreach $key (@keys) {
+           $name = $tag."__".$key;
+           $attrib_vals = $$name;
+           return ($key) if ($attrib_vals =~ /\,$attrib\,/i ); 
+       }
+    }
+    $name = $tag."_attribs_rx_list";
+    $attrib_list=$$name;
+    if (!($attrib_list)) { return(); }
+    $attrib_list =~ s/^\,//o;
+    $attrib_list =~ s/\,$//o;
+    @keys = split(',',$attrib_list);
+    foreach $key (@keys) {
+       next if ($attribs =~ / $key=/);
+       $name = $tag."__".$key."_rx";
+       $attrib_vals = $$name;
+       if ( $attrib =~ /^$attrib_vals$/ ) { 
+           return ($key);
+       }
+    }
+    0;
+}
+
+# in case \HTML is defined differently in packages
+sub do_cmd_HTML { &do_cmd_HTMLcode(@_) }
+
+sub do_cmd_HTMLcode {
+    local($_) = @_;
+    local($tag,$attribs,$dum);
+    local($attribs, $dum) = &get_next_optional_argument;
+    $tag = &missing_braces unless (
+       (s/$next_pair_pr_rx/$tag = $2;''/eo)
+       ||(s/$next_pair_rx/$tag = $2;''/eo));
+    $tag = &translate_commands($tag) if ($tag =~ /\\/);
+    if (! $tag) {
+       print "*** no tag given with \\HTML command, ignoring it";
+       return($_);
+    }
+    local($afterHTML) = $_;
+    local($value,$TAGattribs,$etag);
+    if (defined $unclosed_tags_list{$tag}) {
+    } elsif (defined $closed_tags_list{$tag}) {
+       $value = &missing_braces unless (
+           (s/$next_pair_pr_rx/$value = $2;''/eo)
+           ||(s/$next_pair_rx/$value = $2;''/eo));
+       $etag = "</$tag>";
+       $afterHTML = $_;
+    } else {
+       print "\n*** <$tag> is not a valid tag for HTML $HTML_VERSION";
+       print "\n rejecting: \\HTML".(($attribs)? "[$attribs]" : '')."{$tag}";
+       return $_ ;
+    }
+    if ($dum) {
+       $attribs = &translate_commands($attribs) if ($attribs=~/\\/);
+        if ($attribs) {
+            if (!($attribs =~ /=/)) {
+                $TAGattribs = &parse_valuesonly($attribs,$tag);
+            } else {
+                $TAGattribs = &parse_keyvalues($attribs,$tag);
+            }
+        }
+    } else { }  # default if no [...]
+    local($needed) = join(','
+           , $closed_tags_list{$tag},$unclosed_tags_list{$tag});
+    $needed =~ s/,,/,/g; $needed =~ s/^,|,$//g;
+    if ($TAGattribs) {
+       if ($needed) {
+           $needed =~ s/,,/,/g;
+           local($this, @needed);
+           (@needed) = split(',',$needed);
+           foreach $this (@needed) {
+               next unless ($this);
+               next if ($TAGattribs =~ /\b$this\b/);
+               print "\n*** attribute $this required for <$tag> ***";
+               print "\n rejecting: \\HTML".(($attribs)? "[$attribs]" : '')."{$tag}";
+               return($value.$afterHTML);
+           }
+       }
+       $value = &translate_environments($value);
+       $value = &translate_commands($value) if ($value =~ /\\/);
+       $_ = join('', "<$tag", $TAGattribs, ">", $value, $etag);
+   } elsif ($needed) {
+       print STDOUT "\n*** attributes $needed are required for <$tag> ***";
+       return($value.$after);
+    } elsif ($value) {
+       $value = &translate_environments($value);
+       $value = &translate_commands($value) if ($value =~ /\\/);
+       $_ = join('', "<$tag>", $value, $etag);
+    } else {
+       $_ = join('', "<$tag>", $etag);
+    }
+    $_.$afterHTML; 
+}
+
+sub do_cmd_HTMLget {
+    local($_) = @_;
+    local($which,$value,$hash,$dummy);
+    local($hash, $dummy) = &get_next_optional_argument;
+    $which = &missing_braces unless (
+       (s/$next_pair_pr_rx/$which = $2;''/eo)
+       ||(s/$next_pair_rx/$which = $2;''/eo));
+    if ($hash) {
+       local($tmp) = "\%$hash";
+       if (eval "defined \%{$hash}") { $! = '';
+           $value = ${$hash}{'$which'};
+       } else { print "\nhash: \%$hash not defined" }
+    } elsif ($which) {
+       $value = ${$which};
+    }
+    $value.$_;
+}
+
+sub do_cmd_HTMLset {
+    local($_) = @_;
+    local($which,$value,$hash,$dummy);
+    local($hash, $dummy) = &get_next_optional_argument;
+    $which = &missing_braces unless (
+       (s/$next_pair_pr_rx/$which = $2;''/eo)
+       ||(s/$next_pair_rx/$which = $2;''/eo));
+    $value = &missing_braces unless (
+       (s/$next_pair_pr_rx/$value = $2;''/eo)
+       ||(s/$next_pair_rx/$value = $2;''/eo));
+    if ($hash) {
+       local($tmp) = "\%$hash";
+       if (eval "defined \%{$hash}") { $! = '';
+#          eval "\$$hash{'$which'} = \"$value\";";
+           ${$hash}{'$which'} = $value;
+           print "\nHTMLset failed: $! " if ($!);
+       } else { print "\nhash: \%$hash not defined" }
+    } elsif ($which) { $! = '';
+       eval "\${$which} = \"$value\";";
+       print "\nHTMLset failed: $! " if ($!);
+    }
+    $_;
+}
+
+sub do_cmd_HTMLsetenv { &do_cmd_HTMLset(@_) }
+
+####
+
+
+# Appends $next_def to the preamble if it is not already there.
+sub add_to_preamble {
+    local($type, $next_def) = @_;
+    local($name);
+    if ($type =~ /def|include|special|graphicspath/) {
+        local($pat) = &escape_rx_chars ($next_def);
+#      $preamble .= $next_def . "\n" unless ($preamble =~ /$pat/);
+       push(@preamble, $pat); 
+    } 
+    elsif ($type =~ /command|environment|theorem|counter/) {
+       push(@preamble, $next_def ); 
+    }
+    else {
+       ($name) = $next_def =~ /$marker\s*({[^}]+})/; # matches type{name}
+       $name = &escape_rx_chars($name);
+#      $preamble .= $next_def . "\n" unless ($preamble =~ /$marker\s*$name/);
+       push(@preamble, $name ); 
+    }
+}
+
+sub make_latex{
+# This is the environment in which to process constructs that cannot be
+# translated to HTML.
+# The environment tex2html_wrap will be wrapped around any shorthand
+# environments (e.g. $, \(, \[).
+# The tex2html_wrap environment will be treated as an unrecognised
+# evironment by the translator and its contents (i.e. the 'shorthand'
+# environment) will be passed to latex for processing as usual.
+    local($contents) = @_;
+    local($preamble) = $preamble;
+    local($aux_preamble) = $aux_preamble;
+    while ($preamble =~ s/^(\@.*\n)/$prelatex .= $1;''/e) {}
+    print "\nPRE-LATEX: $prelatex" if (($prelatex)&&($VERBOSITY > 1));
+
+    %newed_commands =
+        ( 'newedcommand' , 'newcommand'
+        , 'renewedcommand' , 'renewcommand'
+        , 'providedcommand' , 'providecommand'
+        , 'newedenvironment' , 'newenvironment'
+        , 'newedboolean' , 'newboolean'
+        , 'newedcounter' , 'newcounter'
+        , 'newedtheorem' , 'newtheorem'
+        , 'newedfont' , 'newfont' , 'newedif', 'newif'
+        );
+                    
+
+    # Make the @ character a normal letter ...
+    $preamble =~ s/\\par([^A-Za-z]|$)/\n$1/g;
+    $preamble =~ s/(\\document(class|style)(\[[^\]]+\])?\{\w+\})/$1\n/;
+    $preamble =~ s/(\\document(class|style)(\[[^\]]+\])?\{\w+\})/$1\n\\RequirePackage{ifthen}\n/
+                        unless ($preamble =~/\{ifthen\}/);
+#    $preamble =~ s/(\\document(class|style)(\[[^\]]+\])?\{\w+\})/$1\n\\makeatletter/;
+    # ... and make it special again after the preamble
+    # remove the  \begin/\end  for  tex2html_nowrap and tex2html_deferred environments
+    $preamble =~s/\\(begin|end)\s*\{(tex2html_(nowrap|deferred|nomath|preform)[_a-z]*|imagesonly)\}//g;
+    $preamble =~s/\n?\s?<tex2html_(end)?file>\#[^#]*\#//mg;
+
+    $preamble = "\\documentclass\{article\}%\n\\usepackage{html}\n\\usepackage[dvips]{color}\n"
+       unless ($preamble);
+    if (($LATEX_DUMP)&&(!($preamble =~ /\\usepackage\{ldump\}/))) {
+       # MRO: replaced $* with /m
+       $preamble =~ s/(\\document(class|style)[^\n]*\n)/$1\\usepackage\{ldump\}\n/m;
+    }
+    if ($preamble =~ /pstricks/) {
+       if ($LOAD_LATEX_COLOR) {
+           $LOAD_LATEX_COLOR =~ s/\{color\}/\{pstcol\}/ ;
+       } else {
+           $LOAD_LATEX_COLOR = "\n\\usepackage[dvips]{pstcol}\n";
+       }
+    } else {
+       $LOAD_LATEX_COLOR = "\n\\usepackage[dvips]{color}";
+    }
+    $LATEX_COLOR = "\\pagecolor[gray]{.85}\\nobreak " unless $LATEX_COLOR;
+    if ($preamble =~ /(^|\s*[^%])\s*\\documentstyle/) {
+       # \usepackage is invalid in LaTeX 2.09 and LaTeX-2e compatibility mode
+       $LATEX_COLOR = ''; $LOAD_LATEX_COLOR = '';
+       # ... so is \providecommand 
+       $preamble =~ s/\\documentstyle[^{]*{[^}]*}\n?/
+               $&."\n\\let\\providecommand\\newcommand\n"/eo;
+    }
+
+    $preamble .= $LOAD_LATEX_COLOR."\n" unless ($preamble =~ /[,\{]color[,\}]/);
+    $preamble .= "\n\n".$LATEX_COLOR."\n" unless ($preamble =~ /\\pagecolor/);
+    do {
+       if ($ISOLATIN_CHARS) { $INPUTENC = $INPUTENC || 'latin1' };
+       $preamble .= "\n\\usepackage[".$INPUTENC."]\{inputenc\}\n";
+       } unless ($preamble =~ /\\inputenc/);
+
+    $aux_preamble = '' unless (($aux_preamble)&&($contents =~ /\\(hyper)?(ref|cite)/));
+
+    $preamble =~ s/\\((provide|(re)?new)ed(command|counter|if|theorem|environment|font))\b/
+                        "%\n\\".$newed_commands{$1}/eg;
+    $preamble =~ s/(\\(re)?newcommand)\s*(\{(\\?)(\}|[^\}]+)\})/
+               $1.(($4)? $3 : "{\\".$5.'}' )/eg;
+
+    $preamble =~s/$verbatim_mark(imagesonly)(\d+)#/$verbatim{$2}/eg; # for images.tex only
+
+#    local($key);
+#    foreach $key (keys %newed_commands) {
+#      $preamble .= "\n\\let\\$key\\".$newed_commands{$key}
+#    }
+    $preamble .= "\n";
+
+    local($paperwidth) = '';
+    if ($PAPERSIZE) { $paperwidth = &adjust_textwidth($PAPERSIZE); }
+    else { $paperwidth = &adjust_textwidth("a5"); }
+    local($kern) = ($EXTRA_IMAGE_SCALE ? $EXTRA_IMAGE_SCALE/2 : ".5" );
+    $kern = $kern * $MATH_SCALE_FACTOR;
+    $prelatex . ($DEBUG ? "\\nonstopmode" : "\\batchmode") .
+    "\n$preamble\n\n\\makeatletter\n$aux_preamble\n" .
+    "\\makeatletter\n\\count\@=\\the\\catcode`\\_ \\catcode`\\_=8 \n" .
+    "\\newenvironment{tex2html_wrap}{}{}%\n" .
+    "\\catcode`\\<=12\\catcode`\\_=\\count\@\n" .
+    "\\newcommand{\\providedcommand}[1]{\\expandafter\\providecommand\\csname #1\\endcsname}%\n" .
+    "\\newcommand{\\renewedcommand}[1]{\\expandafter\\providecommand\\csname #1\\endcsname{}%\n" .
+    "  \\expandafter\\renewcommand\\csname #1\\endcsname}%\n" .
+    "\\newcommand{\\newedenvironment}[1]{\\newenvironment{#1}{}{}\\renewenvironment{#1}}%\n" .
+    "\\let\\newedcommand\\renewedcommand\n" .
+    "\\let\\renewedenvironment\\newedenvironment\n" .
+    "\\makeatother\n" .
+    "\\let\\mathon=\$\n\\let\\mathoff=\$\n" .
+    "\\ifx\\AtBeginDocument\\undefined \\newcommand{\\AtBeginDocument}[1]{}\\fi\n" .
+    "\\newbox\\sizebox\n" . "$paperwidth" .
+    "\\newwrite\\lthtmlwrite\n" . "\\makeatletter\n" .
+    "\\let\\realnormalsize=\\normalsize\n\\global\\topskip=2sp\n\\def\\preveqno{}" .
+    "\\let\\real\@float=\\\@float \\let\\realend\@float=\\end\@float\n" .
+    "\\def\\\@float{\\let\\\@savefreelist\\\@freelist\\real\@float}\n" .
+#    "\\def\\\@float{\\\@dbflt}\n" .
+    "\\def\\liih\@math{\\ifmmode\$\\else\\bad\@math\\fi}\n" .
+    "\\def\\end\@float{\\realend\@float\\global\\let\\\@freelist\\\@savefreelist}\n" . 
+    "\\let\\real\@dbflt=\\\@dbflt \\let\\end\@dblfloat=\\end\@float\n" .
+    "\\let\\\@largefloatcheck=\\relax\n" .
+    "\\let\\if\@boxedmulticols=\\iftrue\n" .
+    "\\def\\\@dbflt{\\let\\\@savefreelist\\\@freelist\\real\@dbflt}\n" .
+    "\\def\\adjustnormalsize{\\def\\normalsize{\\mathsurround=0pt \\realnormalsize\n" .
+    " \\parindent=0pt\\abovedisplayskip=0pt\\belowdisplayskip=0pt}%\n" .
+    " \\def\\phantompar{\\csname par\\endcsname}\\normalsize}%\n" .
+    "\\def\\lthtmltypeout#1{{\\let\\protect\\string \\immediate\\write\\lthtmlwrite{#1}}}%\n" .
+    "\\newcommand\\lthtmlhboxmathA{\\adjustnormalsize\\setbox\\sizebox=\\hbox\\bgroup\\kern.05em }%\n" .
+    "\\newcommand\\lthtmlhboxmathB{\\adjustnormalsize\\setbox\\sizebox=\\hbox to\\hsize\\bgroup\\hfill }%\n" .
+    "\\newcommand\\lthtmlvboxmathA{\\adjustnormalsize\\setbox\\sizebox=\\vbox\\bgroup %\n".
+    " \\let\\ifinner=\\iffalse \\let\\)\\liih\@math }%\n" .
+    "\\newcommand\\lthtmlboxmathZ{\\\@next\\next\\\@currlist{}{\\def\\next{\\voidb\@x}}%\n" .
+#    " \\expandafter\\box\\next\\edef\\next{\\egroup\\def\\noexpand\\thiseqn{\\theequation}}\\next}%\n" .
+    " \\expandafter\\box\\next\\egroup}%\n" .
+    "\\newcommand\\lthtmlmathtype[1]{\\gdef\\lthtmlmathenv{#1}}%\n" .
+    "\\newcommand\\lthtmllogmath{\\dimen0\\ht\\sizebox \\advance\\dimen0\\dp\\sizebox\n" .
+    "  \\ifdim\\dimen0>.95\\vsize\n" .  "   \\lthtmltypeout{%\n" .
+    "*** image for \\lthtmlmathenv\\space is too tall at \\the\\dimen0, reducing to .95 vsize ***}%\n" .
+    "   \\ht\\sizebox.95\\vsize \\dp\\sizebox\\z\@ \\fi\n" .  "  \\lthtmltypeout{l2hSize %\n" .
+    ":\\lthtmlmathenv:\\the\\ht\\sizebox::\\the\\dp\\sizebox::\\the\\wd\\sizebox.\\preveqno}}%\n" .
+    "\\newcommand\\lthtmlfigureA[1]{\\let\\\@savefreelist\\\@freelist
+       \\lthtmlmathtype{#1}\\lthtmlvboxmathA}%\n" .
+    "\\newcommand\\lthtmlpictureA{\\bgroup\\catcode`\\_=8 \\lthtmlpictureB}%\n" . 
+    "\\newcommand\\lthtmlpictureB[1]{\\lthtmlmathtype{#1}\\egroup
+       \\let\\\@savefreelist\\\@freelist \\lthtmlhboxmathB}%\n" .
+    "\\newcommand\\lthtmlpictureZ[1]{\\hfill\\lthtmlfigureZ}%\n" .
+    "\\newcommand\\lthtmlfigureZ{\\lthtmlboxmathZ\\lthtmllogmath\\copy\\sizebox
+       \\global\\let\\\@freelist\\\@savefreelist}%\n" .
+    "\\newcommand\\lthtmldisplayA{\\bgroup\\catcode`\\_=8 \\lthtmldisplayAi}%\n" .
+    "\\newcommand\\lthtmldisplayAi[1]{\\lthtmlmathtype{#1}\\egroup\\lthtmlvboxmathA}%\n" .
+    "\\newcommand\\lthtmldisplayB[1]{\\edef\\preveqno{(\\theequation)}%\n" .
+    "  \\lthtmldisplayA{#1}\\let\\\@eqnnum\\relax}%\n" .
+    "\\newcommand\\lthtmldisplayZ{\\lthtmlboxmathZ\\lthtmllogmath\\lthtmlsetmath}%\n" .
+    "\\newcommand\\lthtmlinlinemathA{\\bgroup\\catcode`\\_=8 \\lthtmlinlinemathB}\n" .
+    "\\newcommand\\lthtmlinlinemathB[1]{\\lthtmlmathtype{#1}\\egroup\\lthtmlhboxmathA\n" .
+    "  \\vrule height1.5ex width0pt }%\n" .
+    "\\newcommand\\lthtmlinlineA{\\bgroup\\catcode`\\_=8 \\lthtmlinlineB}%\n" .
+    "\\newcommand\\lthtmlinlineB[1]{\\lthtmlmathtype{#1}\\egroup\\lthtmlhboxmathA}%\n" .
+    "\\newcommand\\lthtmlinlineZ{\\egroup\\expandafter\\ifdim\\dp\\sizebox>0pt %\n" .
+    "  \\expandafter\\centerinlinemath\\fi\\lthtmllogmath\\lthtmlsetinline}\n" .
+    "\\newcommand\\lthtmlinlinemathZ{\\egroup\\expandafter\\ifdim\\dp\\sizebox>0pt %\n" .
+    "  \\expandafter\\centerinlinemath\\fi\\lthtmllogmath\\lthtmlsetmath}\n" .
+    "\\newcommand\\lthtmlindisplaymathZ{\\egroup %\n" .
+    "  \\centerinlinemath\\lthtmllogmath\\lthtmlsetmath}\n" .
+    "\\def\\lthtmlsetinline{\\hbox{\\vrule width.1em \\vtop{\\vbox{%\n" .
+    "  \\kern.1em\\copy\\sizebox}\\ifdim\\dp\\sizebox>0pt\\kern.1em\\else\\kern.3pt\\fi\n" .
+    "  \\ifdim\\hsize>\\wd\\sizebox \\hrule depth1pt\\fi}}}\n" .
+    "\\def\\lthtmlsetmath{\\hbox{\\vrule width.1em\\kern-.05em\\vtop{\\vbox{%\n" .
+    "  \\kern.1em\\kern$kern pt\\hbox{\\hglue.17em\\copy\\sizebox\\hglue$kern pt}}\\kern.3pt%\n" .
+    "  \\ifdim\\dp\\sizebox>0pt\\kern.1em\\fi \\kern$kern pt%\n" .
+    "  \\ifdim\\hsize>\\wd\\sizebox \\hrule depth1pt\\fi}}}\n" .
+    "\\def\\centerinlinemath{%\n" . 
+    "  \\dimen1=\\ifdim\\ht\\sizebox<\\dp\\sizebox \\dp\\sizebox\\else\\ht\\sizebox\\fi\n" .
+    "  \\advance\\dimen1by.5pt \\vrule width0pt height\\dimen1 depth\\dimen1 \n".
+    " \\dp\\sizebox=\\dimen1\\ht\\sizebox=\\dimen1\\relax}\n\n" .
+    "\\def\\lthtmlcheckvsize{\\ifdim\\ht\\sizebox<\\vsize \n" .
+    "  \\ifdim\\wd\\sizebox<\\hsize\\expandafter\\hfill\\fi \\expandafter\\vfill\n" .
+    "  \\else\\expandafter\\vss\\fi}%\n" .
+    "\\providecommand{\\selectlanguage}[1]{}%\n" .
+#    "\\def\\\@enddocumenthook{\\ifnum\\count0>1 \\ifvoid\\\@cclv\\penalty-\\\@MM\\fi\\fi}\n" .
+    "\\makeatletter \\tracingstats = 1 \n"
+    . ($itrans_loaded ? $itrans_tex_mod : '')
+    . $LaTeXmacros . "\n"  # macros defined in extension files
+#    "\\usepackage{lthimages}\n" .
+    . (($LATEX_DUMP)? "\\latexdump\n" : '')
+    . "\n\\begin{document}\n" .
+    "\\pagestyle{empty}\\thispagestyle{empty}\\lthtmltypeout{}%\n" .
+    "\\lthtmltypeout{latex2htmlLength hsize=\\the\\hsize}\\lthtmltypeout{}%\n" .
+    "\\lthtmltypeout{latex2htmlLength vsize=\\the\\vsize}\\lthtmltypeout{}%\n" .
+    "\\lthtmltypeout{latex2htmlLength hoffset=\\the\\hoffset}\\lthtmltypeout{}%\n" .
+    "\\lthtmltypeout{latex2htmlLength voffset=\\the\\voffset}\\lthtmltypeout{}%\n" .
+    "\\lthtmltypeout{latex2htmlLength topmargin=\\the\\topmargin}\\lthtmltypeout{}%\n" .
+    "\\lthtmltypeout{latex2htmlLength topskip=\\the\\topskip}\\lthtmltypeout{}%\n" .
+    "\\lthtmltypeout{latex2htmlLength headheight=\\the\\headheight}\\lthtmltypeout{}%\n" .
+    "\\lthtmltypeout{latex2htmlLength headsep=\\the\\headsep}\\lthtmltypeout{}%\n" .
+    "\\lthtmltypeout{latex2htmlLength parskip=\\the\\parskip}\\lthtmltypeout{}%\n" .
+    "\\lthtmltypeout{latex2htmlLength oddsidemargin=\\the\\oddsidemargin}\\lthtmltypeout{}%\n" .
+    "\\makeatletter\n" .
+    "\\if\@twoside\\lthtmltypeout{latex2htmlLength evensidemargin=\\the\\evensidemargin}%\n" .
+    "\\else\\lthtmltypeout{latex2htmlLength evensidemargin=\\the\\oddsidemargin}\\fi%\n" .
+    "\\lthtmltypeout{}%\n" .
+    "\\makeatother\n\\setcounter{page}{1}\n\\onecolumn\n\n% !!! IMAGES START HERE !!!\n\n"
+    . "$contents\n"
+#    "\\clearpage\n" .
+    . "\\end{document}";
+}
+
+sub adjust_textwidth {
+    local($_) = @_;
+    local($width,$length) = ('','');
+    if (/a4/) {$width = 595; $length= 842; }
+    elsif (/letter/) {$width = 612; $length= 792; }
+    elsif (/legal/) {$width = 612; $length= 1008; }
+    elsif (/note/) {$width = 540; $length= 720; }
+    elsif (/b5/) {$width = 501; $length= 709; }
+    elsif (/a5/) {$width = 421; $length= 595; }
+    elsif (/a6/) {$width = 297; $length= 421; }
+    elsif (/a7/) {$width = 210; $length= 297; }
+    elsif (/a8/) {$width = 148; $length= 210; }
+    elsif (/a9/) {$width = 105; $length= 148; }
+    elsif (/a10/) {$width = 74; $length= 105; }
+    elsif (/b4/) {$width = 709; $length= 1002; }
+    elsif (/a3/) {$width = 842; $length= 1190; }
+    elsif (/b3/) {$width = 1002; $length= 1418; }
+    elsif (/a2/) {$width = 1190; $length= 1684; }
+    elsif (/b2/) {$width = 1418; $length= 2004; }
+    elsif (/a1/) {$width = 1684; $length= 2380; }
+    elsif (/b1/) {$width = 2004; $length= 2836; }
+    elsif (/a0/) {$width = 2380; $length= 3368; }
+    elsif (/b0/) {$width = 2836; $length= 4013; }
+    else {
+       &write_warnings("\nPAPERSIZE: $_ unknown, using LaTeX's size.");
+       return();
+     }
+    if ($width > 500) { $width = $width - 144; $length = $length - 288; }
+    elsif ($width > 250) { $width = $width - 72; $length = $length - 144; }
+    elsif ($width > 125) { $width = $width - 36; $length = $length - 72; }
+#    "\\setlength{\\oddsidemargin}{0pt}\n" .
+#    "\\setlength{\\evensidemargin}{0pt}\n" .
+#    "\\setlength{\\parskip}{0pt}\\setlength{\\topskip}{0pt}\n" .
+    "\\setlength{\\hoffset}{0pt}\\setlength{\\voffset}{0pt}\n" .
+    "\\addtolength{\\textheight}{\\footskip}\\setlength{\\footskip}{0pt}\n" .
+    "\\addtolength{\\textheight}{\\topmargin}\\setlength{\\topmargin}{0pt}\n" .
+    "\\addtolength{\\textheight}{\\headheight}\\setlength{\\headheight}{0pt}\n" .
+    "\\addtolength{\\textheight}{\\headsep}\\setlength{\\headsep}{0pt}\n" .
+    "\\setlength{\\textwidth}{${width}pt}\n"
+    . (($length > 500) ? "\\setlength{\\textheight}{${length}pt}\n" : '')
+}
+
+# Given the depth of the current sectioning declaration and the current
+# section numbers it returns the new section numbers.
+# It increments the $depth-ieth element of the @curr_sec_id list and
+# 0's the elements after the $depth-ieth element.
+sub new_level {
+    local($depth, @curr_sec_id) = @_;
+    $depth = $section_commands{$outermost_level} unless $depth;
+    local($i) = 0;
+    grep( do { if ($i == $depth) {$_++ ;}
+              elsif ($i > $depth) {$_ = 0 ;};
+              $i++;
+              0;
+          },
+        @curr_sec_id);
+    @curr_sec_id;
+}
+
+sub make_head_and_body {
+    local($title,$body,$before_body) = @_;
+    local($DTDcomment) = '';
+    local($version,$isolanguage) = ($HTML_VERSION, 'EN');
+    local(%isolanguages) = (  'english',  'EN'   , 'USenglish', 'EN-US'
+                           , 'original', 'EN'   , 'german'   , 'DE'
+                           , 'austrian', 'DE-AT', 'french'   , 'FR'
+                           , 'spanish',  'ES'
+                           , %isolanguages );
+#    $isolanguage = $isolanguages{$default_language};  # DTD is in EN
+    $isolanguage = 'EN' unless $isolanguage;
+#JCL(jcl-tcl)
+# clean title as necessary
+# the first words ... is a kludge, but reasonable (or not?) 
+#RRM: why bother? --- as long as it is pure text.
+    $title = &purify($title,1);
+    eval("\$title = ". $default_title ) unless ($title);
+#    $title = &get_first_words($title, $WORDS_IN_NAVIGATION_PANEL_TITLES);
+
+    # allow user-modification of the <TITLE> tag; thanks Dan Young
+    if (defined &custom_TITLE_hook) {
+       $title = &custom_TITLE_hook($title, $toc_sec_title);
+    }
+
+    if ($DOCTYPE =~ /\/\/[\w\.]+\s*$/) { # language spec included
+       $DTDcomment = '<!DOCTYPE HTML PUBLIC "'. $DOCTYPE .'"';
+    } else {
+       $DTDcomment = '<!DOCTYPE HTML PUBLIC "'. $DOCTYPE .'//'
+           . ($ISO_LANGUAGE ? $ISO_LANGUAGE : $isolanguage) . '"'
+    }
+    $DTDcomment .= ($PUBLIC_REF ? "\n  \"".$PUBLIC_REF.'"' : '' ) . '>'."\n";
+
+    $STYLESHEET = $FILE.".css" unless defined($STYLESHEET);
+
+    my ($this_charset) = $charset;
+    if ($USE_UTF) { $charset = $utf8_str; $NO_UTF = ''; }
+    if (!$charset && $CHARSET) {
+       $this_charset = $CHARSET;
+       $this_charset =~ s/_/\-/go;
+    }
+    if ($NO_UTF && $charset =~/utf/) {
+       $this_charset = $PREV_CHARSET||$CHARSET; 
+       $this_charset =~ s/_/\-/go;
+    }
+
+    join("\n", (($DOCTYPE)? $DTDcomment : '' )
+       ,"<!--Converted with LaTeX2HTML $TEX2HTMLVERSION"
+       , "original version by:  Nikos Drakos, CBLU, University of Leeds"
+       , "* revised and updated by:  Marcus Hennecke, Ross Moore, Herb Swan"
+       , "* with significant contributions from:"
+       , "  Jens Lippmann, Marek Rouchal, Martin Wilck and others"
+           . " -->\n<HTML>\n<HEAD>\n<TITLE>".$title."</TITLE>"
+       , &meta_information($title)
+       ,  ($CHARSET && $HTML_VERSION ge "2.1" ? 
+             "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=$this_charset\">" 
+             : "" )
+       , $LATEX2HTML_META
+       , ($BASE ? "<BASE HREF=\"$BASE\">" : "" )
+       , $STYLESHEET_CASCADE
+       , ($STYLESHEET ? "<LINK REL=\"STYLESHEET\" HREF=\"$STYLESHEET\">" : '' )
+       , $more_links_mark
+       , "</HEAD>" , ($before_body? $before_body : '')
+       , "<BODY $body>", '');
+}
+
+
+sub style_sheet {
+    local($env,$id,$style);
+    #AXR:  don't overwrite existing .css
+    #MRO: This is supposed to be $FILE.css, no?
+    #RRM: only by default, others can be specified as well, via $EXTERNAL_STYLESHEET
+    #return if (-f $EXTERNAL_STYLESHEET);
+    return if (-r "$FILE.css" && -s _ && !$REFRESH_STYLES );
+
+    unless(open(STYLESHEET, ">$FILE.css")) {
+        print "\nError: Cannot write '$FILE.css': $!\n";
+        return;
+    }
+    if ( -f $EXTERNAL_STYLESHEET ) {
+        if(open(EXT_STYLES, "<$EXTERNAL_STYLESHEET")) {
+            while (<EXT_STYLES>) { print STYLESHEET $_; }
+            close(EXT_STYLES);
+        } else {
+            print "\nError: Cannot read '$EXTERNAL_STYLESHEET': $!\n";
+        }
+    } else {
+       print STYLESHEET <<"EOF"
+/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */
+.MATH    { font-family: \"Century Schoolbook\", serif; }
+.MATH I  { font-family: \"Century Schoolbook\", serif; font-style: italic }
+.BOLDMATH { font-family: \"Century Schoolbook\", serif; font-weight: bold }
+
+/* implement both fixed-size and relative sizes */
+SMALL.XTINY            { font-size : xx-small }
+SMALL.TINY             { font-size : x-small  }
+SMALL.SCRIPTSIZE       { font-size : smaller  }
+SMALL.FOOTNOTESIZE     { font-size : small    }
+SMALL.SMALL            {  }
+BIG.LARGE              {  }
+BIG.XLARGE             { font-size : large    }
+BIG.XXLARGE            { font-size : x-large  }
+BIG.HUGE               { font-size : larger   }
+BIG.XHUGE              { font-size : xx-large }
+
+/* heading styles */
+H1             {  }
+H2             {  }
+H3             {  }
+H4             {  }
+H5             {  }
+
+/* mathematics styles */
+DIV.displaymath                { }     /* math displays */
+TD.eqno                        { }     /* equation-number cells */
+
+
+/* document-specific styles come next */
+EOF
+    }
+    print "\n *** Adding document-specific styles *** ";
+    while (($env,$style) = each %env_style) {
+        if ($env =~ /\./) {
+            $env =~ s/\.$//;
+            print STYLESHEET "$env\t\t{ $style }\n";
+        } elsif ($env =~ /inline|^(text|math)?((tt|rm|sf)(family)?|(up|it|sl|sc)(shape)?|(bf|md)(series)?|normal(font)?)$/) {
+            print STYLESHEET "SPAN.$env\t\t{ $style }\n";
+        } elsif ($env =~ /\./) {
+            print STYLESHEET "$env\t\t{ $style }\n";
+        } elsif ($env =~ /^(preform|\w*[Vv]erbatim(star)?)$/) {
+            print STYLESHEET "PRE.$env\t\t{ $style }\n";
+        } elsif ($env =~ /figure|table|tabular|equation|$array_env_rx/) {
+            print STYLESHEET "TABLE.$env\t\t{ $style }\n";
+        } else {
+            print STYLESHEET "DIV.$env\t\t{ $style }\n";
+        }
+    }
+    while (($env,$style) = each %txt_style) {
+        print STYLESHEET "SPAN.$env\t\t{ $style }\n";
+    }
+    while (($env,$style) = each %img_style) {
+        print STYLESHEET "IMG.$env\t\t{ $style }\n";
+    }
+
+    my ($style);
+    foreach $id (sort(keys  %styleID)) {
+        $style =  $styleID{$id};
+        $style =~ s/font-(color)/$1/;
+        print STYLESHEET "\#$id\t\t{ $style }\n"
+            if ($styleID{$id} ne '');
+    }
+    close(STYLESHEET);
+}
+
+sub clear_styleID {
+    return unless ($USING_STYLES);
+    local($env_id,$id) = ("grp", @_); 
+    undef $styleID{$env_id} if ($id =~ /^\d+$/);
+}
+
+sub make_address { 
+    local($addr) = &make_real_address(@_);
+    $addr .= "\n</BODY>\n</HTML>\n";
+    &lowercase_tags($addr) if $LOWER_CASE_TAGS;
+    $addr;
+}
+
+sub make_real_address {
+    local($addr) = $ADDRESS;
+    if ((defined &custom_address)&&($addr)) {
+       &custom_address($addr)
+    } elsif ($addr) {
+       "<ADDRESS>\n$addr\n</ADDRESS>";
+    } else { '' }
+}
+
+sub purify_caption {
+    local($_) = @_;
+    local($text) = &recover_image_code($_);
+    $text =~ s/\\protect|ALT\=|%EQNO:\d+//g;
+    $text =~ s/[\\\#\'\"\`]//g;
+    $text;
+}
+
+sub recover_image_code {
+    local($key) = @_;
+    local($text) = $img_params{$key};
+    if (!$text) {
+       if ($text = $id_map{$key}) {
+           if ($orig_name_map{$text}) {
+               $text = $img_params{$orig_name_map{$text}}
+           }
+       } elsif ($cached_env_img{$key}) {
+           $text = $img_params{$cached_env_img{$key}};
+       }
+       if ($text =~ /\#*ALT="([^"]+)"(>|#)/s) { $text = $1 }
+    }
+    $text =~ s/\\protect|%EQNO:\d+//g;
+    $text =~ s/&(gt|lt|amp|quot);/&special_html_inv($1)/eg;
+    $text;
+}
+
+sub encode_title {
+    local($_) = @_;
+    $_ = &encode($_);
+    while (/(<[^<>]*>)/o) {s/$1//g}; # Remove HTML tags
+    s/#[^#]*#//g;               # Remove #-delimited markers
+    $_;
+}
+
+# Encodes the contents of enviroments that are passed to latex. The code
+# is then used as key to a hash table pointing to the URL of the resulting
+# picture.
+sub encode {
+    local($_) = @_;
+    # Remove invocation-specific stuff
+    1 while(s/\\(begin|end)\s*(($O|$OP)\d+($C|$CP))?|{?tex2html_(wrap|nowrap|deferred|)(_\w+)?}?(\2)?//go);
+    $_ = &revert_to_raw_tex($_);
+    s/\\protect//g;            # remove redundant \protect macros
+    #$_ = pack("u*", $_);      # uuencode
+    s/\\\$/dollar/g;           # replace funnies, may cause problems in a hash key
+    s/\//slash/g;              # replace funnies, may cause problems in a hash key
+    s/\$|\/|\\//g;             # remove funnies, may cause problems in a hash key
+    s/\s*|\n//g;               # Remove spaces  and newlines
+    s/^(.{80}).*(.{80})$/$1$2/;                # truncate to avoid DBM problems
+    $_;
+}
+
+
+##################### Hypertext Section Links ########################
+sub post_process {
+    # Put hyperlinks between sections, add HTML headers and addresses,
+    # do cross references and citations.
+    # Uses the %section_info array created in sub translate.
+    # Binds the global variables
+    # $PREVIOUS, $PREVIOUS_TITLE
+    # $NEXT, $NEXT_TITLE
+    # $UP, $UP_TITLE
+    # $CONTENTS, $CONTENTS_TITLE 
+    # $INDEX, $INDEX_TITLE
+    # $NEXT_GROUP, $NEXT_GROUP_TITLE
+    # $PREVIOUS_GROUP, $PREVIOUS_GROUP_TITLE
+    # Converting to and from lists and strings is very inefficient.
+    # Maybe proper lists of lists should be used (or wait for Perl5?)
+    # JKR:  Now using top_navigation and bot_navigation instead of navigation
+    local($_, $key, $depth, $file, $title, $header, @link, @old_link,
+         $top_navigation, $bot_navigation, @keys,
+         @tmp_keys, $flag, $child_links, $body, $more_links);
+
+    @tmp_keys = @keys = sort numerically keys %section_info;
+    print "\nDoing section links ...";
+    while (@tmp_keys) {
+       $key = shift @tmp_keys;
+       next if ($MULTIPLE_FILES &&!($key =~ /^$THIS_FILE/));
+       print ".";
+       $more_links = "";
+       ($depth, $file, $title, $body) = split($delim,$section_info{$key});
+       print STDOUT "\n$key $file $title $body" if ($VERBOSITY > 3);
+       next if ($body =~ /external/);
+       $PREVIOUS = $PREVIOUS_TITLE = $NEXT = $NEXT_TITLE = $UP = $UP_TITLE
+           = $CONTENTS = $CONTENTS_TITLE = $INDEX = $INDEX_TITLE
+           = $NEXT_GROUP = $NEXT_GROUP_TITLE
+           = $PREVIOUS_GROUP = $PREVIOUS_GROUP_TITLE
+           = $_ = $top_navigation = $bot_navigation = undef;
+       &add_link_tag('previous',$file);
+       @link =  split(' ',$key);
+        ($PREVIOUS, $PREVIOUS_TITLE) =
+           &add_link($previous_page_visible_mark,$file,@old_link);
+       @old_link = @link;
+       unless ($done{$file}) {
+           ++$link[$depth];
+#          if ($MULTIPLE_FILES && !$depth && $multiple_toc ) {
+#              local($save_depth) = $link[$depth];
+#              $link[$depth] = 1;
+#              ($NEXT_GROUP, $NEXT_GROUP_TITLE) =
+#                  &add_link($next_visible_mark, $file, @link);
+#              &add_link_tag('next', $file, @link);
+#              $link[$depth] = $save_depth;
+#          } else {
+               ($NEXT_GROUP, $NEXT_GROUP_TITLE) =
+                   &add_link($next_visible_mark, $file, @link);
+               &add_link_tag('next', $file, @link);
+#          }
+
+           $link[$depth]--;$link[$depth]--;
+           if ($MULTIPLE_FILES && !$depth ) {
+           } else {
+               ($PREVIOUS_GROUP, $PREVIOUS_GROUP_TITLE) =
+                   &add_link($previous_visible_mark, $file,@link);
+               &add_link_tag('previous', $file,@link);
+           }
+
+           $link[$depth] = 0;
+           ($UP, $UP_TITLE) =
+               &add_link($up_visible_mark, $file, @link);
+           &add_link_tag('up', $file, @link);
+
+           if ($CONTENTS_IN_NAVIGATION) {
+               ($CONTENTS, $CONTENTS_LINK) = 
+                   &add_special_link($contents_visible_mark, $tocfile, $file);
+               &add_link_tag('contents', $file, $delim.$tocfile);
+           }
+
+           if ($INDEX_IN_NAVIGATION) {
+               ($INDEX, $INDEX_LINK) = 
+                   &add_special_link($index_visible_mark, $idxfile, $file);
+               &add_link_tag('index', $file, $delim.$idxfile,);
+           }
+
+           @link = split(' ',$tmp_keys[0]);
+           # the required `next' link may be several sub-sections along
+           local($nextdepth,$nextfile,$nextkey,$nexttitle,$nextbody)=
+               ($depth,$file,$key,'','');
+           $nextkey = shift @tmp_keys;
+           ($nextdepth, $nextfile,$nexttitle,$nextbody) = split($delim,$section_info{$nextkey});
+           if (($nextdepth<$MAX_SPLIT_DEPTH)&&(!($nextbody=~/external/))) {
+               ($NEXT, $NEXT_TITLE) =
+                   &add_link($next_page_visible_mark, $file, @link);
+               &add_link_tag('next', $file, @link);
+           } else {
+               ($NEXT, $NEXT_TITLE) = ('','');
+               $nextfile = $file;
+           }
+           if ((!$NEXT || $NEXT =~ /next_page_inactive_visible_mark/)&&(@tmp_keys)) {
+               # the required `next' link may be several sub-sections along
+               while ((@tmp_keys)&&(($MAX_SPLIT_DEPTH < $nextdepth+1)||($nextfile eq $file))) {
+                   $nextkey = shift @tmp_keys;
+                   ($nextdepth, $nextfile,$nexttitle,$nextbody) = split($delim,$section_info{$nextkey});
+                   if ($nextbody =~ /external/) {
+                       $nextfile = $file;
+                       next;
+                   };
+                   print ",";
+                   print STDOUT "\n $nextkey" if ($VERBOSITY > 3);
+               }
+               @link = split(' ',$nextkey);
+               if (($nextkey)&&($nextdepth<$MAX_SPLIT_DEPTH)) {
+                   ($NEXT, $NEXT_TITLE) =
+                       &add_link($next_page_visible_mark, $file, @link);
+                   &add_link_tag('next', $file, @link);
+               } else {
+                   ($NEXT, $NEXT_TITLE) = ($NEXT_GROUP, $NEXT_GROUP_TITLE);
+                   $NEXT =~ s/next_page_(inactive_)?visible_mark/next_page_$1visible_mark/;
+                   ($PREVIOUS, $PREVIOUS_TITLE) = ($PREVIOUS_GROUP, $PREVIOUS_GROUP_TITLE);
+                   $PREVIOUS =~ s/previous_(inactive_)?visible_mark/previous_page_$1visible_mark/;
+               }
+           }
+           unshift (@tmp_keys,$nextkey) if ($nextkey);
+#
+           $top_navigation = (defined(&top_navigation_panel) ?
+                              &top_navigation_panel : &navigation_panel)
+               unless $NO_NAVIGATION;
+           $bot_navigation = (defined(&bot_navigation_panel) ?
+                              &bot_navigation_panel : &navigation_panel)
+               unless $NO_NAVIGATION;
+           local($end_navigation) = "\n<!--End of Navigation Panel-->\n";
+           if ($USING_STYLES) {
+               $top_navigation = "\n".'<DIV CLASS="navigation">' . $top_navigation
+                       if $top_navigation;
+               $bot_navigation = "\n".'<DIV CLASS="navigation">' . $bot_navigation
+                       if $bot_navigation;
+               $end_navigation = '</DIV>' . $end_navigation;
+               $env_style{'navigation'} = " ";
+           }
+
+           $header = &make_head_and_body($title, $body);
+           $header = join('', $header, $top_navigation, $end_navigation) if ($top_navigation);
+
+           local($this_file) = $file;
+           if ($MULTIPLE_FILES && $ROOTED) {
+               if ($this_file =~ /\Q$dd\E([^$dd$dd]+)$/) { $this_file = $1 }
+           }
+           &slurp_input($this_file);
+           open(OUTFILE, ">$this_file")
+                || die "\nError: Cannot write file '$this_file': $!\n";
+
+           if (($INDEX) && ($SHORT_INDEX) && ($SEGMENT eq 1)) {
+               &make_index_segment($title,$file); }
+
+           local($child_star,$child_links);
+           local($CURRENT_FILE) = $this_file; # ensure $CURRENT_FILE is set correctly
+           if (/$childlinks_on_mark\#(\d)\#/) { $child_star = $1 }
+           $child_links = &add_child_links('',$file, $depth, $child_star,$key, @keys)
+               unless (/$childlinks_null_mark\#(\d)\#/);
+           if (($child_links)&&(!/$childlinks_mark/)&&($MAX_SPLIT_DEPTH > 1)) {
+               if ($depth < $MAX_SPLIT_DEPTH -1) {
+                   $_ = join('', $header, $_, &child_line(), $childlinks_mark, "\#0\#" );
+               } else {
+                   $_ = join('', $header, "\n$childlinks_mark\#0\#", &upper_child_line(), $_ );
+               }
+           } else {
+               $_ = join('', $header, $_ );
+           }
+           $flag = (($BOTTOM_NAVIGATION || &auto_navigation) && $bot_navigation);
+           $_ .= $bot_navigation . $end_navigation if ($flag &&($bot_navigation));
+           $_ .= &child_line() unless $flag;
+           print STDOUT "\n *** replace markers *** " if ($VERBOSITY > 1);
+           &replace_markers;
+           print STDOUT "\n *** post-post-process *** " if ($VERBOSITY > 1);
+           &post_post_process if (defined &post_post_process);
+           &adjust_encoding;
+           print OUTFILE $_;
+           print OUTFILE &make_address;
+           close OUTFILE;
+           $done{$file}++;
+       }
+    }
+    &post_process_footnotes if ($footfile);
+}
+
+sub adjust_encoding {
+    &convert_to_utf8($_) if ($USE_UTF);
+    &lowercase_tags($_) if $LOWER_CASE_TAGS;
+}
+
+sub post_replace_markers {
+    # MRO: replaced $* with /m
+    # clean up starts and ends of  P, BR and DIV tags
+    s/(<\/?(P|BR|DIV)>)\s*(\w)/$1\n$3/gom unless ($file eq $citefile);
+    s/([^\s])(<(BR|DIV))/$1\n$2/gom unless ($file eq $citefile);
+    local($keep,$after);
+
+    # anchor images when otherwise there is an invisible-anchor
+#    s/(<A[^>]*>)\&\#160;<\/A>\s?(<(P|DIV)[^>]*>)\s*(<IMG[^>]*>)\s*(<\/(P|DIV)>)/
+    s/(<A[^>]*>)($anchor_mark|$anchor_invisible_mark)<\/A>\s?(<(P|DIV)[^>]*>)\s*(<IMG[^>]*>)\s*(<\/(P|DIV)>)/
+       do{ $keep="$3$1$5<\/A>";
+           $after = $6;
+           join('',$keep, &after_punct_break($after), $after);
+       } /egom;
+
+    # absorb named anchor (e.g. from index-entry) into preceding or following anchor
+#    s/(<A NAME=\"[^\"]+\")>\&#160;<\/A>\s*\b?<A( HREF=\"[^\"]+\">)/$1$2/gom;
+#    s/(<A HREF=\"[^\"]+\")(>\s*\b?([^<]+|<([^>\/]+|\/[^>A]+)>\s*)*<\/A>)\s*\b?<A( NAME=\"[^\"]+\")>\&#160;<\/A>/$1$5$2/gom;
+
+    # clean up empty table cells
+    s/(<TD[^>]*>)\s*(<\/TD>)/<TD>$2/gom;
+
+    # clean up list items (only desirable in the bibliography ?)
+    # s/\n<P>(<DT[^>]*>)/\n<P><\/P>\n$1/gom;
+
+    # remove blank lines and comment-markers
+#    s/\n\n/\n/g;  # no, cause this kills intended ones in verbatims
+    s/$comment_mark(\d+\n?)?//gm;
+    s/\&quot;/"/gm;  # replace  &quot;  entities
+
+    # italic \LaTeX looks bad
+    s:<(I|EM)>(($Laname|$AmSname)?$TeXname)</\1>:$2:gm;
+}
+
+sub lowercase_tags {
+    # MRO: modified to use $_[0]
+    # local(*stream) = @_;
+    my ($tags,$attribs);
+    $_[0] =~ s!<(/?\w+)( [^>]*)?>!
+       $tags = $1; $attribs = $2;
+       $attribs =~ s/ ([\w\d-]+)(=| |$)/' '.lc($1).$2/eg;
+       join('', '<', lc($tags) , $attribs , '>')!eg;
+}
+
+sub after_punct_break {
+    # MRO: modified to use $_[0]
+    # local(*stream) = @_;
+#    $stream =~ s/^([ \t]*)([,;\.\)\!\"\'\?])[ \t]*(\n)?/(($2)? "$2" : "$1")."\n"/em;
+#    $stream;
+    $_[0] =~ s/^([ \t]*)([,;\.\)\!\"\'\?\>]|\&gt;)[ \t]*(\n)?//em;
+    ($2 ? $2 : $1)."\n";
+}
+
+sub make_index_segment {
+    local($title,$file)= @_ ;
+#JCL(jcl-tcl)
+#    s/<[^>]*>//g;
+#
+    $index_segment{$PREFIX} = "$title";
+    if (!($ref_files{"segment"."$PREFIX"} eq "$file")) {
+       $ref_files{"segment"."$PREFIX"} = "$file";
+       $changed = 1
+    }
+    $SEGMENT = 2;
+}
+
+
+sub add_link {
+    # Returns a pair (iconic link, textual link)
+    local($icon, $current_file, @link) = @_;
+    local($dummy, $file, $title, $lbody) = split($delim,$section_info{join(' ',@link)});
+    if ($lbody =~ /external/) { return ('','') };
+
+#    local($dummy, $file, $title) = split($delim,$toc_section_info{join(' ',@link)});
+
+    if ($MULTIPLE_FILES && $ROOTED && $file) {
+        if (!($DESTDIR =~ /\Q$FIXEDDIR\E[$dd$dd]?$/)) { $file = "..$dd$file" }
+    }
+#    if ($title && ($file ne $current_file || $icon ne $up_visible_mark)) {
+    if ($title && ($file ne $current_file)) {
+       #RRM: allow user-customisation of the link-text; thanks Dan Young
+       if (defined &custom_link_hook ) {
+           $title = &custom_link_hook($title,$toc_section_info{join(' ',@link)});
+       } else {
+            $title = &purify($title);
+           $title = &get_first_words($title, $WORDS_IN_NAVIGATION_PANEL_TITLES);
+       }
+       return ("\n".&make_href($file, $icon), &make_href($file, "$title"))
+    }
+#    elsif ($icon eq $up_visible_mark && $file eq $current_file && $EXTERNAL_UP_LINK) {
+    elsif ($icon eq $up_visible_mark && $EXTERNAL_UP_LINK) {
+       return ("\n".&make_href($EXTERNAL_UP_LINK, $icon),
+               &make_href($EXTERNAL_UP_LINK, "$EXTERNAL_UP_TITLE"))
+    }
+    elsif (($icon eq $previous_visible_mark || $icon eq $previous_page_visible_mark)
+       && $EXTERNAL_PREV_LINK && $EXTERNAL_PREV_TITLE) {
+       return ("\n".&make_href($EXTERNAL_PREV_LINK, $icon),
+               &make_href($EXTERNAL_PREV_LINK, "$EXTERNAL_PREV_TITLE"))
+    }
+    elsif (($icon eq $next_visible_mark ||  $icon eq $next_page_visible_mark)
+       && $EXTERNAL_DOWN_LINK && $EXTERNAL_DOWN_TITLE) {
+       return ("\n".&make_href($EXTERNAL_DOWN_LINK, $icon),
+               &make_href($EXTERNAL_DOWN_LINK, "$EXTERNAL_DOWN_TITLE"))
+    }
+    (&inactive_img($icon), "");
+}
+
+sub add_special_link { &add_real_special_link(@_) }
+sub add_real_special_link {
+    local($icon, $file, $current_file) = @_;
+    local($text);
+    if ($icon eq $contents_visible_mark) { $text = $toc_title }
+    elsif ($icon eq $index_visible_mark) { $text = $idx_title }
+    elsif ($icon eq $biblio_visible_mark) { $text = $bib_title }
+    (($file && ($file ne $current_file)) ? 
+       ("\n" . &make_href($file, $icon), 
+           ($text ? " ". &make_href($file, $text) : undef))
+       : ( undef, undef ))
+}
+
+#RRM: add <LINK ...> tag to the HTML head.
+#     suggested by Marcus Hennecke
+#
+sub add_link_tag {
+    local($rel, $currentfile, @link ) = @_;
+#    local($dummy, $file, $title) = split($delim,$toc_section_info{join(' ',@link)});
+    local($dummy, $file, $title) = split($delim,$section_info{join(' ',@link)});
+    ($dummy, $file, $title) = split($delim,$toc_section_info{join(' ',@link)})
+       unless ($title);
+
+    if ($MULTIPLE_FILES && $ROOTED && $file) {
+        if (!($DESTDIR =~ /\Q$FIXEDDIR\E[$dd$dd]?$/)) { $file = "..$dd$file" }
+    }
+    if ($file && !($file eq $currentfile) && (!$NO_NAVIGATION)) {
+       #RRM: allow user-customisation of the REL attribute
+       if (defined &custom_REL_hook ) {
+           $rel = &custom_REL_hook($rel,$toc_section_info{join(' ',@link)});
+       }
+        $more_links .= "\n<LINK REL=\"$rel\" HREF=\"$file\">";
+    }
+}
+
+sub remove_markers {
+# modifies $_
+    s/$lof_mark//go;
+    s/$lot_mark//go;
+    &remove_bbl_marks;
+    s/$toc_mark//go;
+    s/$idx_mark//go;
+    &remove_cross_ref_marks;
+    &remove_external_ref_marks;
+    &remove_cite_marks;
+    &remove_file_marks;
+# sensitive markers
+    &remove_image_marks;
+    &remove_icon_marks;
+    &remove_verbatim_marks;
+    &remove_verb_marks;
+    &remove_child_marks;
+# uncaught markers
+    s/$percent_mark/%/go;
+    s/$ampersand_mark/\&amp;/go;
+    s/$comment_mark\s*(\d+\n?)?//sgo;
+    s/$caption_mark//go;
+    s/<tex2html[^>]*>//g;
+    s/$OP\d+\$CP//g;
+    $_;
+}
+
+sub replace_markers {
+    &find_quote_ligatures;
+    &replace_general_markers;
+    &text_cleanup;
+    # Must NOT clean the ~'s out of the navigation icons (in panel or text),
+    # and must not interfere with verbatim-like environments
+    &replace_sensitive_markers;
+    &replace_init_file_mark if (/$init_file_mark/);
+    &replace_file_marks;
+    &post_replace_markers;
+}
+
+sub replace_general_markers {
+    if (defined &replace_infopage_hook) {&replace_infopage_hook if (/$info_page_mark/);}
+    else { &replace_infopage if (/$info_page_mark/); }
+    if (defined &add_idx_hook) {&add_idx_hook if (/$idx_mark/);}
+    else {&add_idx if (/$idx_mark/);}
+
+    if ($segment_figure_captions) {
+#      s/$lof_mark/<UL>$segment_figure_captions<\/UL>/o
+#   } else { s/$lof_mark/<UL>$figure_captions<\/UL>/o }
+       s/$lof_mark/$segment_figure_captions/o
+    } else { s/$lof_mark/$figure_captions/o }
+    if ($segment_table_captions) {
+#      s/$lot_mark/<UL>$segment_table_captions<\/UL>/o
+#   } else { s/$lot_mark/<UL>$table_captions<\/UL>/o }
+       s/$lot_mark/$segment_table_captions/o
+    } else { s/$lot_mark/$table_captions/o }
+    &replace_morelinks();
+    if (defined &replace_citations_hook) {&replace_citations_hook if /$bbl_mark/;}
+    else {&replace_bbl_marks if /$bbl_mark/;}
+    if (defined &add_toc_hook) {&add_toc_hook if (/$toc_mark/);}
+    else {&add_toc if (/$toc_mark/);}
+    if (defined &add_childs_hook) {&add_childs_hook if (/$childlinks_on_mark/);}
+    else {&add_childlinks if (/$childlinks_on_mark/);}
+    &remove_child_marks;
+
+    if (defined &replace_cross_references_hook) {&replace_cross_references_hook;}
+    else {&replace_cross_ref_marks if /$cross_ref_mark||$cross_ref_visible_mark/;}
+    if (defined &replace_external_references_hook) {&replace_external_references_hook;}
+    else {&replace_external_ref_marks if /$external_ref_mark/;}
+    if (defined &replace_cite_references_hook) {&replace_cite_references_hook;}
+    else { &replace_cite_marks if /$cite_mark/; }
+    if (defined &replace_user_references) {
+       &replace_user_references if /$user_ref_mark/; }
+}
+
+sub replace_sensitive_markers {
+    if (defined &replace_images_hook) {&replace_images_hook;}
+    else {&replace_image_marks if /$image_mark/;}
+    if (defined &replace_icons_hook) {&replace_icons_hook;}
+    else {&replace_icon_marks if /$icon_mark_rx/;}
+    if (defined &replace_verbatim_hook) {&replace_verbatim_hook;}
+    else {&replace_verbatim_marks if /$verbatim_mark/;}
+    if (defined &replace_verb_hook) {&replace_verb_hook;}
+    else {&replace_verb_marks if /$verb_mark|$verbstar_mark/;}
+    s/;SPMdollar;/\$/g; s/;SPMtilde;/\~/g; s/;SPMpct;/\%/g;
+    s/;SPM/\&/go;
+    s/$percent_mark/%/go;
+    s/$ampersand_mark/\&amp;/go;
+    #JKR: Turn encoded ~ back to normal
+    s/&#126;/~/go;
+}
+
+sub find_quote_ligatures {
+    my $ent;
+
+# guillemets, governed by $NO_FRENCH_QUOTES
+    do {
+       $ent = &iso_map('laquo', "", 1);
+       if ($NO_UTF && !$USE_UTF && $ent=~/\&\#(\d+);/) {
+           $ent='' if ($1 > 255);
+       }
+       s/((\&|;SPM)lt;){2}/$ent/ogs if $ent;
+       $ent = &iso_map('raquo', "", 1) if ($ent);
+       s/((\&|;SPM)gt;){2}/$ent/ogs if $ent;
+       # single guillemot chars cannot be easily implemented this way
+       # finding an approp regexp is work for the future
+    } unless ($NO_FRENCH_QUOTES);
+
+    $ent = &iso_map("gg", "", 1);
+    s/;SPMgg;/($ent ? $ent : '&gt;&gt;')/eg unless ($USE_NAMED_ENTITIES);
+    $ent = &iso_map("ll", "", 1);
+    s/;SPMll;/($ent ? $ent : '&lt;&lt;')/eg unless ($USE_NAMED_ENTITIES);
+
+    my $ldquo, $rdquo;
+# "curly" quotes, governed by  $USE_CURLY_QUOTES.
+    do {
+       $ldquo = &iso_map("ldquo", "", 1);
+       if ($NO_UTF && !$USE_UTF && $ldquo =~ /\&\#(\d+);/) {
+           $ldquo = '' if ($1 > 255);
+       }
+       s/``/$ldquo/ogs if ($ldquo);
+       $rdquo = &iso_map("rdquo", "", 1) if ($ldquo);
+       s/''/$rdquo/ogs if ($rdquo);
+       
+       # single curly quotes cannot be easily implemented this way
+       # finding an approp regexp is work for the future
+    } if ($USE_CURLY_QUOTES);
+
+# "german" quotes, governed by  $NO_GERMAN_QUOTES.
+    do {
+       $ent = &iso_map('bdquo', "", 1);
+       if ($NO_UTF && !$USE_UTF && $ent =~ /\&\#(\d+);/) {
+           $ent = '' if ($1 > 255);
+       }
+       s/,,/$ent/eg if $ent;
+
+       # closing upper quotes are not properly displayed in browsers
+       s/($ent[\w\s\&\#;']+)$ldquo/$1``/og
+               if ($USE_CURLY_QUOTES && $ldquo && $ent);
+    } unless ($NO_GERMAN_QUOTES);
+}
+
+sub add_childlinks {
+    local($before, $after, $star);
+    while (/$childlinks_on_mark\#(\d)\#/) {
+       $star = $1;
+       $before = $`;
+       $after = $';
+       $before =~ s/\n\s*$//;
+       $_ = join('', $before, "\n", $child_links, $after);
+    }
+}
+
+sub replace_infopage {
+    local($INFO)=1 if !(defined $INFO);
+    if ($INFO == 1) {
+       local($title);
+       if ((defined &do_cmd_infopagename)||$new_command{'infopagename'}) {
+           local($br_id)=++$global{'max_id'};
+           $title = &translate_environments("$O$br_id$C\\infopagename$O$br_id$C");
+       } else { $title = $info_title }
+           if ($MAX_SPLIT_DEPTH <= $section_commands{$outermost_level}) {
+               $_ =~ s/(<HR[^>]*>\s*)?$info_title_mark/
+                   ($1? $1 : "\n<HR>")."\n<H2>$title<\/H2>"/eog;
+           } else {
+               $_ =~ s/$info_title_mark/"\n<H2>$title<\/H2>"/eog;
+           }
+    }
+    while (/$info_page_mark/o) {
+       $_ = join('', $`, &do_cmd_textohtmlinfopage, $');
+    }
+}
+
+sub replace_init_file_mark {
+    local($init_file, $init_contents, $info_line)=($INIT_FILE,'','');
+    if (-f $init_file) {
+    } elsif (-f "$orig_cwd$dd$init_file") {
+       $init_file = $orig_cwd.$dd.$init_file;
+    } else {
+       s/$init_file_mark//g;
+       return();
+    }
+    if(open(INIT, "<$init_file")) {
+        foreach $info_line (<INIT>) {
+           $info_line =~ s/[<>"&]/'&'.$html_special_entities{$&}.';'/eg;
+           $init_contents .= $info_line;
+       }
+        close INIT;
+    } else {
+        print "\nError: Cannot read '$init_file': $!\n";
+    }
+    s/$init_file_mark/\n<BLOCKQUOTE><PRE>\n$init_contents\n<\/PRE><\/BLOCKQUOTE>\n/g;
+}
+
+sub replace_morelinks {
+    $_ =~ s/$more_links_mark/$more_links/e;
+}
+
+# This code is extremely inefficient. At least the subtrees should be
+# filtered according to $MAX_LINK_DEPTH before going into the
+# inner loops.
+# RRM: revamped parts, for $TOC_STARS, fixing some errors.
+#
+sub add_child_links { &add_real_child_links(@_) }
+sub add_real_child_links {
+    local($exclude, $base_file, $depth, $star, $current_key, @keys) = @_;
+    local $min_depth = $section_commands{$outermost_level} - 1;
+    return ('') if ((!$exclude)&&(!$LEAF_LINKS)&&($depth >= $MAX_SPLIT_DEPTH));
+    if ((!$depth)&&($outermost_level)) { $depth = $min_depth }
+
+    local($_, $child_rx, @subtree, $next, %open, @roottree);
+    local($first, $what, $pre, $change_key, $list_class);
+    $childlinks_start = "<!--Table of Child-Links-->";
+    $childlinks_end = "<!--End of Table of Child-Links-->\n";
+    $child_rx = $current_key;
+    $child_rx =~ s/( 0)*$//;   # Remove trailing 0's
+    if ((!$exclude)&&($depth < $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH -1 )
+#          &&($depth >= $MAX_SPLIT_DEPTH-1)) {
+           &&($depth > $min_depth)) {
+       if ((defined &do_cmd_childlinksname)||$new_command{'childlinksname'}) {
+           local($br_id)=++$global{'max_id'};
+           $what = &translate_environments("$O$br_id$C\\childlinksname$O$br_id$C");
+       } else {
+           $what = "<strong>$child_name</strong>";
+       }
+       $list_class = ' CLASS="ChildLinks"' if ($USING_STYLES);
+       $first = "$childlinks_start\n<A NAME=\"CHILD_LINKS\">$what<\/A>\n";
+    } elsif ($exclude) {
+       # remove any surrounding braces
+       $exclude =~ s/^($O|$OP)\d+($C|$CP)|($O|$OP)\d+($C|$CP)$//g;
+       # Table-of-Contents
+       $list_class = ' CLASS="TofC"' if ($USING_STYLES);
+       $childlinks_start = "\n<!--Table of Contents-->\n";
+       $childlinks_end = "<!--End of Table of Contents-->";
+       $first = "$childlinks_start";
+    } else {
+       $list_class = ' CLASS="ChildLinks"' if ($USING_STYLES);
+       $first = "$childlinks_start\n"
+           . ($star ? '':"<A NAME=\"CHILD_LINKS\">$anchor_mark<\/A>\n");
+    }
+    my $startlist, $endlist;
+    $startlist = "<UL$list_class>" unless $CHILD_NOLIST;
+    $endlist = '</UL>' unless $CHILD_NOLIST;
+    my $alt_item = '<BR>&nbsp;<BR>'."\n";
+    my $outer_item = ($CHILD_NOLIST ? $alt_item : '<LI>');
+    my $inner_item = '<LI>';
+    my $inner_end = '</UL><BR>';
+
+    # collect the relevant keys...
+    foreach $next (@keys) {
+       if ($MULTIPLE_FILES && $exclude) {
+           # ...all but with this document as the root
+           if ($next =~ /^$THIS_FILE /) {
+#              # make current document the root
+#              $change_key = '0 '.$';
+               push(@roottree,$next);
+               print "\n$next : m-root" if ($VERBOSITY > 3);
+           } else {
+               push(@subtree,$next);
+               print "\n$next : m-sub" if ($VERBOSITY > 3);
+           }
+       } elsif (($next =~ /^$child_rx /)&&($next ne $current_key)) {
+       # ...which start as $current_key
+           push(@subtree,$next);
+           print "\n$next : sub $child_rx" if ($VERBOSITY > 3);
+       } else {
+           print "\n$next : out $current_key" if ($VERBOSITY > 3);
+       }
+    }
+    if (@subtree) { @subtree = sort numerically @subtree; }
+    if (@roottree) {
+       @roottree = sort numerically @roottree;
+       @subtree = ( @roottree, @subtree );
+    }
+    # @subtree now contains the subtree rooted at the current node
+
+    local($countUL); #counter to ensure correct tag matching
+    my $root_file, $href;
+    if (@subtree) {
+       local($next_depth, $file, $title, $sec_title, $star, $ldepth,$this_file, $prev_file);
+       $ldepth = $depth;
+       $prev_file = $base_file;
+#      @subtree = sort numerically @subtree;
+       foreach $next (@subtree) {
+           $title = '';
+           if ($exclude) {
+               # making TOC
+               ($next_depth, $file, $sec_title) =
+                       split($delim,$section_info{$next});
+               ($next_depth, $file, $title, $star) =
+                       split($delim,$toc_section_info{$next});
+               # use the %section_info  title, in case there are images
+               $title = $sec_title if ($sec_title =~ /image_mark>\#/);
+           } else {
+               # making mini-TOC i.e. the child-links tables
+               $star = '';
+               ($next_depth, $file, $title) =
+                       split($delim,$section_info{$next});
+           }
+           $root_file = $file unless $root_file;
+           if ($root_file && $root_file =~ /_mn\./) { $root_file=$` };
+           # remove any surrounding braces
+           $title =~ s/^($O|$OP)\d+($C|$CP)|($O|$OP)\d+($C|$CP)$//g;
+           next if ($exclude && $title =~ /^$exclude$/);
+           if (!$title) {
+               ($next_depth, $file, $title, $star) =
+                       split($delim,$toc_section_info{$next});
+           }
+           $this_file = $file;
+           $title = "\n".$title if !($title =~/^\n/);
+           next if ( $exclude &&(                              # doing Table-of-Contents
+               ( $TOC_DEPTH &&($next_depth > $TOC_DEPTH))      # and  too deep
+               ||($star && !$TOC_STARS ) ));                   # or no starred sections 
+           $file = "" if (!$MAX_SPLIT_DEPTH); # Martin Wilck
+           next if ($exclude && !$MULTIPLE_FILES &&($title =~ /^\s*$exclude\s*$/));
+           next if (!$exclude && $next_depth > $MAX_LINK_DEPTH + $depth);
+           print "\n$next :" if ($VERBOSITY > 3);
+           if ($this_file =~ /^(\Q$prev_file\E|\Q$base_file\E)$/) {
+               $file .= join('', "#SECTION", split(' ', $next));
+           } else { $prev_file = $file }
+
+           if (!$next_depth && $MULTIPLE_FILES) { ++$next_depth }
+           local($num_open) = (split('/',%open))[0];
+           if ((($next_depth > $ldepth)||$first)
+               && ((split('/',%open))[0] < $MAX_LINK_DEPTH + $depth )
+               ) {
+               # start a new <UL> list
+               if ($first) {
+                   $_ = "$first\n$startlist\n"; $countUL++;
+                   local $i = 1;
+                   while ($i <= $ldepth) {
+                       $open{$i}=0; $i++
+                   }
+                   $first = '';        # include NAME tag first time only
+                   while ($i < $next_depth) {
+                       $open{$i}=1; $i++; 
+                       $_ .= ($countUL >1 ? $inner_item : $outer_item)."<UL>\n";
+                       $countUL++;
+                   }
+               } else {
+                   $_ .= "<UL>\n"; $countUL++;
+               }
+               $ldepth = $next_depth;
+               $open{$ldepth}++; 
+               # append item to this list
+               print " yes " if ($VERBOSITY > 3);
+               if (defined &add_frame_child_links) {
+                   $href = &make_href($file,$title);
+                   if ($href =~ s/($root_file)_mn/$1_ct/) {
+                       $href =~ s/(target=")main(")/$1contents$2/i;
+                   };
+                   $_ .= ($countUL >1 ? $inner_item : $outer_item)
+                       . $href . "\n";
+               } else {
+                   $_ .= ($countUL >1 ? $inner_item : $outer_item)
+                       . &make_href($file,$title) . "\n";
+               }
+           }
+           elsif (($next_depth)&&($next_depth <= $ldepth)
+               &&((split('/',%open))[0] <= $MAX_LINK_DEPTH + $depth )
+               ) {
+               # append item to existing <UL> list
+               while (($next_depth < $ldepth) && %open ) {
+               # ...closing-off any nested <UL> lists
+                   if ($open{$ldepth}) {
+                       if (!(defined $open{$next_depth}))  {
+                           $open{$next_depth}++;
+                       } else {
+                           $_ .= ($countUL==2 ? $inner_end : '</UL>')."\n";
+                           $countUL--;
+                       }
+                       delete $open{$ldepth};
+                   };
+                   $ldepth--;
+               }
+               $ldepth = $next_depth;
+               print " yes" if ($VERBOSITY > 3);
+               if (defined &add_frame_child_links) {
+                   $href = &make_href($file,$title);
+                   if ($href =~ s/($root_file)_mn/$1_ct/) {
+                       $href =~ s/(target=")main(")/$1contents$2/i;
+                   };
+                   $_ .= ($countUL >1 ? $inner_item : $outer_item)
+                       . $href . "\n";
+               } else {
+                   $_ .= ($countUL >1 ? $inner_item : $outer_item)
+                       . &make_href($file,$title) . "\n";
+               }
+           } else {
+               # ignore items that are deeper than $MAX_LINK_DEPTH
+               print " no" if ($VERBOSITY > 3);
+           }
+       }
+
+       if (%open) {
+       # close-off any remaining <UL> lists
+           $countUL-- if $CHILD_NOLIST;
+           local $cnt = (split('/',%open))[0];
+           local $i = $cnt;
+               while ($i > $depth) { 
+                   if ($open{$i}) {
+                       $_ .= '</UL>' if $countUL;
+                       $countUL--;
+                       delete $open{$i};
+                   }
+               $i--;
+           }
+       }
+    }
+    # just in case the count is wrong
+    $countUL-- if ($CHILD_NOLIST && $countUL > 0);
+    $countUL = '' if ($countUL < 0);
+    while ($countUL) { $_ .= '</UL>'; $countUL-- }
+    ($_ ? join('', $_, "\n$childlinks_end") : '');
+}
+
+sub child_line {($CHILDLINE) ? "$CHILDLINE" : "<BR>\n<HR>";}
+sub upper_child_line { "<HR>\n"; }
+
+sub adjust_root_keys {
+    return() unless ($MULTIPLE_FILES && $ROOTED);
+    local($next,$change_key,$current_rx);
+    local(@keys) = (keys %toc_section_info);
+    
+    local($current_key) = join(' ',@curr_sec_id);
+    $current_key =~ /^(\d+ )/;
+    $current_rx = $1;
+    return() unless $current_rx;
+
+    # alter the keys which start as $current_key
+    foreach $next (@keys) {
+       if ($next =~ /^$current_rx/) {
+           # make current document the root
+           $change_key = '0 '.$';
+           $toc_section_info{$change_key} = $toc_section_info{$next};
+           $section_info{$change_key} = $section_info{$next};
+#          if (!($next eq $current_key)) {
+#              $toc_section_info{$next} = $section_info{$next} = '';
+#          }
+       }
+    }
+}
+
+sub top_page {
+    local($file, @navigation_panel) = @_;
+    # It is the top page if there is a link to itself
+    join('', @navigation_panel) =~ /$file/;
+}
+
+# Sets global variable $AUX_FILE
+sub process_aux_file {
+    local(@exts) = ('aux');
+    push(@exts, 'lof') if (/\\listoffigures/s);
+    push(@exts, 'lot') if (/\\listoftables/s);
+    local($_, $status);                # To protect caller from &process_ext_file
+    $AUX_FILE = 1;
+    foreach $auxfile (@exts) {
+       $status = &process_ext_file($auxfile);
+       if ($auxfile eq "aux" && ! $status) {
+           print "\nCannot open $FILE.aux $!\n";
+           &write_warnings("\nThe $FILE.aux file was not found," .
+                           " so sections will not be numbered \nand cross-references "
+                           . "will be shown as icons.\n");
+       }
+    }
+    $AUX_FILE = 0;
+}
+
+sub do_cmd_htmlurl {
+    local($_) = @_;
+    local($url);
+    $url = &missing_braces unless (
+       (s/$next_pair_pr_rx/$br_id=$1;$url=$2;''/e)
+       ||(s/$next_pair_rx/$br_id=$1;$url=$2;''/e));
+    $url =~ s/\\(html)?url\s*($O|$OP)([^<]*)\2/$3/;
+    $url =~ s/\\?~/;SPMtilde;/og;
+    join('','<TT>', &make_href($url,$url), '</TT>', $_);
+}
+sub do_cmd_url { &do_cmd_htmlurl(@_) }
+
+sub make_href { &make_real_href(@_) }
+sub make_real_href {
+    local($link, $text) = @_;
+    $href_name++;
+    my $htarget = '';
+    $htarget = ' target="'.$target.'"'
+       if (($target)&&($HTML_VERSION > 3.2));
+    #HWS: Nested anchors not allowed.
+    $text =~ s/<A .*><\/A>//go;
+    #JKR: ~ is handled different - &#126; is turned to ~ later.
+    #$link =~ s/&#126;/$percent_mark . "7E"/geo;
+    if ($text eq $link) { $text =~ s/~/&#126;/g; }
+    $link =~ s/~/&#126;/g;
+    # catch \url or \htmlurl
+    $link =~ s/\\(html)?url\s*(($O|$OP)\d+($C|$CP))([^<]*)\2/$5/;
+    $link =~ s:(<TT>)?<A [^>]*>([^<]*)</A>(</TT>)?(([^<]*)|$):$2$4:;
+    # this should not be here; else TOC, List of Figs, etc. fail:
+    # $link =~ s/^\Q$CURRENT_FILE\E(\#)/$1/ unless ($SEGMENT||$SEGMENTED);
+    $text = &simplify($text);
+    "<A NAME=\"tex2html$href_name\"$htarget\n  HREF=\"$link\">$text</A>";
+}
+
+sub make_href_noexpand { # clean
+    my ($link, $name, $text) = @_;
+    do {$name = "tex2html". $href_name++} unless $name;
+    #HWS: Nested anchors not allowed.
+    $text =~ s/<A .*><\/A>//go;
+    #JKR: ~ is handled different - &#126; is turned to ~ later.
+    #$link =~ s/&#126;/$percent_mark . "7E"/geo;
+    if ($text eq $link) { $text =~ s/~/&#126;/g; }
+    $link =~ s/~/&#126;/g;
+    # catch \url or \htmlurl
+    $link =~ s/\\(html)?url\s*(($O|$OP)\d+($C|$CP))([^<]*)\2/$5/;
+    $link =~ s:(<TT>)?<A [^>]*>([^<]*)</A>(</TT>)?(([^<]*)|$):$2$4:;
+    "<A NAME=\"$name\"\n HREF=\"$link\">$text</A>";
+}
+
+sub make_named_href {
+    local($name, $link, $text) = @_;
+    $text =~ s/<A .*><\/A>//go;
+    $text = &simplify($text);
+    if ($text eq $link) { $text =~ s/~/&#126;/g; }
+    $link =~ s/~/&#126;/g;
+    # catch \url or \htmlurl
+    $link =~ s/\\(html)?url\s*(($O|$OP)\d+($C|$CP))([^<]*)\2/$5/;
+    $link =~ s:(<TT>)?<A [^>]*>([^<]*)</A>(</TT>)?(([^<]*)|$):$2$4:;
+    if (!($name)) {"<A\n HREF=\"$link\">$text</A>";}
+    elsif ($text =~ /^\w/) {"<A NAME=\"$name\"\n HREF=\"$link\">$text</A>";}
+    else {"<A NAME=\"$name\"\n HREF=\"$link\">$text</A>";}
+}
+
+sub make_section_heading {
+    local($text, $level, $anchors) = @_;
+    local($elevel) = $level; $elevel =~ s/^(\w+)\s.*$/$1/;
+    local($section_tag) = join('', @curr_sec_id);
+    local($align,$pre_anchors);
+
+    # separate any invisible anchors or alignment, if this has not already been done
+    if (!($anchors)){ ($anchors,$text) = &extract_anchors($text) }
+    else { 
+       $anchors =~ s/(ALIGN=\"\w*\")/$align = " $1";''/e;
+       $align = '' if ($HTML_VERSION < 2.2);
+       $anchors = &translate_commands($anchors) if ($anchors =~ /\\/);
+    }
+
+    # strip off remains of bracketings
+    $text =~ s/$OP\d+$CP//g;
+    if (!($text)) {
+       # anchor to a single `.' only
+       $text = "<A NAME=\"SECTION$section_tag\">.</A>$anchors\n";
+    } elsif ($anchors) {
+#      # put anchors immediately after, except if title is too long
+#      if ((length($text)<60 )&&(!($align)||($align =~/left/))) {
+#          $text = "<A NAME=\"SECTION$section_tag\">$text</A>\n" . $anchors;
+       # ...put anchors preceding the title, on a separate when left-aligned
+#      } else {
+           $text = "<A NAME=\"SECTION$section_tag\">$anchor_invisible_mark</A>$anchors"
+               . (!($align)||($align =~ /left/i ) ? "<BR>" : "") . "\n". $text;
+#      }
+    } elsif (!($text =~ /<A[^\w]/io)) {
+       # no embedded anchors, so anchor it all
+       $text = "<A NAME=\"SECTION$section_tag\">\n" . $text . "</A>";
+    } else {
+       # there are embedded anchors; these cannot be nested
+       local ($tmp) = $text;
+       $tmp =~ s/<//o ;        # find 1st <
+       if ($`) {               # anchor text before the first < 
+#          $text = "<A NAME=\"SECTION$section_tag\">\n" . $` . "</A>\n<" . $';
+           $text = "<A NAME=\"SECTION$section_tag\">\n" . $` . "</A>";
+           $pre_anchors = "<" . $';
+           if ($pre_anchors =~ /^(<A NAME=\"[^\"]+>${anchor_invisible_mark}<\/A>\s*)+$/) {
+               $pre_anchors .= "\n"
+           } else { $text .= $pre_anchors; $pre_anchors = '' }
+       } else {
+           # $text starts with a tag
+           local($after,$tmp) = ($','');
+           if ( $after =~ /^A[^\w]/i ) {       
+               # it is an anchor already, so need a separate line
+               $text = "<A NAME=\"SECTION$section_tag\">$anchor_invisible_mark</A><BR>\n$text";
+           } else {
+               # Is it a tag enclosing the anchor ?
+               $after =~ s/^(\w)*[\s|>]/$tmp = $1;''/eo;
+               if ($after =~ /<A.*<\/$tmp>/) {
+                   # it encloses an anchor, so use anchor_mark + break
+                   $text = "<A NAME=\"SECTION$section_tag\">$anchor_invisible_mark</A><BR>\n$text";
+               } else {
+                   # take up to the anchor
+                   $text =~ s/^(.*)<A([^\w])/"<A NAME=\"SECTION$section_tag\">$1<A$2"/oe;
+               }
+           }
+       }
+    }
+    "$pre_anchors\n<$level$align>$text\n<\/$elevel>";
+}
+
+sub do_cmd_captionstar { &process_cmd_caption(1, @_) }
+sub do_cmd_caption { &process_cmd_caption('', @_) }
+sub process_cmd_caption {
+    local($noLOTentry, $_) = @_;
+    local($text,$opt,$br_id, $contents);
+    local($opt) = &get_next_optional_argument;
+    $text = &missing_braces unless (
+       (s/$next_pair_pr_rx/$br_id=$1;$text=$2;''/e)
+       ||(s/$next_pair_rx/$br_id=$1;$text=$2;''/e));
+
+    # put it in $contents, so &extract_captions can find it
+    local($contents) = join('','\caption', ($opt ? "[$opt]" : '')
+          , "$O$br_id$C" , $text , "$O$br_id$C");
+
+    # $cap_env is set by the surrounding figure/table
+    &extract_captions($cap_env);
+    $contents.$_;
+}
+
+sub extract_captions {
+    # Uses and modifies $contents and $cap_anchors, defined in translate_environments
+    # and modifies $figure_captions, $table_captions, $before and $after
+    # MRO: no effect! local($env,*cap_width) = @_;
+    local($env) = @_;
+    local(%captions, %optional_captions, $key, $caption, $optional_caption,
+         $item, $type, $list, $extra_list, $number, @tmp, $br_id, $_);
+    # associate the br_id of the caption with the argument of the caption
+    $contents =~ s/$caption_rx(\n)?/do {
+       $key = $9; $caption = $10; $optional_caption = $3;
+       $key = &filter_caption_key($key) if (defined &filter_caption_key);
+       $optional_captions{$key} = $optional_caption||$caption;
+       $captions{$key} = $10; ''}/ego;
+#      $captions{$9} = $10; $caption_mark }/ego;
+    $key = $caption = $optional_caption = '';
+
+    #catch any  \captionwidth  settings that may remain
+    $contents =~ s/$caption_width_rx(\n)?/&translate_commands($&);''/eo;
+    
+#    $after = join("","<P>",$after) if ($&);
+#    $before .= "</P>" if ($&);
+    #JKR: Replaced "Figure" and "Table" with variables (see latex2html.config too).
+    if ($env eq 'figure') {
+       if ((defined &do_cmd_figurename)||$new_command{'figurename'}){
+           $br_id = ++$global{'max_id'};
+           $type = &translate_environments("$O$br_id$C\\figurename$O$br_id$C")
+               unless ($noLOFentry);
+       } else { $type = $fig_name }
+       $list = "\$figure_captions";
+#      $extra_list = "\$segment_figure_captions" if ($figure_table_captions);
+       $extra_list = "\$segment_figure_captions" if ($segment_figure_captions);
+    }
+    elsif ($env =~ /table/) {
+       if ((defined &do_cmd_tablename)||$new_command{'tablename'}) {
+           $br_id = ++$global{'max_id'};
+           $type = &translate_environments("$O$br_id$C\\tablename$O$br_id$C")
+               unless ($noLOTentry);
+       } else { $type = $tab_name }
+       $list = "\$table_captions";
+       $extra_list = "\$segment_table_captions" if ($segment_table_captions);
+    }
+
+#    $captions = "";
+    $cap_anchors = "";
+    local($this);
+    foreach $key (sort {$a <=> $b;} keys %captions){ # Sort numerically
+       $this = $captions{$key};
+       $this =~ s/\\label\s*($O\d+$C)[^<]+\1//g; # remove \label commands
+               local($br_id) = ++$global{'max_id'};
+       local($open_tags_R) = []; # locally, initially no style
+       $caption = &translate_commands(
+            &translate_environments("$O$br_id$C$this$O$br_id$C"));
+
+       # same again for the optional caption
+       $this = $optional_captions{$key};
+       $this =~ s/\\label\s*($O\d+$C)[^<]+\1//g; # remove \label commands
+       local($open_tags_R) = []; local($br_id) = ++$global{'max_id'};
+       $this = &translate_environments("$O$br_id$C$this$O$br_id$C");
+       $optional_caption = &translate_commands($this);
+
+       $cap_anchors .= "<A NAME=\"$key\">$anchor_mark</A>";
+       $_ = $optional_caption || $caption;
+
+
+       # split at embedded anchor or citation marker
+       local($pre_anchor,$post_anchor) = ('','');
+       if (/\s*(<A\W|\#[^#]*\#<tex2html_cite_[^>]*>)/){
+           $pre_anchor = "$`";
+           $post_anchor = "$&$'";
+           $pre_anchor = $anchor_invisible_mark
+               unless (($pre_anchor)||($SHOW_SECTION_NUMBERS));
+       } else {
+           $pre_anchor = "$_";
+       }
+
+#JCL(jcl-tcl)
+##     &text_cleanup;
+##     $_ = &encode_title($_);
+##     s/&nbsp;//g;            # HWS - LaTeX changes ~ in its .aux files
+#      $_ = &sanitize($_);
+##
+#      $_ = &revert_to_raw_tex($_);
+
+       #replace image-markers by the image params
+       s/$image_mark\#([^\#]+)\#/&purify_caption($1)/e;
+
+       local($checking_caption, $cap_key) = (1, $_);
+       $cap_key = &simplify($cap_key);
+       $cap_key = &sanitize($cap_key);
+       @tmp = split(/$;/, eval ("\$encoded_$env" . "_number{\$cap_key}"));
+       $number = shift(@tmp);
+       $number = "" if ($number eq "-1");
+
+       if (!$number) {
+           $cap_key = &revert_to_raw_tex($cap_key);
+           @tmp = split(/$;/
+              , eval ("\$encoded_$env" . "_number{\$cap_key}"));
+           $number = shift(@tmp);
+           $number = "" if ($number eq "-1");
+       }
+
+       #resolve any embedded cross-references first
+       $checking_caption = '';
+       $_ = &simplify($_);
+       $_ = &sanitize($_);
+
+
+#      @tmp = split(/$;/, eval ("\$encoded_$env" . "_number{\$_}"));
+#      $number = shift(@tmp);
+#      $number = "" if ($number eq "-1");
+
+       &write_warnings(qq|\nNo number for "$_"|) if (! $number);
+       eval("\$encoded_$env" . "_number{\$_} = join(\$;, \@tmp)");
+
+       $item = join( '', ($SHOW_SECTION_NUMBERS ? $number."\. " : '')
+           , &make_href("$CURRENT_FILE#$key", $pre_anchor)
+           , $post_anchor);
+       undef $_;
+       undef @tmp;
+
+       $captions = join("", ($captions ? $captions."\n<BR>\n" : '')
+               , "<STRONG>$type" , ($number ? " $number:" : ":")
+               , "</STRONG>\n$caption" , (($captions) ? "\n" : "" ));
+
+       do {
+           eval "$extra_list .= \"\n<LI>\" .\$item" if ($extra_list);
+           eval "$list .= \"\n<LI>\" .\$item" }
+                unless ( $noLOTentry || $noLOFentry);
+#      eval("print \"\nCAPTIONS:\".$extra_list.\n\"");
+    }
+}
+
+
+# This processes \label commands found in environments that will
+# be handed over to Latex. Sets the table %symbolic_labels
+sub do_labels {
+    local($context,$new_context) = @_;
+    local($label);
+    # MRO: replaced $* by /m
+    $context =~ s/\s*$labels_rx/do {
+       $label = &do_labels_helper($2);
+       $new_context = &anchor_label($label,$CURRENT_FILE,$new_context);""}/geom;
+    $new_context;
+}
+
+sub extract_labels {
+    local($_) = @_;
+    local($label,$anchors);
+    # MRO: replaced $* by /m
+    while (s/[ \t]*$labels_rx//om) {
+        $label = &do_labels_helper($2);
+        $anchors .= &anchor_label($label,$CURRENT_FILE,'');
+    }
+    ($_, $anchors);
+}
+
+# This should be done inside the substitution but it doesn't work ...
+sub do_labels_helper {
+    local($_) = @_;
+    s/$label_rx/_/g;  # replace non-alphanumeric characters
+    $symbolic_labels{$_} = $latex_labels{$_}; # May be empty;
+    $_;
+}
+
+sub convert_to_description_list {
+    # MRO: modified to use $_[1]
+    # local($which, *list) = @_;
+    my $which = $_[0];
+    $_[1] =~ s!(</A>\s*)<[OU]L([^>]*)>!$1<DD><DL$2>!ig;
+    $_[1] =~ s!<(/?)[OU]L([^>]*)>!$1? "<$1DL$2>":"<DL$2>"!eig;
+    $_[1] =~ s!(</?)LI>!$1D$which>!ig;
+#    $_[1] =~ s/^\s*<DD>//;
+}
+
+sub add_toc { &add_real_toc(@_) }
+sub add_real_toc {
+    local($temp1, $temp2);
+    print "\nDoing table of contents ...";
+    local(@keys) = keys %toc_section_info;
+    @keys = sort numerically @keys;
+    $temp1 = $MAX_LINK_DEPTH; $temp2 = $MAX_SPLIT_DEPTH;
+    $MAX_SPLIT_DEPTH = $MAX_LINK_DEPTH = 1000;
+    #JKR: Here was a "Contents" - replaced it with $toc_title
+    local($base_key) = $keys[0];
+    if ($MULTIPLE_FILES) {
+       $base_key = $THIS_FILE;
+    }
+    local($title);
+    if ((defined &do_cmd_contentsname)||$new_command{'contentsname'}) {
+       local($br_id)=++$global{'max_id'};
+       $title = &translate_environments("$O$br_id$C\\contentsname$O$br_id$C");
+    } else { $title = $toc_title }
+    local($toc,$on_first_page) = ('','');
+    $on_first_page = $CURRENT_FILE
+       unless ($MAX_SPLIT_DEPTH && $MAX_SPLIT_DEPTH <1000);
+    $toc = &add_child_links($title,$on_first_page,'',1,$keys[0],@keys);
+    &convert_to_description_list('T',$toc) if ($use_description_list);
+    s/$toc_mark/$toc/;
+    $MAX_LINK_DEPTH = $temp1; $MAX_SPLIT_DEPTH = $temp2;
+}
+
+# Assign ref value, but postpone naming the label
+sub make_half_href {
+    local($link) = $_[0];
+    $href_name++;
+    "<A NAME=\"tex2html$href_name\"\n HREF=\"$link\">";
+}
+
+
+# Redefined in makeidx.perl
+sub add_idx {
+    local($sidx_style, $eidx_style) =('<STRONG>','</STRONG>');
+    if ($INDEX_STYLES) {
+       if ($INDEX_STYLES =~/,/) {
+       local(@styles) = split(/\s*,\s*/,$INDEX_STYLES);
+           $sidx_style = join('','<', join('><',@styles) ,'>');
+           $eidx_style = join('','</', join('></',reverse(@styles)) ,'>');
+       } else {
+           $sidx_style = join('','<', $INDEX_STYLES,'>');
+           $eidx_style = join('','</', $INDEX_STYLES,'>');
+       }
+    }
+    &add_real_idx(@_)
+}
+sub add_real_idx {
+    print "\nDoing the index ...";
+    local($key, $str, @keys, $index, $level, $count,
+         @previous, @current);
+    @keys = keys %index;
+    @keys = sort keysort  @keys;
+    $level = 0;
+    foreach $key (@keys) {
+       @current = split(/!/, $key);
+       $count = 0;
+       while ($current[$count] eq $previous[$count]) {
+           $count++;
+       }
+       while ($count > $level) {
+           $index .= "\n<DL COMPACT>";
+           $level++;
+       }
+       while ($count < $level) {
+           $index .= "\n</DL>";
+           $level--;
+       }
+       foreach $term (@current[$count .. $#current-1]) {
+           # need to "step in" a little
+#          $index .= "<DT>" . $term . "\n<DL COMPACT>";
+           $index .= "\n<DT>$sidx_style" . $term . "$eidx_style\n<DD><DL COMPACT>";
+           $level++;
+       }
+       $str = $current[$#current];
+       $str =~ s/\#\#\#\d+$//o; # Remove the unique id's
+       $index .= $index{$key} .
+           # If it's the same string don't start a new line
+           (&index_key_eq(join('',@current), join('',@previous)) ?
+            ", $sidx_style" . $cross_ref_visible_mark . "$eidx_style</A>\n" :
+            "<DT>$sidx_style" . $str . "$eidx_style</A>\n");
+       @previous = @current;
+    }
+    while ($count < $level) {
+       $index .= "\n</DL>";
+       $level--;
+    }
+    $index = '<DD>'.$index unless ($index =~ /^\s*<D(T|D)>/);
+
+    $index =~ s/(<A [^>]*>)(<D(T|D)>)/$2$1/g;
+    
+#    s/$idx_mark/<DL COMPACT>$index<\/DL>/o;
+    s/$idx_mark/$preindex\n<DL COMPACT>\n$index<\/DL>\n/o;
+}
+
+sub keysort {
+    local($x, $y) = ($a,$b);
+    $x = &clean_key($x);
+    $y = &clean_key($y);
+#    "\L$x" cmp "\L$y";  # changed sort-rules, by M Ernst.
+    # Put alphabetic characters after symbols; already downcased
+    $x =~ s/^([a-z])/~~~$1/;
+    $y =~ s/^([a-z])/~~~$1/;
+    $x cmp $y;
+}
+
+sub index_key_eq {
+    local($a,$b) = @_;
+    $a = &clean_key($a);
+    $b = &clean_key($b);
+    $a eq $b;
+}
+
+sub clean_key {
+    local ($_) = @_;
+    tr/A-Z/a-z/;
+    s/\s+/ /g;         # squeeze white space and newlines into space
+    s/ (\W)/$1/g;      # make foo( ), foo () and foo(), or <TT>foo</TT>
+    ;                  # and <TT>foo </TT> to be equal
+    s/$O\d+$C//go;     # Get rid of bracket id's
+    s/$OP\d+$CP//go;   # Get rid of processed bracket id's
+    s/\#\#\#\d+$//o;   # Remove the unique id
+    $_;
+}
+
+
+sub make_footnotes {
+    # Uses $footnotes defined in translate and set in do_cmd_footnote
+    # Also uses $footfile
+    local($_) = "\n<DL>$footnotes\n<\/DL>";
+    $footnotes = ""; # else they get used
+    local($title);
+    if ((defined &do_cmd_footnotename)||$new_command{'footnotename'}) {
+       local($br_id)=++$global{'max_id'};
+       $title = &translate_environments("$O$br_id$C\\footnotename$O$br_id$C");
+    } else {
+       $foot_title = "Footnotes" unless $foot_title;
+       $title = $foot_title;
+    }
+    print "\nDoing footnotes ...";
+#JCL(jcl-tcl)
+# If the footnotes go into a separate file: see &make_file.
+    if ($footfile) {
+       $toc_sec_title = $title;
+       &make_file($footfile, $title, $FOOT_COLOR); # Modifies $_;
+       $_ = "";
+    } else {
+       $footnotes = ""; # else they get re-used
+       $_ = join ('', '<BR><HR><H4>', $title, '</H4>', $_ );
+    }
+    $_;
+}
+
+sub post_process_footnotes {
+    &slurp_input($footfile);
+    open(OUT, ">$footfile") || die "Cannot write file '$footfile': $!\n";
+    &replace_markers;
+    &post_post_process if (defined &post_post_process);
+    &adjust_encoding;
+    print OUT $_;
+    close OUT;
+}
+
+sub make_file {
+    # Uses and modifies $_ defined in the caller
+    local($filename, $title, $layout) = @_;
+    $layout = $BODYTEXT unless $layout;
+    $_ = join('',&make_head_and_body($title,$layout), $_
+       , (($filename =~ /^\Q$footfile\E$/) ? '' : &make_address )
+       , (($filename =~ /^\Q$footfile\E$/) ? "\n</BODY>\n</HTML>\n" : '')
+       );
+    &replace_markers unless ($filename eq $footfile); 
+
+    unless(open(FILE,">$filename")) {
+        print "\nError: Cannot write '$filename': $!\n";
+        return;
+    }
+    print FILE $_;
+    close(FILE);
+}
+
+sub add_to_body {
+    local($attrib, $value) = @_;
+    local($body) = $BODYTEXT;
+    if ($body =~ s/\Q$attrib\E\s*=\s*"[^"]*"/$attrib="$value"/) {
+    } else {
+       $body .= " $attrib=\"$value\""; $body =~ s/\s{2,}/ /g;
+    }
+    $BODYTEXT = $body if $body;
+}
+
+sub replace_verbatim_marks {
+    # Modifies $_
+    my($tmp);
+    s/$math_verbatim_rx/&make_comment('MATH', $verbatim{$1})/eg;
+    s/$mathend_verbatim_rx/&make_comment('MATHEND', '')/eg;
+#    s/$verbatim_mark(verbatim\*?)(\d+)#/<PRE>\n$verbatim{$2}\n<\/PRE>/go;
+##    s/$verbatim_mark(\w*[vV]erbatim\*?)(\d+)#/\n$verbatim{$2}\n/go;
+    s!$verbatim_mark(\w*[vV]erbatim\*?|tex2html_code)(\d+)#\n?!$tmp=$verbatim{$2};
+       $tmp.(($tmp =~/\n\s*$/s)? '':"\n")!eg;
+#      "\n".$tmp.(($tmp =~/\n\s*$/s)? '':"\n")!eg;
+#    s/$verbatim_mark(rawhtml)(\d+)#/$verbatim{$2}/eg; # Raw HTML
+    s/$verbatim_mark(imagesonly)(\d+)#//eg; # imagesonly is *not* replaced
+    # Raw HTML, but replacements may have protected characters
+    s/$verbatim_mark(rawhtml)(\d+)#/&unprotect_raw_html($verbatim{$2})/eg;
+    s/$verbatim_mark$keepcomments_rx(\d+)#/$verbatim{$2}/ego; # Raw TeX
+    s/$unfinished_mark$keepcomments_rx(\d+)#/$verbatim{$2}/ego; # Raw TeX
+}
+
+# TeX's special characters may have been escaped with a '\'; remove it.
+sub unprotect_raw_html {
+    local($raw) = @_;
+    $raw =~ s/\\($latex_specials_rx|~|\^|@)/$1/g;
+    $raw;
+}
+
+# remove file-markers; special packages may redefine &replace_file_marks
+sub remove_file_marks {
+    s/<(DD|LI)>\n?($file_mark|$endfile_mark)\#.*\#\n<\/\1>(\n|(<))/$4/gm;
+    s/($file_mark|$endfile_mark)\#.*\#(\n|(<))/$3/gm;
+}
+sub replace_file_marks { &remove_file_marks }
+
+sub remove_verbatim_marks {
+    # Modifies $_
+    s/($math_verbatim_rx|$mathend_verbatim_rx)//go;
+#    s/$verbatim_mark(verbatim\*?)(\d+)#//go;
+    s/$verbatim_mark(\w*[Vv]erbatim\w*\*?)(\d+)#//go;
+    s/$verbatim_mark(rawhtml|imagesonly)(\d+)#//go;
+    s/$verbatim_mark$keepcomments_rx(\d+)#//go;
+    s/$unfinished_mark$keepcomments_rx(\d+)#//go;
+}
+
+sub replace_verb_marks {
+    # Modifies $_
+    s/(?:$verb_mark|$verbstar_mark)(\d+)$verb_mark/
+       $code = $verb{$1};
+       $code = &replace_comments($code) if ($code =~ m:$comment_mark:);
+       "<code>$code<\/code>"/ego;
+}
+
+sub replace_comments{
+    local($_) = @_;
+    $_ =~ s/$comment_mark(\d+)\n?/$verbatim{$1}/go;
+    $_ =~ s/$comment_mark\d*\n/%\n/go;
+    $_;
+}
+
+sub remove_verb_marks {
+    # Modifies $_
+    s/($verb_mark|$verbstar_mark)(\d+)$verb_mark//go;
+}
+
+# This is used by revert_to_raw_tex
+sub revert_verbatim_marks {
+    # Modifies $_
+#    s/$verbatim_mark(verbatim)(\d+)#/\\begin{verbatim}$verbatim{$2}\\end{verbatim}\n/go;
+    s/$verbatim_mark(\w*[Vv]erbatim)(\d+)#/\\begin{$1}\n$verbatim{$2}\\end{$1}\n/go;
+    s/$verbatim_mark(rawhtml)(\d+)#/\\begin{rawhtml}\n$verbatim{$2}\\end{rawhtml}\n/go;
+    s/$verbatim_mark(imagesonly|tex2html_code)(\d+)#\n?/$verbatim{$2}/go;
+    s/$verbatim_mark$image_env_rx(\d+)#/\\begin{$1}\n$verbatim{$2}\\end{$1}\n/go;
+    s/($math_verbatim_rx|$mathend_verbatim_rx)//go;
+}
+
+sub revert_verb_marks {
+    # Modifies $_
+    s/$verbstar_mark(\d+)$verb_mark/\\verb*$verb_delim{$1}$verb{$1}$verb_delim{$1}/go;
+    s/$verb_mark(\d+)$verb_mark/\\verb$verb_delim{$1}$verb{$1}$verb_delim{$1}/go;
+}
+
+sub replace_cross_ref_marks {
+    # Modifies $_
+    local($label,$id,$ref_label,$ref_mark,$after,$name);
+    local($invis) = "<tex2html_anchor_invisible_mark></A>";
+#    s/$cross_ref_mark#([^#]+)#([^>]+)>$cross_ref_mark/
+    s/$cross_ref_mark#([^#]+)#([^>]+)>$cross_ref_mark<\/A>(\s*<A( NAME=\"\d+)\">$invis)?/
+       do {($label,$id) = ($1,$2); $name = $4;
+           $ref_label = $external_labels{$label} unless
+               ($ref_label = $ref_files{$label});
+           print "\nXLINK<: $label : $id :$name " if ($VERBOSITY > 3);
+           $ref_label = '' if ($ref_label eq $CURRENT_FILE);
+           $ref_mark = &get_ref_mark($label,$id);
+           &extend_ref if ($name); $name = '';
+           print "\nXLINK: $label : $ref_label : $ref_mark " if ($VERBOSITY > 3);
+           '"' . "$ref_label#$label" . "\">" . $ref_mark . "<\/A>"
+       }/geo;
+
+    # This is for pagerefs which cannot have symbolic labels ??? 
+#    s/$cross_ref_mark#(\w+)#\w+>/
+    s/$cross_ref_mark#([^#]+)#[^>]+>/
+       do {$label = $1;
+           $ref_label = $external_labels{$label} unless
+               ($ref_label = $ref_files{$label});
+           $ref_label = '' if ($ref_label eq $CURRENT_FILE);
+           print "\nXLINKP: $label : $ref_label" if ($VERBOSITY > 3);
+           '"' . "$ref_files{$label}#$label" . "\">"
+       }/geo;
+}
+
+#RRM: this simply absorbs the name from the invisible anchor following, 
+#     when the anchor itself is not already named.
+sub extend_ref {
+    if ($ref_label !=~ /NAME=/) { $label .= "\"\n".$name  }
+}
+
+sub remove_cross_ref_marks {
+    # Modifies $_
+#    s/$cross_ref_mark#(\w+)#(\w+)>$cross_ref_mark/
+    s/$cross_ref_mark#([^#]+)#([^>]+)>$cross_ref_mark/
+       print "\nLOST XREF: $1 : $2" if ($VERBOSITY > 3);''/ego;
+#    s/$cross_ref_mark#(\w+)#\w+>//go;
+    s/$cross_ref_mark#([^#]+)#[^#>]+>//go;
+}
+
+sub replace_external_ref_marks {
+    # Modifies $_
+    local($label, $link);
+#    s/$external_ref_mark#(\w+)#(\w+)>$external_ref_mark/
+    s/$external_ref_mark#([^#]+)#([^>]+)>$external_ref_mark/
+       do {($label,$id) = ($1,$2); 
+           $link = $external_labels{$label};
+           print "\nLINK: $label : $link" if ($VERBOSITY > 3);
+           '"'. "$link#$label" . "\">\n"
+              . &get_ref_mark("userdefined$label",$id)
+       }
+    /geo;
+}
+
+sub remove_external_ref_marks {
+    # Modifies $_
+#    s/$external_ref_mark#(\w+)#(\w+)>$external_ref_mark/
+    s/$external_ref_mark#([^#]+)#([^>]+)>$external_ref_mark/
+       print "\nLOST LINK: $1 : $2" if ($VERBOSITY > 3);''/ego;
+}
+
+sub get_ref_mark {
+    local($label,$id) = @_;
+    ( ( $SHOW_SECTION_NUMBERS && $symbolic_labels{"$label$id"}) ||
+     $latex_labels{"userdefined$label$id"} ||
+     $symbolic_labels{"$label$id"} ||
+     $latex_labels{$label} ||
+     $external_latex_labels{$label} ||
+     $cross_ref_visible_mark );
+}
+
+sub replace_bbl_marks {
+    # Modifies $_
+    s/$bbl_mark#([^#]+)#/$citations{$1}/go;
+}
+
+sub remove_bbl_marks {
+    # Modifies $_
+    s/$bbl_mark#([^#]+)#//go;
+}
+
+sub replace_image_marks {
+    # Modifies $_
+    s/$image_mark#([^#]+)#([\.,;:\)\]])?(\001)?([ \t]*\n?)(\001)?/
+       "$id_map{$1}$2$4"/ego;
+#      "$id_map{$1}$2".(($4)?"\n":'')/ego;
+}
+
+sub remove_image_marks {
+    # Modifies $_
+    s/$image_mark#([^#]+)#//go;
+}
+
+sub replace_icon_marks {
+    # Modifies $_
+    if ($HTML_VERSION < 2.2 ) {
+       local($icon);
+       s/$icon_mark_rx/$icon = &img_tag($1);
+           $icon =~ s| BORDER="?\d+"?||;$icon/ego;
+    } else {
+       s/$icon_mark_rx/&img_tag($1)/ego;
+    }
+}
+
+sub remove_icon_marks {
+    # Modifies $_
+    s/$icon_mark_rx//go;
+}
+
+sub replace_cite_marks {
+    local($key,$label,$text,$file);
+    # Modifies $_
+    # Uses $citefile set by the thebibliography environment
+    local($citefile) = $citefile;
+    $citefile =~ s/\#.*$//;
+    
+    s/#([^#]+)#$cite_mark#([^#]+)#((($OP\d+$CP)|[^#])*)#$cite_mark#/
+       $text = $3; $label= $1; $file='';
+       $text = $cite_info{$1} unless $text;
+       if ($checking_caption){
+           "$label"
+       } elsif ($citefiles{$2}){
+           $file = $citefiles{$2}; $file =~ s:\#.*$::;
+           &make_named_href('', "$file#$label","$text");
+       } elsif ($PREAMBLE) {
+           $text || "\#!$1!\#" ;
+       } elsif ($simplifying) {
+           $text
+       } else {
+            &write_warnings("\nno reference for citation: $1");
+            "\#!$1!\#"
+       }/sge ;
+    #
+    #RRM: Associate the cite_key with  $citefile , for use by other segments.
+    if ($citefile) {
+       local($cite_key, $cite_ref);
+       while (($cite_key, $cite_ref) = each %cite_info) {
+           if ($ref_files{'cite_'."$cite_key"} ne $citefile) {
+               $ref_files{'cite_'."$cite_key"} = $citefile;
+               $changed = 1; }
+       }
+    }
+}
+
+sub remove_cite_marks {
+    # Modifies $_
+    s/#([^#]+)#$cite_mark#([^#]+)#([^#]*)#$cite_mark#//go;
+}
+
+sub remove_anchors {
+# modifies $_
+    s/<A[^>]*>//g;
+    s/<\/A>//g;
+}
+
+
+# We need two matching keys to determine section/figure/etc. numbers.
+# The "keys" are the name of the section/figure/etc. and its
+# equivalent in the .aux file (also carrying the number we desire).
+# But both keys might have been translated slightly different,
+# depending on the usage of math, labels, special characters such
+# as umlauts, or simply spacing!
+#
+# This routine tries to squeeze the HTML translated keys such
+# that they match (hopefully very often). -- JCL
+#
+sub sanitize {
+    local($_,$mode) = @_;
+    &remove_markers;
+    &remove_anchors;
+    &text_cleanup;
+    s/(\&|;SPM)nbsp;//g;            # HWS - LaTeX changes ~ in its .aux files
+    #strip unwanted HTML constructs
+    s/<\/?(P|BR|H)[^>]*>//g;
+    s/\s+//g; #collapse white space
+    $_;
+}
+
+# This one removes any HTML markup, so that pure
+# plain text remains. (perhaps with <SUP>/<SUB> tags)
+# As the result will be part of the HTML file, it will be
+# &text_cleanup'd later together with its context.
+#
+sub purify {
+    local($_,$strict) = @_;
+    &remove_markers;
+    #strip unwanted HTML constructs
+#    s/<[^>]*>/ /g;
+    s/<(\/?SU[BP])>/>$1>/g unless ($strict);  # keep sup/subscripts ...
+    s/<[^>]*>//g;                             # remove all other tags
+    s/>(\/?SU[BP])>/<$1>/g unless ($strict);  # ...reinsert them
+    s/^\s+|\001//g; s/\s\s+/ /g;              #collapse white space
+    $_;
+}
+
+# This one is not as strict as &sanitize.
+# It is chosen to strip section names etc. a bit from
+# constructs so that it better fits a table of contents,
+# label files, etc.
+# As the result will be part of the HTML file, it will be
+# &text_cleanup'd later together with its context.
+#
+sub simplify {
+    local($_) = @_;
+    local($simplifying) = 1;
+    s/$tex2html_envs_rx//g;
+    if (/\\/) {
+       local($USING_STYLES) = 0;
+       $_ = &translate_commands($_);
+       undef $USING_STYLES;
+    }
+    &replace_external_ref_marks if /$external_ref_mark/;
+    &replace_cross_ref_marks if /$cross_ref_mark||$cross_ref_visible_mark/;
+    &replace_cite_marks if /$cite_mark/;
+    # strip unwanted HTML constructs
+#    s/<\/?H[^>]*>/ /g;
+    s/<\/?(H)[^>]*>//g;
+    s/<\#\d+\#>//g;
+    s/^\s+//;
+    $_;
+}
+
+#RRM: This extracts $anchor_mark portions from a given chunk of text,
+#     so they can be positioned separately by the calling subroutine.
+# added for v97.2: 
+#  search within the immediately following text also; so that 
+#  \index and \label after section-headings work as expected.
+#
+sub extract_anchors {
+    local($search_text, $start_only) = @_; 
+    local($anchors) = '';
+    local($untranslated_anchors) = '';
+
+    do {
+       while ($search_text =~ s/<A[^>]*>($anchor_mark|$anchor_invisible_mark)<\/A>//) {
+           $anchors .= $&;
+       }
+    } unless ($start_only);
+    
+    $search_text =~ s/\s*(\\protect)?\\(label|index|markright|markboth\s*(($O|$OP)\d+($C|$CP))[^<]*\3)\s*(($O|$OP)\d+($C|$CP))[^<]*\6/
+       $anchors .= $&;''/eg unless ($start_only);
+
+    while ( s/^\s*<A[^>]*>($anchor_mark|$anchor_invisible_mark)<\/A>//m) {
+       $untranslated_anchors .= $&;
+    }
+    while ( s/^\s*(\\protect)?\\(label|index|markright|markboth\s*(($O|$OP)\d+($C|$CP))[^<]*\3)\s*(($O|$OP)\d+($C|$CP))[^<]*\6//) {
+       $untranslated_anchors .= $&;
+    }
+    if ($TITLE||$start_only) {
+       $anchors .= &translate_commands($untranslated_anchors);
+       $untranslated_anchors = '';
+    }
+    ($anchors.$untranslated_anchors,$search_text); 
+}
+
+# This routine must be called once on the text only,
+# else it will "eat up" sensitive constructs.
+sub text_cleanup {
+    # MRO: replaced $* with /m
+    s/(\s*\n){3,}/\n\n/gom;    # Replace consecutive blank lines with one
+    s/<(\/?)P>\s*(\w)/<$1P>\n$2/gom;      # clean up paragraph starts and ends
+    s/$O\d+$C//go;             # Get rid of bracket id's
+    s/$OP\d+$CP//go;           # Get rid of processed bracket id's
+    s/(<!)?--?(>)?/(length($1) || length($2)) ? "$1--$2" : "-"/ge;
+    # Spacing commands
+    s/\\( |$)/ /go;
+    #JKR: There should be no more comments in the source now.
+    #s/([^\\]?)%/$1/go;        # Remove the comment character
+    # Cannot treat \, as a command because , is a delimiter ...
+    s/\\,/ /go;
+    # Replace tilde's with non-breaking spaces
+    s/ *~/&nbsp;/g;
+
+    ### DANGEROUS ?? ###
+    # remove redundant (not <P></P>) empty tags, incl. with attributes
+    s/\n?<([^PD >][^>]*)>\s*<\/\1>//g;
+    s/\n?<([^PD >][^>]*)>\s*<\/\1>//g;
+    # remove redundant empty tags (not </P><P> or <TD> or <TH>)
+    s/<\/(TT|[^PTH][A-Z]+)><\1>//g;
+    s/<([^PD ]+)(\s[^>]*)?>\n*<\/\1>//g;
+
+    
+#JCL(jcl-hex)
+# Replace ^^ special chars (according to p.47 of the TeX book)
+# Useful when coming from the .aux file (german umlauts, etc.)
+    s/\^\^([^0-9a-f])/chr((64+ord($1))&127)/ge;
+    s/\^\^([0-9a-f][0-9a-f])/chr(hex($1))/ge;
+}
+
+# This is useful for getting words from a title which are not cluttered
+# with tex2html markers or HTML constructs
+sub extract_pure_text {
+    local($mode) = @_;
+    &text_cleanup;             # Remove marking brackets
+#
+# HWS <hswan@perc.Arco.com>:  Conditionally doing the following
+#     permits equations in section headings.
+#
+    if ($mode eq "strict") {
+       s/$image_mark#[^#]*#//g;        # Remove image marker
+       s/$bbl_mark#[^#]*#//g;          # Remove citations marker
+        s/<tex2html_percent_mark>/%/g;  # BMcM: Retain % signs...
+        s/<tex2html_ampersand_mark>/\&amp;/g;
+       s/tex2html[\w\d]*//g;   # Remove other markers
+       }
+
+#
+# HWS <hswan@perc.Arco.com>:  Replace next statement with the following two
+#    to permit symbolic links and images to appear in section headings.
+
+#   s/<[^>]*>//go;                     # Remove HTML constructs
+    s/$OP[^#]*$CP//go;                 # Remove <# * #> constructs
+    s/<\s*>//go;                       # Remove embedded whitespace
+}
+
+############################ Misc ####################################
+
+# MRO: Print standardized header
+sub banner {
+    print <<"EOF";
+This is LaTeX2HTML Version $TEX2HTMLVERSION
+by Nikos Drakos, Computer Based Learning Unit, University of Leeds.
+
+EOF
+}
+
+# MRO: Extract usage information from POD
+sub usage {
+    my $start  = 0;
+    my $usage  = 'Usage: ';
+    my $indent = '';
+
+    print (@_, "\n") if @_;
+
+    my $perldoc = "/usr/bin${dd}perldoc";
+    my $script = $SCRIPT || $0;
+    open(PIPE, "$perldoc -t $script |")
+        || die "Fatal: can't open pipe: $!";
+    while (<PIPE>) {
+        if (/^\s*$/) {
+            next;
+        } elsif (/^SYNOPSIS/) {
+            $start = 1;
+        } elsif (/^\w/) {
+            $start = 0;
+        } elsif ($start == 1) {
+            ($indent) = /^(\s*)/;
+            s/^$indent/$usage/;
+            $usage =~ s/./ /g;
+            $start = 2;
+            print $_;
+        } elsif ($start == 2) {
+            s/^$indent/$usage/;
+            print $_;
+        }
+    }
+    close PIPE;
+    1;
+}
+
+# The bibliographic references, the appendices, the lists of figures and tables
+# etc. must appear in the contents table at the same level as the outermost
+# sectioning command. This subroutine finds what is the outermost level and
+# sets the above to the same level;
+sub set_depth_levels {
+    # Sets $outermost_level
+    local($level);
+    # scan the document body, not the preamble, for use of sectioning commands
+    my ($contents) = $_;
+    if ($contents =~ /\\begin\s*((?:$O|$OP)\d+(?:$C|$CP))document\1|\\startdocument/s) {
+       $contents = $';
+    }
+    #RRM:  do not alter user-set value for  $MAX_SPLIT_DEPTH
+    foreach $level ("part", "chapter", "section", "subsection",
+                   "subsubsection", "paragraph") {
+       last if (($outermost_level) = $contents =~ /\\($level)$delimiter_rx/);
+       last if (($outermost_level) = $contents =~ /\\endsegment\s*\[\s*($level)\s*\]/s);
+       if ($contents =~ /\\segment\s*($O\d+$C)[^<]+\1\s*($O\d+$C)\s*($level)\s*\2/s)
+               { $outermost_level = $3; last };
+    }
+    $level = ($outermost_level ? $section_commands{$outermost_level} :
+             do {$outermost_level = 'section'; 3;});
+
+    #RRM:  but calculate value for $MAX_SPLIT_DEPTH when a $REL_DEPTH was given
+    if ($REL_DEPTH && $MAX_SPLIT_DEPTH) { 
+       $MAX_SPLIT_DEPTH = $level + $MAX_SPLIT_DEPTH;
+    } elsif (!($MAX_SPLIT_DEPTH)) { $MAX_SPLIT_DEPTH = 1 };
+
+    %unnumbered_section_commands = (
+          'tableofcontents', $level
+       , 'listoffigures', $level
+       , 'listoftables', $level
+       , 'bibliography', $level
+       , 'textohtmlindex', $level
+        , %unnumbered_section_commands
+        );
+
+    %section_commands = ( 
+         %unnumbered_section_commands
+        , %section_commands
+        );
+}
+
+# Now ignores accents which cannot be translated to ISO-LATIN-1 characters
+# Also replaces ?' and !' ....
+sub replace_strange_accents { 
+    &real_replace_strange_accents(@_); # if ($CHARSET =~ /8859[_\-]1$/);
+}
+sub real_replace_strange_accents {
+    # Modifies $_;
+    s/\?`/&iso_map("iquest", "")/geo;
+    s/!`/&iso_map("iexcl", "")/geo;
+    s/\\\^\\i /&iso_map("icirc", "")/geo;
+    my ($charset) = "${CHARSET}_character_map_inv";
+    $charset =~ s/-/_/g;
+    # convert upper 8-bit characters
+    if (defined %$charset &&($CHARSET =~ /8859[_\-]1$/)) {
+       s/([\200-\377])/
+           $tmp = $$charset{'&#'.ord($1).';'};
+           &mark_string($tmp) if ($tmp =~ m!\{!);
+           &translate_commands($tmp)
+       /egos
+    }
+};
+
+# Creates a new directory or reuses old, perhaps after deleting its contents
+sub new_dir {
+    local($this_dir,$mode) = @_;
+    local(@files)=();
+    $this_dir = '.' unless $this_dir;
+    $this_dir =~ s/[$dd$dd]+$//o;
+    local($print_dir) = $this_dir.$dd;
+    (!$mode && mkdir($this_dir, 0755)) ||
+       do {
+           print "\nCannot create directory $print_dir: $!" unless ($mode);
+           if ($REUSE) {
+               print ", reusing it.\n" unless ($mode);
+               &reuse($this_dir,$print_dir);
+           } else {
+               print "\n" unless ($mode);
+               while (! ($answer =~ /^[dqr]$/)) {
+                   if ($mode) {
+                       $answer = $mode;
+                   } else { 
+                       print "(r) Reuse the images in the old directory OR\n"
+                           . (($this_dir eq '.') ?
+               "(d) *** DELETE *** the images in $print_dir  OR\n"
+               : "(d) *** DELETE *** THE CONTENTS OF $print_dir  OR\n" )
+                           . "(q) Quit ?\n:";
+                       $answer = scalar(<STDIN>);
+                   };
+                   if ($answer =~ /^d$/) {
+                        @files = ();
+                       if(opendir(DIR,$this_dir)) {
+                           @files = readdir DIR;
+                           closedir DIR;
+                        } else {
+                            print "\nError: Cannot read dir '$this_dir': $!\n";
+                        }
+                       foreach (@files) {
+                           next if /^\.+$/;
+                           if (-d "$this_dir$dd$_") {
+                               &new_dir("$this_dir$dd$_",'d');
+                           } elsif ($this_dir eq '.') {
+                               L2hos->Unlink($_) if (/\.(pl|gif|png)$/) 
+                           } else {
+                               L2hos->Unlink("$this_dir$dd$_"); 
+                           };
+                       }
+                       return(1) if ($this_dir eq '.');
+                       if($mode) {
+                         rmdir($this_dir);
+                         rmdir($print_dir);
+                        }
+                       if (!$mode) { &new_dir($this_dir,'r')};
+                       return(1);
+                   } elsif ($answer =~ /^q$/) {
+                       die "Bye!\n";
+                   } elsif ($answer =~ /^r$/) {
+                       &reuse($this_dir,$print_dir);
+                       return(1);
+                   } else {print "Please answer r d or q!\n";};
+               }
+           };
+       };
+    1;
+}
+
+sub reuse {
+    local($this_dir,$print_dir) = @_;
+    $print_dir = $this_dir.$dd unless ($print_dir);
+    if (-f "$this_dir$dd${PREFIX}images.pl") {
+       print STDOUT "Reusing directory $print_dir:\n";
+       local($key);
+       require("$this_dir$dd${PREFIX}images.pl");
+    }
+}
+
+
+# JCL(jcl-del) - use $CD rather than a space as delimiter.
+# The commands might take white space, or not, depending on
+# their definition. Eg. \relax takes white space, because it's a
+# letter command, but \/ won't.
+# TeX seems to have an internal separator: If \x is " x",
+# and \y is "y", then \expandafter\y \x expands to "y x", TeX
+# hasn't gobbled the space, meaning that spaces are gobbled once
+# when the \y token is consumed, but then never again after \y.
+#
+# The actions below ensure to insert exactly one space after
+# the command name.    # what happens to  `\ '  ?
+# The substition is done twice to handle \one\delimits\another
+# cases.
+# The internal shortcut $CD is then turned into the single
+# space we desire.
+#
+sub tokenize {
+    # Modifies $_;
+    local($rx) = @_;
+    # $rx must be specially constructed, see &make_new_cmd_rx.
+    if (length($rx)) {
+       # $1: non-letter cmd, or $2: letter cmd
+       s/$rx/\\$1$2$CD$4/g;
+       s/$rx/\\$1$2$CD$4/g;
+       s/$CD+/ /g;     # puts space after each command name
+    }
+}
+
+# When part of the input text contains special perl characters and the text
+# is to be used as a pattern then these specials must be escaped.
+sub escape_rx_chars {
+    my($rx) = @_; # must use a copy of the string
+    $rx =~ s:([\\(){}[\]\^\$*+?.|]):\\$1:g; $rx; }
+
+# Does not do much but may need it later ...
+# The document environment has to be removed because it spans
+# more than one sections (the translator can only deal with
+# environments wholly contained with sections).
+
+# (Does a little more now ... the end of the preamble is now marked
+# with an internally-generated command which causes all output
+# erroneously generated from unrecognized commands in the preamble
+# to vanish --- rst).
+
+sub remove_document_env {
+#    s/\\begin$match_br_rx[d]ocument$match_br_rx/\\latextohtmlditchpreceding /o;
+    if (/\\begin\s*${match_br_rx}document$match_br_rx/) { 
+        s/\\begin\s*$match_br_rx[d]ocument$match_br_rx/\\latextohtmlditchpreceding /
+    }
+#   s/\\end$match_br_rx[d]ocument$match_br_rx(.|\n)*//o;
+    if (/\\end\s*${match_br_rx}document$match_br_rx/) { $_ = $` }
+}
+
+# And here's the code to handle the marker ...
+
+sub do_cmd_latextohtmlditchpreceding {
+    local($_) = @_;
+    $ref_before = '';
+    $_;
+}
+
+print "\n"; # flushes a cache? This helps, for some unknown reason!!
+
+sub do_AtBeginDocument{
+    local($_) = @_;
+    eval $AtBeginDocument_hook;
+    $_;
+}
+
+sub cleanup {
+    local($explicit) = @_;
+    return unless $explicit || !$DEBUG;
+
+    if (opendir(DIR, '.')) {
+       while (defined($_ = readdir(DIR))) {
+           L2hos->Unlink($_)
+               if /\.ppm$/ || /^${PREFIX}images\.dvi$/ || /^(TMP[-._]|$$\_(image)?)/;
+       }
+       closedir (DIR);
+    }
+
+    L2hos->Unlink("WARNINGS") if ($explicit &&(-f "WARNINGS"));
+
+    if ($TMPDIR && opendir(DIR, $TMPDIR)) {
+       local(@files) = grep(!/^\.\.?$/,readdir(DIR));
+       local($busy);
+       foreach (@files) {
+           $busy .= $_." " unless (L2hos->Unlink("$TMPDIR$dd$_"));
+       }
+       closedir (DIR);
+       if ($busy) {
+           print "\n\nFiles: $busy  are still in use.\n\n" if ($DEBUG);
+       } else {
+           &write_warnings("\n\n Couldn't remove $TMPDIR : $!")
+               unless (rmdir $TMPDIR);
+       }
+    }
+    if (opendir(DIR, $TMP_)) {
+       local(@files) = grep(!/^\.\.?$/,readdir(DIR));
+       $busy = '';
+       foreach (@files) {
+           $busy .= "$_ " unless (L2hos->Unlink("$TMP_$dd$_"));
+       }
+       closedir (DIR);
+       local($full_dir) = L2hos->Make_directory_absolute($TMP_);
+       if ($busy) {
+           print "\n\nFiles: $busy in $full_dir are still in use.\n\n"
+               if ($DEBUG);
+       } else {
+           &write_warnings("\n\nCouldn't remove directory '$full_dir': $!")
+               unless (rmdir $full_dir);
+       }
+    }
+}
+
+sub handler {
+    print "\nLaTeX2HTML shutting down.\n";
+    kill ('INT', $child_pid) if ($child_pid);
+    &close_dbm_database;
+    &cleanup();
+    exit(-1);
+}
+
+# Given a filename or a directory it returns the file and the full pathname
+# relative to the current directory.
+sub get_full_path {
+    local($file) = @_;
+    local($path,$dir);
+    if (-d $file) {    # $file is a directory
+       $path = L2hos->Make_directory_absolute($file);
+       $file = '';
+
+# JCL(jcl-dir)
+    } elsif ($file =~ s|\Q$dd\E([^$dd$dd]*)$||o ) {
+       $path = $file;
+       $file = $1;
+       $path = L2hos->Make_directory_absolute($path);
+
+#RRM: check within $TEXINPUTS directories
+    } elsif (!($TEXINPUTS =~ /^\.$envkey$/)) {
+       #check along directories in the $TEXINPUTS variable
+       foreach $dir (split(/$envkey/,$TEXINPUTS)) {
+           $dir =~ s/[$dd$dd]$//o;
+           if (-f $dir.$dd.$file) {
+               $path = L2hos->Make_directory_absolute($dir);
+               last;
+           }
+       }
+    } else {
+       $path = L2hos->Cwd();
+    }
+    ($path, $file);
+}
+
+
+# Given a directory name in either relative or absolute form, returns
+# the absolute form.
+# Note: The argument *must* be a directory name.
+# The whole function has been moved to override.pm
+
+
+
+# Given a relative filename from the directory in which the original
+# latex document lives, it tries to expand it to the full pathname.
+sub fulltexpath {
+    # Uses $texfilepath defined in sub driver
+    local($file) = @_;
+    $file =~ s/\s//g;
+    $file = "$texfilepath$dd$file"
+      unless (L2hos->is_absolute_path($file));
+    $file;
+}
+
+#RRM  Extended to allow customised filenames, set $CUSTOM_TITLES
+#     or long title from the section-name, set $LONG_TITLES
+#
+sub make_name {
+    local($sec_name, $packed_curr_sec_id) = @_;
+    local($title,$making_name,$saved) = ('',1,'');
+    if ($LONG_TITLES) {
+       $saved = $_;
+       &process_command($sections_rx, $_) if /^$sections_rx/;
+       $title = &make_long_title($TITLE)
+           unless ((! $TITLE) || ($TITLE eq $default_title));
+       $_ = $saved;
+    } elsif ($CUSTOM_TITLES) {
+       $saved = $_;
+       &process_command($sections_rx, $_) if /^$sections_rx/;
+       $title = &custom_title_hook($TITLE)
+           unless ((! $TITLE) || ($TITLE eq $default_title));
+       $_ = $saved;
+    }
+    if ($title) {
+       #ensure no more than 32 characters, including .html extension
+       $title =~ s/^(.{1,27}).*$/$1/;
+       ++$OUT_NODE;
+       join("", ${PREFIX}, $title, $EXTN);
+    } else {
+    # Remove 0's from the end of $packed_curr_sec_id
+       $packed_curr_sec_id =~ s/(_0)*$//;
+       $packed_curr_sec_id =~ s/^\d+$//o; # Top level file
+       join("",($packed_curr_sec_id ? 
+           "${PREFIX}$NODE_NAME". ++$OUT_NODE : $sec_name), $EXTN);
+    }
+}
+
+#RRM: redefine this subroutine, to create customised file-names
+#     based upon the actual section title.
+#     The default is empty, so reverts to:  node1, node2, ...
+#
+sub custom_title_hook {
+    local($_)= @_;
+    "";
+}
+
+
+sub make_long_title {
+    local($_)= @_;
+    local($num_words) = $LONG_TITLES;
+    #RRM:  scan twice for short words, due to the $4 overlap
+    #      Cannot use \b , else words break at accented letters
+    $_ =~ s/(^|\s)\s*($GENERIC_WORDS)(\'|(\s))/$4/ig;
+    $_ =~ s/(^|\s)\s*($GENERIC_WORDS)(\'|(\s))/$4/ig;
+    #remove leading numbering, unless that's all there is.
+    local($sec_num);
+    if (!(/^\d+(\.\d*)*\s*$/)&&(s/^\s*(\d+(\.\d*)*)\s*/$sec_num=$1;''/e))
+       { $num_words-- };
+    &remove_markers; s/<[^>]*>//g; #remove tags
+    #revert entities, etc. to TeX-form...
+    s/([\200-\377])/"\&#".ord($1).";"/eg;
+    $_ = &revert_to_raw_tex($_);
+
+    # get $LONG_TITLES number of words from what remains
+    $_ = &get_first_words($_, $num_words) if ($num_words);
+    # ...and cleanup accents, spaces and punctuation
+    $_ = join('', ($SHOW_SECTION_NUMBERS ? $sec_num : ''), $_);
+    s/\\\W\{?|\}//g; s/\s/_/g; s/\W/_/g; s/__+/_/g; s/_+$//;
+    $_;
+}
+
+
+sub make_first_key {
+    local($_);
+    $_ = ('0 ' x keys %section_commands);
+    s/^0/$THIS_FILE/ if ($MULTIPLE_FILES);  
+    chop;
+    $_;
+}
+
+# This copies the preamble into the variable $preamble.
+# It also sets the LaTeX font size, if $FONT_SIZE is set.
+sub add_preamble_head {
+    $preamble = join("\n", $preamble, @preamble);
+    $preamble = &revert_to_raw_tex($preamble);
+    $preamble = join ("\n", &revert_to_raw_tex(/$preamble_rx/o),
+                               $preamble);
+    local($savedRS) = $/; undef $/;
+    # MRO: replaced $* with /m
+    $preamble =~ /(\\document(style|class))\s*(\[[^]]*\])?\s*\{/sm;
+    local($before,$after) = ($`.$1, '{'.$');
+    $/ = $savedRS;
+    local ($options) = $3;
+    if ($FONT_SIZE) {
+       $options =~ s/(1\dpt)\b//;
+       $options =~ s/(\[|\])//g;
+       $options = "[$FONT_SIZE".($options ? ",$options" : '').']';
+       $preamble = join('', $before, $options, $after );
+       &write_mydb_simple("preamble", $preamble);
+       @preamble = split(/\n/, $preamble);
+       $LATEX_FONT_SIZE = $FONT_SIZE;
+    }
+    if (($options =~ /(1\dpt)\b/)&&(!$LATEX_FONT_SIZE)) {
+       $LATEX_FONT_SIZE = $1;
+    }
+    #RRM: need to know the font-size before the .aux file is read
+    $LATEX_FONT_SIZE = '10pt' unless ($LATEX_FONT_SIZE);
+}
+
+# It is necessary to filter some parts of the document back to raw
+# tex before passing them to latex for processing.
+sub revert_to_raw_tex {
+    local($_) = @_;
+    local($character_map) = "";
+    if ( $CHARSET && $HTML_VERSION ge "2.1" ) {
+       $character_map = $CHARSET;
+       $character_map =~ tr/-/_/; }
+    while (s/$O\s*\d+\s*$C/\{/o) { s/$&/\}/;}
+    while (s/$O\s*\d+\s*$C/\{/o) { s/$&/\}/;} #repeat this.
+    # The same for processed markers ...
+    while ( s/$OP\s*\d+\s*$CP/\{/o ) { s/$&/\}/; }
+    while ( s/$OP\s*\d+\s*$CP/\{/o ) { s/$&/\}/;} #repeat this.
+
+    s/<BR>/\\\\/g; # restores the \\ from \parbox's
+
+    # revert any math-entities
+    s/\&\w+#(\w+);/\\$1/g;
+    s/\&limits;/\\limits/g;
+    s/\\underscore/\\_/g;
+    s/\\circflex/\\^/g;
+    s/\\space/\\ /g;
+    s/;SPMthinsp;/\\,/g;
+    s/;SPMnegsp;/\\!/g;
+    s/;SPMsp;/\\:/g;
+    s/;SPMthicksp;/\\;/g;
+    s/;SPMgg;/\\gg /g;
+    s/;SPMll;/\\ll /g;
+    s/;SPMquot;/"/g;
+
+    # revert any super/sub-scripts
+    s/<SUP>/\^\{/g;
+    s/<SUB>/\_\{/g;
+    s/<\/SU(B|P)>/\}/g;
+
+
+#    #revert common character entities  ??
+#    s/&#92;/\\/g;
+
+#    # revert special marks
+#    s/$percent_mark/\\%/go;
+##    s/$comment_mark(\d+)\n/%$comments{$1}\n/go;
+    local($tmp,$tmp2);
+#    s/$comment_mark(\d+)\n/$tmp=$verbatim{$1};chomp($tmp);$tmp."\n"/ego;
+    s/$comment_mark(\d+)(\n|$|(\$))/$tmp=$verbatim{$1};$tmp2 = $3;
+        ($tmp=~m!^\%!s ? '':'%').$tmp.(($tmp=~ m!\n\s*$!s)?'':"\n").$tmp2/sego;
+    s/${verbatim_mark}tex2html_code(\d+)\#/$verbatim{$1}/go;
+    s/^($file_mark|$endfile_mark).*\#\n//gmo;
+    s/$comment_mark(\d*)\s*\n/%\n/go;
+    s/$dol_mark/\$/go;
+    s/$caption_mark//go;
+
+    # From &pre_process.
+    # MRO: replaced $* with /m
+    s/\\\\[ \t]*(\n)?/\\\\$1/gm;
+
+    # revert any array-cell delimiters
+    s/$array_col_mark/\&/g;
+    s/$array_row_mark/\\\\/g;
+    s/$array_text_mark/\\text/g;
+    s/$array_mbox_mark/\\mbox/g;
+
+    # Replace any verbatim and image markers ...
+    &revert_verbatim_marks;
+    &revert_verb_marks;
+
+
+#    &replace_image_marks;
+    s/$image_mark\#([^\#]+)\#/&recover_image_code($1)/eg;
+
+    # remove artificial environments and commands
+
+    s/(\n*)\\(begin|end)(($O|$OP)\d+($C|$CP))tex2html_b(egin)?group\3\n?/
+       ($1? "\n":'')."\\".($6? $2:(($2 =~ m|end|)? 'e':'b'))."group\n"
+    /gem;
+    s/\\(begin|end)(\{|(($O|$OP)\d+($C|$CP|\})))(tex2html|verbatim)_code(\}|\3)\n?//gm;
+
+    #take care not to concatenate \<cmd> with following letters
+    local($tmp);
+    s/(\\\w+)?$tex2html_wrap_rx([^\\\n])?/$tmp=$2;
+        ((($tmp eq 'end')&&($1)&&!($5)&&($6))? "$1 $6":"$1$5$6")/egs;
+    undef $tmp;
+    s/\s*\\newedcommand\s*{/"%\n\\providecommand{\\"/gem;
+    s/\\newedcommand\s*{/\\providecommand{\\/gom;
+#    s/(\n*)\\renewedcommand{/($1? "\n":'')."\\renewcommand{\\"/geo;
+    s/\s*\\providedcommand\s*{/"%\n\\providecommand{\\"/gem;
+#    s/\\providedcommand{/\\providecommand{\\/go;
+    s/\\renewedenvironment\s*/\\renewenvironment/gom;
+    s/\\newedboolean\s*{/\\newboolean{/gom;
+    s/\\newedcounter\s*{/\\newcounter{/gom;
+    s/\\newedtheorem\s*{/\\newtheorem{/gom;
+    s/\\xystar/\\xy\*/gom; # the * has a special meaning in Xy-pic
+
+    #fix-up the star'd environment names
+    s/(\\(begin|end)(($O|$OP)\d+($C|$CP))[^<]*)star\3/$1\*$3/gm;
+    s/(\\(begin|end)\{[^\}]*)star\}/$1\*\}/gm;
+    s/\\(begin|end)\{[^\}]*begin(group)\}/\\$1$2/gm;
+    s/\\(b|e)(egin|end)\{[^\}]*b(group)\}/\\$1$3/gm;
+
+    s/(\\(\w+)TeX)/($language_translations{$2}? "\\selectlanguage{$2}": $1)/egom;
+
+    if ($PREPROCESS_IMAGES) {
+      while (/$pre_processor_env_rx/m) {
+       $done .= $`; $pre_env = $5; $which =$1; $_ = $';
+        if (($which =~ /begin/)&&($pre_env =~ /indica/)) {
+           ($indic, $dum) = &get_next_optional_argument;
+           $done .= "\#$indic";
+        } elsif (($which =~ /begin/)&&($pre_env =~ /itrans/)) {
+           ($indic, $dum) = &get_next_optional_argument;
+           $done .= "\#$indic";
+        } elsif (($which =~ /end/)&&($pre_env =~ /indica/)) {
+           $done .= '\#NIL';
+        } elsif (($which =~ /end/)&&($pre_env =~ /itrans/)) {
+           $done .= "\#end$indic";
+       } elsif ($which =~ /begin/) {
+           $done .= (($which =~ /end/)? $end_preprocessor{$pre_env}
+                         : $begin_preprocessor{$pre_env} )
+       }
+       $_ = $done . $_;
+      }
+    }
+    s/\\ITRANSinfo\{(\w+)\}\{([^}]*)\}/\#$1=$2/gm if $itrans_loaded;
+
+    s/\n{3,}/\n\n/gm; # remove multiple (3+) new-lines 
+    s/^\n+$//gs; # ...especially if that is all there is!
+    if ($PREAMBLE) {
+       s/$comment_mark(\d+\n?)?//g;
+#      $preamble =~ s/\\par\n?/\n/g;
+       s/\\par\b/\n/g;
+       s/^\s*$//g; #remove blank lines in the preamble
+    };
+
+    s/($html_specials_inv_rx)/$html_specials_inv{$1}/geo;
+    # revert entities to TeX code, except if in {rawhtml} environments
+    if (!($env =~ /rawhtml/)) {
+        s/$character_entity_rx/( $character_map ?
+         eval "\$${character_map}_character_map_inv\{\"$1\"\}" :
+           $iso_8859_1_character_map_inv{$1} ||
+             $iso_10646_character_map_inv{$1})/geo;
+        s/$named_entity_rx/( $character_map ? 
+         eval "\$${character_map}_character_map_inv\{\$${character_map}_character_map{'$1'}}" :
+           $iso_8859_1_character_map_inv{$iso_8859_1_character_map{$1}} ||
+             $iso_10646_character_map_inv{$iso_10646_character_map{$1}})/geo;
+
+    } else {
+        #RRM: check for invalid named entities in {rawhtml} environments
+       s/($named_entity_rx)/&write_warnings(
+           "An unknown named entity ($1) appears in the source text.") unless (
+                $character_map && eval 
+         "\$${character_map}_character_map_inv\{\$${character_map}_character_map{'$2'}}");
+                    ";SPM$2;"/ego;
+    }
+
+    #RRM: check for numbered character entity out-of-range
+    if ($HTML_VERSION < 4.0) {
+       s/$character_entity_rx/&write_warnings(
+           "An invalid character entity ($1) appears in the source text.")
+            if ($2 > 255);
+       $1/ego; }
+
+    #RRM: check for invalid named entities outside {rawhtml} environments
+    # --- these should have been caught already, but check again
+    s/$named_entity_rx/&write_warnings(
+           "An unknown named entity ($1) appears in the source text.") unless (
+       $character_map && eval 
+         "\$${character_map}_character_map_inv\{\$${character_map}_character_map{'$1'}}");
+                    $1/ego;
+
+    &revert_to_raw_tex_hook if (defined &revert_to_raw_tex_hook);
+    $_;
+}
+
+sub next_wrapper {
+    local($dollar) = @_;
+    local($_,$id);
+    $wrap_toggle = (($wrap_toggle eq 'end') ? 'begin' : 'end');
+    $id = ++$global{'max_id'};
+    $_ = "\\$wrap_toggle$O$id$C"."tex2html_wrap$O$id$C";
+    $_ = (($wrap_toggle eq 'end') ? $dollar.$_ : $_.$dollar);
+    $_;
+}
+
+sub make_wrapper {
+    &make_any_wrapper($_[0], '', "tex2html_wrap");
+}
+
+sub make_nowrapper {
+    &make_any_wrapper($_[0], 1, "tex2html_nowrap");
+}
+
+sub make_inline_wrapper {
+    &make_any_wrapper($_[0], '', "tex2html_wrap_inline");
+}
+
+sub make_deferred_wrapper {
+    &make_any_wrapper($_[0], 1, "tex2html_deferred");
+}
+
+sub make_nomath_wrapper {
+    &make_any_wrapper($_[0], '', "tex2html_nomath_inline");
+}
+
+sub make_any_wrapper {
+    local($toggle,$break,$kind) = @_;
+    local($max_id) = ++$global{'max_id'};
+    '\\'. (($toggle) ? 'begin' : 'end')
+       . "$O$max_id$C"."$kind$O$max_id$C"
+       . (($toggle || !$break) ? '' : '');
+}
+
+sub get_last_word {
+    # Returns the last word in multi-line strings
+    local($_) = @_;
+    local ($word,$lastbit,$which);
+#JCL(jcl-tcl)
+# also remove anchors and other awkward HTML markup
+#    &extract_pure_text("strict");
+##    $_ = &purify($_);  ## No. what if it is a verbatim string or image?
+#
+#    while (/\s(\S+)\s*$/g) { $word = $lastbit = $1;}
+
+    if (!$_ && (defined $keep)) {
+       # inside mathematics !
+       $_ = $keep . $pre ;
+    }
+    if (!$_ && $ref_before) { $_ = $ref_before; }
+    elsif (!$_) {
+       # get it from last thing before the current environment
+       $which = $#processedE;
+       $_ = $processedE[$which];
+    }
+
+    while (/((($O|$OP)\d+($C|$CP))[.\n]*\2|\s(\S+))\s*$/g)
+       { $word = $lastbit = $1 }
+    if (($lastbit =~ s/\$\s*$//)||(defined $keep)) {
+       local($br_idA) = ++$global{'max_id'};
+       local($br_idB) = ++$global{'max_id'};
+       $lastbit = join('', "\\begin $O$br_idA${C}tex2html_wrap_inline$O$br_idA$C\$"
+               , $lastbit, "\$\\end $O$br_idB${C}tex2html_wrap_inline$O$br_idB$C");
+       $lastbit = &translate_environments($lastbit);
+       $lastbit = &translate_commands($lastbit);
+       return ($lastbit);
+    }
+    if ($lastbit =~ s/($O|$OP)\d+($C|$CP)//g) { return ($lastbit); }
+    elsif ($lastbit eq '') { return ($_) }
+
+    local($pre_bit);
+    if ($lastbit =~/>([^>]*)$/) { 
+       $word = $1; $pre_bit = $`.'>';
+       if ($pre_bit =~ /($verb_mark|$verbstar_mark)$/) {
+           $word = $lastbit;
+       } elsif ($pre_bit =~ /<\w+_mark>$/) {
+           $word = $& . $word;
+       } elsif (!($word)) {
+           if ($lastbit =~ s/<([^\/][^>]*)>$//o)
+               { $word=$1; $pre_bit = $`; }
+           elsif ($lastbit =~ s/>([^<]*)<\/[^>]*>//o)
+               { $word=$1; $pre_bit = $`.'>' }
+           else { $word = ";SPMnbsp;"; }
+       }
+#      if ($pre_bit =~ /<\w+_mark>$/) { $word = $& . $word }
+     } else { $word = $lastbit };
+    $word;
+}
+
+#JCL(jcl-tcl)
+# changed completely
+#
+# We take the first real words specified by $min from the string.
+# Allow for simple HTML constructs like <I>...</I> (but not <H*>
+# or <P*> and the like), math, or images to remain in the result,
+# not counting as words.
+# Take care that eg. <I>...</I> grouping tags are not broken.
+# This is achieved by lifting the markup, removing superfluous
+# words, re-inserting the markup, and throw empty markup away.
+# In later versions images could be modified such that they become
+# thumbnail sized.
+#
+# rawhtml or verbatim environments might introduce lots of awkward
+# stuff, but yet we leave the according tex2html markers in.
+#
+sub get_first_words {
+    local($_, $min) = @_;
+    local($words,$i);
+    local($id,%markup);
+    #no limit if $min is negative
+    $min = 1000 if ($min < 0);
+
+    &remove_anchors;
+    #strip unwanted HTML constructs
+    s/<\/?(P|BR|H)[^>]*>/ /g;
+    #remove leading white space and \001 characters
+    s/^\s+|\001//g;
+    #lift html markup, numbered for recovery
+    s/(<[^>]*>(#[^#]*#)?)/$markup{++$id}=$1; "\000$id\000"/ge;
+
+    foreach (split /\s+|\-{3,}/) {
+        # count words (incl. HTML markup as part of the word)
+        ++$i; 
+#      $words .= $_ . " " if (/\000/ || ($i <= $min));
+       $words .= $_ . " " if ($i <= $min);
+    }
+    $_ = $words;
+    chop;
+
+    #re-insert markup
+    s/\000(\d+)\000/$markup{$1}/g;
+    # remove empty markup
+    # it's normalized, because generated by LaTeX2HTML only
+    s/<([A-Z]+)[^>]*>\s*<\/\1>\s*//g;
+    $_;
+}
+
+sub replace_word {
+    # Replaces the LAST occurrence of $old with $new in $str;
+    local($str, $old, $new) = @_;
+    substr($str,rindex($str,$old),length($old)) = $new;
+    $str;
+}
+
+# Returns the recognised sectioning commands as a string of alternatives
+# for use in regular expressions;
+sub get_current_sections {
+    local($_, $key);
+    foreach $key (keys %section_commands) {
+       if ($key =~ /star/) {
+           $_ = $key . "|" . $_}
+       else {
+           $_ .= "$key" . '[*]?|';
+       }
+    }
+    chop;                      # Remove the last "|".
+    $_;
+}
+
+sub numerically {
+    local(@x) = split(' ',$a);
+    local(@y) = split(' ',$b);
+    local($i, $result);
+    for($i=0;$i<$#x;$i++) {
+       last if ($result = ($x[$i] <=> $y[$i]));
+    }
+    $result
+}
+
+# Assumes that the files to be sorted are of the form
+# <NAME><NUMBER>
+sub file_sort {
+    local($i,$j) = ($a,$b);
+    $i =~ s/^[^\d]*(\d+)$/$1/;
+    $j =~ s/^[^\d]*(\d+)$/$1/;
+    $i <=> $j
+}
+
+# If a normalized command name exists, return it.
+sub normalize {
+    # MRO: modified to use $_[1]
+    # local($cmd,*after) = @_;
+    my $cmd =$_[0];
+    my $ncmd;
+    # Escaped special LaTeX characters
+    if ($cmd =~ /^($latex_specials_rx)/) {
+#      $cmd =~ s/&(.*)$/&amp;$1/o;
+       $cmd =~ s/&(.*)$/$ampersand_mark$1/o;
+        $cmd =~ s/%/$percent_mark/o;
+       $_[1] = join('', $cmd, $_[1]);
+       $cmd = ""}
+    elsif ($ncmd = $normalize{$cmd}) {
+       $ncmd;
+    }
+    else {
+       $cmd =~ s/[*]$/star/;
+       $cmd =~ s/\@/_at_/g;
+       $cmd;
+    }
+}
+
+sub normalize_sections {
+    my $dummy = '';
+    # MRO: s/$sections_rx/'\\' . &normalize($1.$2,*after) . $4/ge;
+    s/$sections_rx/'\\' . &normalize($1.$2,$dummy) . $4/ge;
+}
+
+sub embed_image {
+    my ($url,$name,$external,$altst,$thumbnail,$map,$align,
+       $usemap,$exscale,$exstr) = @_;
+    my $imgID = '';
+    my $urlimg = $url;
+    my $ismap = $map ? " ISMAP" : '';
+    print "\nembedding $url for $name, with $altst\n" if ($VERBOSITY > 1);
+
+    if (! ($NO_IMAGES || $PS_IMAGES)) {
+       # for over-scaled GIFs with pre-determined sizes        # RRM 11-9-96
+        my $size;
+       if (($width{$name})&&(($exscale)||($EXTRA_IMAGE_SCALE))) {
+           $exscale = $EXTRA_IMAGE_SCALE unless ($exscale);
+           if ($name =~ /inline|indisplay|entity|equation|math|eqn|makeimage/){
+               ($size, $imgID) = &get_image_size($url, $exscale);
+           } else {
+               ($size, $imgID) = &get_image_size($url,'');
+           }
+       } else {
+           ($size,$imgID) = &get_image_size($url,'');
+       }
+       $image_size{$url} = $size 
+           unless ((! $size) || ($size eq "WIDTH=\"0\" HEIGHT=\"0\""));
+       $url = &find_unique($url);
+    }
+
+    $urlimg = $url;
+    $urlimg =~ s/\.$IMAGE_TYPE$/.html/ if ($map);
+    if ($exstr =~ s/align\s*=\s*(\"?)(\w+)\1($|\s|,)//io) { $align = $2; }
+    my $usersize = '';
+    if ($exstr =~ s/width\s*=\s*(\"?)([^\s,]+)\1($|\s|,)//io) {
+       my ($pxs,$len) = &convert_length($2);
+       $usersize = " WIDTH=\"$pxs\"";
+    }
+    if ($exstr =~ s/height\s*=\s*(\"?)([^\s,]+)\1($|\s|,)//io) { 
+       my ($pxs,$len) = &convert_length($2);
+       $usersize .= " HEIGHT=\"$pxs\"";
+    }
+
+    my $border = '';
+    $border = "\" BORDER=\"0"
+       unless (($HTML_VERSION < 2.2 )||($exstr =~ /BORDER/i));
+
+    my $aalign;
+    if (($name =~ /figure|table|displaymath\d+|eqnarraystar/)&&(!$align)) {
+    } elsif ($name =~ /displaymath_/) {
+       $aalign = "MIDDLE".$border;
+    } elsif (($name =~ /(equation|eqnarray)($|\d)/)&&(!$align)) {
+       if ($HTML_VERSION >= 3.2) {
+           $aalign =  ($EQN_TAGS eq "L") ? "RIGHT" : "LEFT";
+       }
+    } elsif ($name =~ /inline|display|entity|xy|diagram/ && $depth{$name} != 0) {
+       $aalign = "MIDDLE".$border;
+    } elsif ($name =~ /inpar/m) {
+       $aalign = "TOP".$border;
+    } else {  $aalign = "BOTTOM".$border }
+
+    $aalign = "\U$align" if $align;
+    my $ausemp = $usemap ? "\UUSEMAP=$usemap" : '';
+
+    #append any extra valid options 
+    $ismap .= &parse_keyvalues ($exstr, ("IMG")) if ($exstr);
+
+    $altst = '' if ($ismap =~ /(^|\s+)ALT\s*=/);
+    if ($altst) {
+       if ($altst =~ /\s*ALT="?([^\"]+)"?\s*/io) { $altst=$1 }
+       $altst =~ s/[<>"&]/'&'.$html_special_entities{$&}.';'/eg;
+       $altst = "\n ALT=\"$altst\"";
+    }
+
+    my ($extern_image_mark,$imagesize);
+    if ($thumbnail) {
+       print "\nmaking thumbnail" if ($VERBOSITY > 1);
+       if (($image_size{$thumbnail}) = &get_image_size($thumbnail,'')) {
+           $thumbnail = &find_unique($thumbnail);
+           $imagesize = " ".$image_size{$thumbnail};
+           if ($HTML_VERSION < 2.2 ) {
+               # put the WIDTH/HEIGHT information into the ALT string
+               # first removing the quotes
+               my ($noquotes) = $imagesize;
+               $noquotes =~ s/\"//g;
+               $altst =~ s/"$/\% $noquotes "/m;
+               $imagesize = '';
+           }
+           $extern_image_mark = join('',"<IMG"
+               , "\n$imagesize" 
+               , (($aalign) ? " ALIGN=\"$aalign\"" : '')
+               , ("$aalign$imagesize" ? "\n" : '' )
+               , " SRC=\"$thumbnail\"$altst>");
+       }
+       $extern_image_mark =~ s/\s?BORDER="?\d+"?//
+            unless ($exstr =~ /BORDER/i);
+    } else { 
+        # MRO: dubious (&extern_image_mark takes only one arg)
+        $extern_image_mark = &extern_image_mark($IMAGE_TYPE,$altst);
+    }
+
+    my ($anch1,$anch2) = ('','');
+    my $result;
+    if ($external || $thumbnail || $EXTERNAL_IMAGES) {
+       if ( $extern_image_mark ) {
+           $result = &make_href_noexpand($urlimg, $name , $extern_image_mark);
+           &save_image_map($url, $urlimg, $map, $name, $altst, $ausemp) if $map;
+       }
+    } else {
+       if ($map) {
+           $anch1 = "<A HREF=\"$map\">";
+           $anch2 = "</A>";
+       }
+#      if ($aalign eq "CENTER") {
+#          if ($HTML_VERSION eq "2.0") {
+#              $anch1 .= "\n<P ALIGN=\"CENTER\">";
+#              $anch2 .= "</P>";
+#          } else {
+#              $anch1 .= "\n<DIV ALIGN=\"CENTER\">";
+#              $anch2 .= "</DIV>";
+#          }
+#      }
+
+       $imagesize = $image_size{$url};
+       $imagesize = $usersize if (($usersize)&&($HTML_VERSION > 2.1 ));
+       if ($HTML_VERSION < 2.2 ) {
+           # put the WIDTH/HEIGHT information into the ALT string
+           # first removing the quotes
+           my ($noquotes) = $imagesize;
+           $noquotes =~ s/\"//g;
+           $altst =~ s/"$/\% $noquotes "/m;
+       }
+
+       # include a stylesheet entry for each included image
+       if ($USING_STYLES && $SCALABLE_IMAGES &&(!$imgID)) {
+           if ($url =~ /($dd|^)([^$dd$dd]+)\.$IMAGE_TYPE$/) {
+               my $img_name = $2;
+               $imgID = $img_name . ($img_name =~ /img/ ? '' : $IMAGE_TYPE);
+               $img_style{"$imgID"} = ' ' unless $img_style{"$imgID"};
+               $imgID = join('', ' CLASS="', $imgID, '"') if $imgID;
+           }
+       }
+
+       ### MEH Add width and height to IMG
+       ### Patched by <hswan@perc.Arco.com>:  Fixed \htmladdimg 
+       if ( $imagesize || $name eq "external image" || $NO_IMAGES || $PS_IMAGES) {
+           $imagesize = '' if ($HTML_VERSION < 2.2 );
+           if ($border =~ s/^"//) { $border .= '"' };
+           $result = join(''
+                  , "<IMG$imgID"
+                  , "\n", ($imagesize ? " $imagesize" : '')
+                  , (($aalign)? " ALIGN=\"$aalign\"" : $border)
+                  , $ismap );
+           if ($ausemp) { $result .= " $ausemp" }
+           $result .= "\n" unless (($result =~ /\n *$/m)|| !$imagesize);
+           $result .= " SRC=\"$url\"";
+           if ($altst) { $result .= $altst }
+           $result .= ">";
+       }
+    }
+    join('',$anch1, $result, $anch2);
+}
+
+# MRO: added PNG support
+sub get_image_size { # clean
+    my ($imagefile, $scale) = @_;
+
+    $scale = '' if ($scale == 1);
+    my ($imgID,$size) = ('','');
+    if (open(IMAGE, "<$imagefile")) {
+        my ($buffer,$magic,$dummy,$width,$height) = ('','','',0,0);
+       binmode(IMAGE); # not harmful un UNIX
+        if ($IMAGE_TYPE =~ /gif/) {
+           read(IMAGE,$buffer,10);
+           ($magic,$width,$height) = unpack('a6vv',$buffer);
+            # is this image sane?
+           unless($magic =~ /^GIF8[79]a$/ && ($width * $height) > 0) {
+                $width = $height = 0;
+           }
+        }
+        elsif ($IMAGE_TYPE =~ /png/) {
+            read(IMAGE,$buffer,24);
+           ($magic,$dummy,$width,$height) = unpack('a4a12NN',$buffer);
+           unless($magic eq "\x89PNG" && ($width * $height) > 0) {
+                $width = $height = 0;
+            }
+       }
+       close(IMAGE);
+
+       # adjust for non-trivial $scale factor.
+        my ($img_w,$img_h) = ($width,$height);
+       if ($scale && ($width * $height) > 0) {
+            $img_w = int($width / $scale + .5);
+            $img_h = int($height / $scale + .5);
+       }
+       $size = qq{WIDTH="$img_w" HEIGHT="$img_h"};
+
+       # allow height/width to be stored in the stylesheet
+       my ($img_name,$imgID);
+       if ($SCALABLE_IMAGES && $USING_STYLES) {
+           if ($imagefile =~ /(^|[$dd$dd])([^$dd$dd]+)\.(\Q$IMAGE_TYPE\E|old)$/o) {
+               $img_name = $2;
+               $imgID = $img_name . ($img_name =~ /img/ ? '' : $IMAGE_TYPE);
+           }
+           if ($imgID) {
+               $width = $width/$LATEX_FONT_SIZE/$MATH_SCALE_FACTOR;
+               $height = 1.8 * $height/$LATEX_FONT_SIZE/$MATH_SCALE_FACTOR;
+               # How wide is an em in the most likely browser font ?
+               if ($scale) {
+               # How high is an ex in the most likely browser font ?
+                   $width = $width/$scale; $height = $height/$scale;
+               }
+               $width = int(100*$width + .5)/100;
+               $height = int(100*$height + .5)/100;
+               $img_style{$imgID} = qq(width:${width}em ; height:${height}ex );
+               #join('','width:',$width,'em ; height:',$height,'ex ');
+               $imgID = qq{ CLASS="$imgID"};
+           }
+       }
+    }
+    ($size, $imgID);
+}
+
+sub find_unique { # clean
+    my ($image1) = @_;
+    local($/) = undef; # slurp in complete files
+
+    my $imagedata;
+    if(open(IMG1,"<$image1")) {
+       binmode(IMG1); # needed with .png under DOS
+        $imagedata = <IMG1>;
+        close(IMG1);
+    } else {
+        print "\nError: Cannot read '$image1': $!\n"
+           unless ($image1 =~ /^\s*$HTTP_start/i);
+        return $image1;
+    }
+
+    my ($image2,$result);
+    foreach $image2 (keys(%image_size)) {
+       if ( $image1 ne $image2 &&
+           $image_size{$image1} eq $image_size{$image2} ) {
+           if(open(IMG2,$image2)) {
+               binmode(IMG2); # needed with .png under DOS
+               $result = ($imagedata eq <IMG2>);
+               close(IMG2);
+            } else {
+                print "\nWarning: Cannot read '$image2': $!\n"
+                   unless ($image2 =~ /^\s*$HTTP_start/i);
+            }
+#
+#  If we've found a match, rename the new image to a temporary one.
+#  Then try to link the new name to the old image.
+#  If the link fails, restore the temporary image.
+#
+           if ( $result ) {
+               my $tmp = "temporary.$IMAGE_TYPE";
+               L2hos->Unlink($tmp);
+               L2hos->Rename($image1, $tmp);
+               if (L2hos->Link($image2, $image1)) {
+                    L2hos->Unlink($tmp);
+                } else {
+                    L2hos->Rename($tmp, $image1);
+                }
+               return $image1;
+           }
+       }
+    }
+    $image1;
+}
+
+sub save_image_map { # clean
+    my ($url, $urlimg, $map, $name, $altst, $ausemp) = @_;
+    unless(open(IMAGE_MAP, ">$urlimg")) {
+        print "\nError: Cannot write '$urlimg': $!\n";
+        return;
+    }
+    ### HWS  Pass server map unchanged from user
+    print IMAGE_MAP "<HTML>\n<BODY>\n<A HREF=\"$map\">\n";
+    print IMAGE_MAP "<IMG\n SRC=\"$url\" ISMAP $ausemp $altst> </A>";
+    print IMAGE_MAP "</BODY>\n</HTML>\n";
+    close IMAGE_MAP;
+}
+
+#  Subroutine used mainly to rename an old image file about to recycled.
+#  But for active image maps, we must edit the auxiliary HTML file to point
+#     to the newly renames image.
+sub rename_html {
+    local ($from, $to) = @_;
+    local ($from_prefix, $to_prefix, $suffix);
+    ($from_prefix, $suffix) = split(/\./, $from);
+    ($to_prefix, $suffix) = split(/\./, $to);
+    if ($EXTN =~ /$suffix$/) {
+       if (open(FROM, "<$from") && open(HTMP, ">HTML_tmp")) {
+           while (<FROM>) {
+               s/$from_prefix\.$IMAGE_TYPE/$to_prefix.$IMAGE_TYPE/g;
+               print HTMP;
+           }
+           close (FROM);
+           close (HTMP);
+           L2hos->Rename ("HTML_tmp", $to);
+           L2hos->Unlink($from) unless ($from eq $to);
+       }
+       else {
+           &write_warnings("File $from is missing!\n");
+       }
+    }
+    L2hos->Rename("$from_prefix.old", "$to_prefix.$IMAGE_TYPE");
+    $to;
+}
+
+sub save_captions_in_file {
+    local ($type, $_) = @_;
+    if ($_) {
+       s/^\n//om;
+       &replace_markers;
+       &add_dir_to_href if ($DESTDIR);
+       if(open(CAPTIONS, ">${PREFIX}$type.pl")) {
+           print CAPTIONS $_;
+           close (CAPTIONS);
+        } else {
+            print "\nError: Cannot write '${PREFIX}$type.pl': $!\n";
+        }
+    }
+}
+
+sub add_dir_to_href {
+    $_ =~ s/'/\\'/g;
+    $_ =~ s/(<LI><A )(NAME\=\"tex2html\d+\")?\s*(HREF=\")/$1$3\'.\$dir.\'/og;
+    $_ = join('', "\'", $_, "\'\n");
+}
+
+sub save_array_in_file {
+    local ($type, $array_name, $append, %array) = @_;
+    local ($uutxt,$file,$prefix,$suffix,$done_file,$depth,$title);
+    $prefix = $suffix = "";
+    my $filespec = ($append ? '>>' : '>') . "${PREFIX}$type.pl";
+    $prefix = q("$URL/" . )
+       if ($type eq "labels") && !($array_name eq "external\_latex\_labels");
+    $suffix = " unless (\$$array_name\{\$key\})"
+       if (($type =~ /(sections|contents)/)||($array_name eq "printable\_key"));
+    if ((%array)||($type eq "labels")) {
+       print "\nSAVE_ARRAY:$array_name in FILE: ${PREFIX}$type.pl"
+           if ($VERBOSITY > 1);
+       unless(open(FILE,$filespec)) {
+            print "\nError: Cannot write '${PREFIX}$type.pl': $!\n";
+            return;
+        }
+       if (($array_name eq "sub\_index") || ($array_name eq "printable\_key")) {
+           print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n";
+           print FILE "# Printable index-keys from $array_name array.\n\n";
+       } elsif ($array_name eq "index\_labels") {
+           print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n";
+           print FILE "# labels from $array_name array.\n\n";
+       } elsif ($array_name eq "index\_segment") {
+           print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n";
+           print FILE "# segment identifier from $array_name array.\n\n";
+       } elsif ($array_name eq "external\_latex\_labels") {
+           print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n";
+           print FILE "# labels from $array_name array.\n\n";
+       } else {
+           print FILE "# LaTeX2HTML $TEX2HTMLVERSION\n";
+           print FILE "# Associate $type original text with physical files.\n\n";
+       }
+       while (($uutxt,$file) = each %array) {
+           $uutxt =~ s|/|\\/|g;
+           $uutxt =~ s|\\\\/|\\/|g;
+
+           if (!($array_name =~/images/)&&($file =~ /</)) {
+               do { local $_ = $file;
+                    &replace_markers;
+                    $file = $_; undef $_;
+                    $file =~ s/(\G|[^q])[\\\|]\|/$1\\Vert/sg;
+                    $file =~ s/(\G|[^q])\|/$1\\vert/sg;
+               };
+           }
+
+           local ($nosave);    
+           if ($MULTIPLE_FILES && $ROOTED && 
+                   $type =~ /(sections|contents)/) {
+               #RRM: save from $THIS_FILE only
+               if ( $uutxt =~ /^$THIS_FILE /) {
+                   #RRM: save from $THIS_FILE only
+                   $nosave = ''
+               } else { $nosave = 1 }
+           } else {
+               #RRM: suppress info from other segments
+               $nosave = $noresave{$uutxt}; 
+           }
+
+           if (!$nosave && ($file ne ''))  {
+               print FILE "\n\$key = q/$uutxt/;\n";
+
+               $file =~ s/\|/\\\|/g; # RRM:  escape any occurrences of |
+               $file =~ s/\\\\\|/\\\|/g; # unless already escaped as \|
+               $file =~ s|\\\\|\\\\\\\\|g;
+               $file =~ s/(SRC=")($HTTP_start)?/$1.($2 ? '' :"|.\"\$dir\".q|").$2/seg;
+#
+#
+# added code for  $dir  with segmented docs;  RRM  15/3/96
+#
+               if ($type eq "contents") {
+                   ($depth, $done_file) = split($delim, $file, 2 );
+                   next if ($depth > $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH);
+                   print FILE 
+    "\$$array_name\{\$key\} = '$depth$delim'.\"\$dir\".q|$done_file|$suffix; \n";
+
+               } elsif ($type eq "sections") {
+                   ($depth, $done_file) = split($delim, $file, 2 );
+                   next if ($depth > $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH);
+                   print FILE 
+    "\$$array_name\{\$key\} = '$depth$delim'.\"\$dir\".q|$done_file|$suffix; \n";
+
+               } elsif ($type eq "internals") {
+                   print FILE 
+    "\$$array_name\{\$key\} = \"\$dir\".q|$file|$suffix; \n";
+
+               } elsif ($array_name eq "sub_index") {
+                   print FILE
+    "\$$array_name\{\$key\} .= q|$file|$suffix; \n";
+
+               } elsif ($array_name eq "index") {
+                   local($tmp_file) = '';
+                   ($depth, $done_file) = split('HREF=\"', $file, 2 );
+                   if ($done_file) {
+                       while ($done_file) {
+                           $depth =~ s/\s*$/ / if ($depth);
+                           $tmp_file .= "q|${depth}HREF=\"|.\"\$dir\".";
+                           ($depth, $done_file) = split('HREF=\"', $done_file, 2 );
+                       }
+                       print FILE
+    "\$$array_name\{\$key\} .= ${tmp_file}q|$depth|$suffix; \n";
+
+                   } else {
+                       print FILE
+    "\$$array_name\{\$key\} .= q|$file|$suffix; \n";
+                   }
+               } elsif ($array_name eq "printable_key") {
+                   print FILE
+    "\$$array_name\{\$key\} = q|$file|$suffix; \n";
+
+               } else {
+                   print FILE
+    "\$$array_name\{\$key\} = ${prefix}q|$file|$suffix; \n";
+               }
+
+               if ($type =~ /(figure|table|images)/) {} else {
+                   print FILE "\$noresave\{\$key\} = \"\$nosave\";\n";
+               }
+
+               if ($type eq "sections") {
+                   ($depth, $done_file, $title) = split($delim, $file);
+                   print FILE "\$done\{\"\$\{dir\}$done_file\"\} = 1;\n";
+               }
+           }
+       }
+       print FILE "\n1;\n\n"  unless  ( $array_name =~ /index/ );
+       close (FILE);
+    } else {
+       print "\nSAVE_FILE:$array_name: ${PREFIX}$type.pl  EMPTY " if ($VERBOSITY > 1);
+    }
+}
+
+# returns true if $AUTO_NAVIGATION is on and there are more words in $_
+# than $WORDS_IN_PAGE
+sub auto_navigation {
+    # Uses $_;
+    local(@tmp) = split(/\W*\s+\W*/, $_);
+    ($AUTO_NAVIGATION && ( (scalar @tmp) > $WORDS_IN_PAGE));
+}
+
+# Returns true if $f1 is newer than $f2
+sub newer {
+    ($f1,$f2) = @_;
+    local(@f1s) = stat($f1);
+    local(@f2s) = stat($f2);
+    ($f1s[9] > $f2s[9]);
+};
+
+sub iso_map {
+    local($char, $kind, $quiet) = @_;
+    my($character_map,$enc);
+    local ($this);
+
+    if ( $CHARSET && $HTML_VERSION ge "2.1" ) {
+       # see if it is a character in the charset
+       $character_map = ((($charset =~ /utf/)&&!$NO_UTF)?
+                         'iso_10646' : $CHARSET );
+       $character_map =~ tr/-/_/;
+       eval "\$enc = \$${character_map}_character_map\{\"$char$kind\"\}";
+       print "\n no support for $CHARSET: $@ " if ($@);
+    }
+    if ($USE_ENTITY_NAMES && $enc) { return(";SPM$char$kind;") }
+
+    if ($enc) {
+       $enc =~ /^\&\#(\d{3});$/;
+       # maybe convert it to an 8-bit character
+       if ($NO_UTF && !$USE_UTF && ($1<=255)) { $enc = chr($1) }
+#      elsif (!$USE_UTF &&($1>127)&&($1<160)) { $enc = chr($1) }
+       elsif ($character_map !~ /^iso_(8859_1|10646)/) {
+       # get its latin1 or unicode entity encoding
+           $enc = $iso_8859_1_character_map{"$char$kind"}
+               ||$iso_8859_1A_character_map{"$char$kind"}
+               ||$iso_10646_character_map{"$char$kind"}
+       }
+     } else {
+       # get its latin1 or unicode entity encoding, if available
+       $enc = $iso_8859_1_character_map{"$char$kind"}
+           ||$iso_8859_1A_character_map{"$char$kind"}
+           ||$iso_10646_character_map{"$char$kind"};
+    }
+
+    if ($enc) {
+       $ISOLATIN_CHARS = 1; $enc;
+    } elsif (!$image_made{"$char$kind"}) {
+       print "\ncouldn't convert character $char$kind into available encodings"
+           if (!quiet &&($VERBOSITY > 1));
+       &write_warnings(
+           "couldn't convert character $char$kind into available encodings"
+           . ($ACCENT_IMAGES ? ', using image' : '')) unless ($quiet);
+       $image_made{"$char$kind"} = 1;
+       '';
+    } else {''}
+}
+
+sub titles_language {
+    local($_) = @_;
+    local($lang) = $_ . "_titles";
+    if (defined(&$lang)) { &$lang }
+    else {
+       &english_titles;
+       &write_warnings(
+           "\nThere is currently no support for the $tmp language." .
+           "\nSee the file $CONFIG_FILE for examples on how to add it\n\n");
+    }
+}
+
+sub translate_titles {
+    $toc_title = &translate_commands($toc_title) if ($toc_title =~ /\\/);
+    $lof_title = &translate_commands($lof_title) if ($lof_title =~ /\\/);
+    $lot_title = &translate_commands($lot_title) if ($lot_title =~ /\\/);
+    $idx_title = &translate_commands($idx_title) if ($idx_title =~ /\\/);
+    $ref_title = &translate_commands($ref_title) if ($ref_title =~ /\\/);
+    $bib_title = &translate_commands($bib_title) if ($bib_title =~ /\\/);
+    $abs_title = &translate_commands($abs_title) if ($abs_title =~ /\\/);
+    $app_title = &translate_commands($app_title) if ($app_title =~ /\\/);
+    $pre_title = &translate_commands($pre_title) if ($pre_title =~ /\\/);
+    $foot_title = &translate_commands($foot_title) if ($foot_title =~ /\\/);
+    $fig_name = &translate_commands($fig_name) if ($fig_name =~ /\\/);
+    $tab_name = &translate_commands($tab_name) if ($tab_name =~ /\\/);
+    $prf_name = &translate_commands($prf_name) if ($prf_name =~ /\\/);
+    $page_name = &translate_commands($page_name) if ($page_name =~ /\\/);
+    $child_name = &translate_commands($child_name) if ($child_name =~ /\\/);
+    $info_title = &translate_commands($info_title) if ($info_title =~ /\\/);
+    $part_name = &translate_commands($part_name) if ($part_name =~ /\\/);
+    $chapter_name = &translate_commands($chapter_name)
+       if ($chapter_name =~ /\\/);
+    $section_name = &translate_commands($section_name)
+       if ($section_name =~ /\\/);
+    $subsection_name = &translate_commands($subsection_name)
+       if ($subsection_name =~ /\\/);
+    $subsubsection_name = &translate_commands($subsubsection_name)
+       if ($subsubsection_name =~ /\\/);
+    $paragraph_name = &translate_commands($paragraph_name)
+       if ($paragraph_name =~ /\\/);
+    $see_name = &translate_commands($see_name) if ($see_name =~ /\\/);
+    $also_name = &translate_commands($also_name) if ($also_name =~ /\\/);
+    $next_name = &translate_commands($next_name) if ($next_name =~ /\\/);
+    $prev_name = &translate_commands($prev_name) if ($prev_name =~ /\\/);
+    $up_name = &translate_commands($up_name) if ($up_name =~ /\\/);
+    $group_name = &translate_commands($group_name) if ($group_name =~ /\\/);
+    $encl_name = &translate_commands($encl_name) if ($encl_name =~ /\\/);
+    $headto_name = &translate_commands($headto_name) if ($headto_name =~ /\\/);
+    $cc_name = &translate_commands($cc_name) if ($cc_name =~ /\\/);
+    $default_title = &translate_commands($default_title)
+       if ($default_title =~ /\\/);
+}
+####################### Code Generation Subroutines ############################
+# This takes a string of commands followed by optional or compulsory
+# argument markers and generates a subroutine for each command that will
+# ignore the command and its arguments.
+# The commands are separated by newlines and have the format:
+##      <cmd_name>#{}# []# {}# [] etc.
+# {} marks a compulsory argument and [] an  optional one.
+sub ignore_commands {
+    local($_) = @_;
+    foreach (/.*\n?/g) {
+       s/\n//g;
+       # For each line
+       local($cmd, @args) = split('\s*#\s*',$_);
+       next unless $cmd;
+       $cmd =~ s/ //;
+       ++$ignore{$cmd};
+       local ($body, $code, $thisone) = ("", "");
+       
+       # alter the pattern here to debug particular commands
+       $thisone = 1 if ($cmd =~ /let/);
+
+       if (@args) {
+           print "\n$cmd: ".scalar(@args)." arguments" if ($thisone);
+           # Replace the argument markers with appropriate patterns
+           foreach $arg (@args) {
+               print "\nARG: $arg" if ($thisone);
+               if ($arg =~ /\{\}/) {
+                   $body .= 'local($cmd) = '."\"$cmd\"".";\n";
+                   $body .= '$args .= &missing_braces'."\n ".'unless (';
+                   $body .= '(s/$next_pair_pr_rx/$args .= $2;\'\'/eo)'."\n";
+                   $body .= '  ||(s/$next_pair_rx/$args .= $2;\'\'/eo));'."\n";
+                   print "\nAFTER:$'" if (($thisone)&&($'));
+                   $body .= $' if ($');
+               } elsif ($arg =~ /\[\]/) {
+                   $body .= '($dummy, $pat) = &get_next_optional_argument;'
+                       . '$args .= $pat;'."\n";
+                   print "\nAFTER:$'" if (($thisone)&&($'));
+                   $body .= $' if ($');
+               } elsif ($arg =~ /^\s*\\/) {                
+                   $body .= '($dummy, $pat) = &get_next_tex_cmd;'
+                       . '$args .= $pat;'."\n";
+                   print "\nAFTER:$'" if (($thisone)&&($'));
+                   $body .= $' if ($');
+               } elsif ($arg =~ /<<\s*([^>]*)[\b\s]*>>/) {
+                   local($endcmd, $after) = ($1,$');
+                   $after =~ s/(^\s*|\s*$)//g;
+                   $endcmd = &escape_rx_chars($endcmd);
+                   $body .= 'if (/'.$endcmd.'/o) { $args .= $`; $_ = $\' };'."\n";
+                   print "\nAFTER:$after" if (($thisone)&&($after));
+                   $body .= "$after" if ($after);
+               } else {
+                   print "\nAFTER:$'" if (($thisone)&&($arg));
+                   $body .= $arg ;
+               }
+           }
+           # Generate a new subroutine
+#          $code = "sub do_cmd_$cmd {\n".'local($_) = @_;'. join('',@args) .'$_}';
+           $code = "sub do_cmd_$cmd {\n"
+               . 'local($_,$ot) = @_; '
+               . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R; '
+               . 'local($args); '
+               . "\n" . $body . (($body)? ";\n" : '')
+               . (($thisone)? "print \"\\n$cmd:\".\$args.\"\\n\";\n" : '')
+               . (($arg)? $arg : '$_') . "}";
+           print STDOUT "\n$code\n" if ($thisone); # for error-checking
+           eval ($code); # unless ($thisone);
+           print STDERR "\n\n*** sub do_cmd_$cmd failed: $@\n" if ($@);
+       } else {
+           $code = "sub do_cmd_$cmd {\n".'$_[0]}';
+           print "\n$code\n" if ($thisone); # for error-checking
+           eval ($code); # unless ($thisone);
+           print STDERR "\n\n*** sub do_cmd_$cmd failed: $@\n" if ($@);
+        }
+    }
+}
+
+
+sub ignore_numeric_argument {
+    # Chop this off
+    #RRM: 2001/11/8: beware of taking too much, when  <num> <num> 
+    local($num) = '(^|width|height|plus|minus)\s*[+-]?[\d\.]+(cm|em|ex|in|pc|pt|mm)?\s*';
+    do { s/^\s*=?\s*//so; s/^($num)*//so } unless (/^(\s*\<\<\d+\>\>|$)/);
+}
+
+sub get_numeric_argument {
+    my ($num_rx,$num) = ('','');
+    # Collect the numeric part
+    #RRM: 2001/11/8: beware of taking too much, when  <num> <num> 
+    $num_rx = '(^|width|height|plus|minus)\s*[+-]?[\d\.]+(cm|em|ex|in|pc|pt|mm)?\s*';
+    do { s/^\s*=?\s*//so; s/($num_rx)*/$num=$&;''/soe } unless (/^(\s*\<\<\d+\>\>|$)/);
+    $num;
+}
+
+sub process_in_latex_helper {
+    local($ctr,$val,$cmd) = @_;
+    ($ASCII_MODE ? "[$cmd]" : 
+       &process_in_latex("\\setcounter{$ctr}{$val}\\$cmd"))
+}
+
+sub do_cmd_catcode {
+    local($_) = @_;
+    s/^\s*[^=]+(=?\s*\d+\s|\\active)\s?//;
+    $_;
+}
+
+sub do_cmd_string {
+    local($_) = @_;
+    local($tok);
+    s/^\s*(\\([a-zA-Z]+|.)|[&;]\w+;(#\w+;)?|.)/$tok=$1;''/e;
+    if ($2) {$tok = "\&#92;$2"};
+    "$tok".$_
+}
+
+sub do_cmd_boldmath {
+    local($_) = @_;
+    $BOLD_MATH = 1;
+    $_;
+}
+
+sub do_cmd_unboldmath {
+    local($_) = @_;
+    $BOLD_MATH = 0;
+    $_;
+}
+
+sub do_cmd_lq {
+    local($_) = @_ ;
+    local($lquote);
+    # check for double quotes
+    if (s/^\s*\\lq(\b|$|[^A-Za-z])/$1/) {
+       $lquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? '``'
+               : &do_leftquotes($_));
+    } else {
+       $lquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? '`'
+               : &do_leftquote($_));
+    }
+    $lquote . $_;
+}
+
+sub do_leftquote {
+    # MRO: use $_[0] : local(*_) = @_;
+    local($quote,$lquo) = ('',($HTML_VERSION<5)? '&#8216;' : ';SPMlsquo;');
+    # select whole quotation, if \lq matches \rq
+    if ($_[0] =~ /^(.*)((\\rq\\rq|'')*)(\\rq)/) {
+       $quote = $1.$2; $_[0] = $';
+       local($rquo) = &do_rightquote();
+       &process_quote($lquo,$quote,$rquo);
+    } else { $lquo; }
+}
+
+sub do_leftquotes {
+    # MRO: use $_[0] : local(*_) = @_;
+    local($quote,$lquo) = ('',($HTML_VERSION<5)? '&#8220;' : ';SPMldquo;');
+    # select whole quotation, if \lq\lq matches \rq\rq or ''
+    if ($_[0] =~ /^(.*)(\\rq\\rq|'')/) {
+       $quote = $1; $_[0] = $';
+       local($rquo) = &do_rightquotes();
+       &process_quote($lquo,$quote,$rquo);
+    } else { $lquo; }
+}
+
+# RRM: By default this just concatenates the strings; e.g. ` <quote> '
+# This can be overridden in a html-version file
+sub process_quote { join ('', @_) }
+
+sub do_cmd_rq {
+    local($_) = @_ ;
+    local($rquote);
+    if ($_ =~ s/^\s*\\rq\b//) {
+       $rquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? "''"
+               : &do_rightquotes());
+    } else { 
+       $rquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? "'"
+               : &do_rightquote());
+    }
+    $rquote . $_;
+}
+
+sub do_rightquote { (($HTML_VERSION < 5)? '&#8217;' : ';SPMrsquo;') }
+sub do_rightquotes { (($HTML_VERSION < 5)? '&#8221;' : ';SPMrdquo;') }
+
+sub do_cmd_parbox {
+    local($_) = @_;
+    local($args, $contents, $dum, $pat);
+    $* = 1;                    # Multiline matching ON
+    ($dum,$pat) = &get_next_optional_argument; # discard this
+    ($dum,$pat) = &get_next_optional_argument; # discard this
+    ($dum,$pat) = &get_next_optional_argument; # discard this
+    $args .= $pat if ($pat);
+    $pat = &missing_braces unless (
+       (s/$next_pair_pr_rx/$pat=$2;''/eo)
+       ||(s/$next_pair_rx/$pat=$2;''/eo));
+    $args .= "{".$`.$pat."}";
+    $contents = &missing_braces unless (
+       (s/$next_pair_pr_rx/$contents=$2;''/eo)
+       ||(s/$next_pair_rx/$contents=$2;''/eo));
+    $* = 0;                    # Multiline matching OFF
+    $args .= "{".$`.$contents."}";
+    if ($NO_PARBOX_IMAGES) {
+       $contents = join ('', &do_cmd_par(), $contents, '</P>' );
+    } else {
+       $contents = &process_math_in_latex('','text',0,"\\parbox$args")
+           if ($contents);
+    }
+    $contents . $_;
+}
+
+
+sub do_cmd_mbox {
+    local($_) = @_;
+    local($text,$after)=('','');
+    $text = &missing_braces unless (
+       (s/$next_pair_pr_rx/$text = $2;''/eo)
+       ||(s/$next_pair_rx/$text = $2;''/eo));
+    $after = $_;
+
+    # incomplete macro replacement
+    if ($text =~ /(^|[^\\<])#\d/) { return($after) }
+
+    if ($text =~ /(tex2html_wrap_inline|\$$OP(\d+)$CP$OP\2$CP\$|\$$O(\d+)$C$O\2$C\$)/) {
+       if ($text =~ 
+           /$image_mark#([^#]+)#([\.,;:\)\]])?(\001)?([ \t]*\n?)(\001)?/) {
+           local($mbefore, $mtext, $mafter) = ($`, $&, $');
+           $mbefore = &translate_commands($mbefore) if ($mbefore =~ /\\/);
+           $mafter = &translate_commands($mafter) if ($mafter =~ /\\/);
+           join('', $mbefore, $mtext, $mafter, $after);
+       } else {
+           join ('', &process_math_in_latex('','','',"\\hbox{$text}"), $after )
+       }
+    } else {
+       $text = &translate_environments($text);
+       $text = &translate_commands($text);
+       join('', $text, $after);
+    }
+}
+
+
+
+# *Generates* subroutines to handle each of the declarations
+# like \em, \quote etc., in case they appear with the begin-end
+# syntax.
+sub generate_declaration_subs {
+    local($key, $val, $pre, $post, $code );
+    print "\n *** processing declarations ***\n";
+    while ( ($key, $val) = each %declarations) {
+       if ($val) {
+           ($pre,$post) = ('','');
+           $val =~ m|</.*$|;
+           do {$pre = $`; $post = $& } unless ($` =~ /^<>/);
+           $pre =~ s/"/\\"/g; $post =~ s/"/\\"/g;
+           $code = "sub do_env_$key {"
+#              . 'local($_) = @_;' . "\n"
+#              . 'push(@$open_tags_R, $key);'. "\n"
+#              . '$_ = &translate_environments($_);'. "\n"
+#              . '$_ = &translate_commands($_);'. "\n"
+#              . "join('',\"$pre\",\"\\n\"," .'$_' .",\"$post\");\n};";
+               . '&declared_env('.$key.',@_)};';
+           eval $code;
+           if ($@) {print "\n *** $key ".  $@ };
+       }
+    }
+}
+
+# *Generates* subroutines to handle each of the sectioning commands.
+sub generate_sectioning_subs {
+    local($key, $val, $cmd, $body);
+    while ( ($key, $val) = each %standard_section_headings) {
+       $numbered_section{$key} = 0;
+       eval "sub do_cmd_$key {"
+           . 'local($after,$ot) = @_;'
+           . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'
+            . '&reset_dependents('. $key . ');'
+            . '&do_cmd_section_helper('.$val.','.$key.');}';
+       print STDERR "\n*** sub do_cmd_$key failed:\n$@\n" if ($@);
+       # Now define the *-form of the same commands. The difference is that the
+       # $key is not passed as an argument.
+       eval "sub do_cmd_$key" . "star {"
+           . 'local($after,$ot) = @_;'
+           . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'
+           . '&do_cmd_section_helper(' . $val . ');}';
+       print STDERR "\n*** sub do_cmd_${key}star failed:\n$@\n" if ($@);
+       # Now define the macro  \the$key  
+       &process_commands_wrap_deferred("the$key \# {}\n");
+###    local($_) = "<<1>>$key<<1>>";
+       $body = "<<1>>$key<<1>>";
+       &make_unique($body);
+       $cmd = "the$key";
+       eval "sub do_cmd_$cmd {"
+           . 'local($after,$ot) = @_;'
+           . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'
+           . '&do_cmd_arabic(' . "\"$body\"" . ").\$after;};";
+       print STDERR "\n*** sub do_cmd_$cmd failed:\n$@\n" if ($@);
+       $raw_arg_cmds{$cmd} = 1;
+    }
+    &addto_dependents('chapter','section');
+    &addto_dependents('section','subsection');
+    &addto_dependents('subsection','subsubsection');
+    &addto_dependents('subsubsection','paragraph');
+    &addto_dependents('paragraph','subparagraph');
+}
+
+sub addto_dependents {
+    local($ctr, $dep) = @_;
+    local($tmp, $depends);
+    if ($depends = $depends_on{$dep}) {
+       &remove_dependency($depends, $dep) }
+    $depends_on{$dep} = $ctr;
+
+    $tmp = $dependent{$ctr};
+    if ($tmp) { 
+       $dependent{$ctr} = join($delim, $tmp, $dep);
+    } else { $dependent{$ctr} = $dep }
+}
+
+sub remove_dependency {
+    local($ctr, $dep) = @_;
+    local(@tmp, $tmp, $dtmp);
+    print "\nremoving dependency of counter {$dep} from {$ctr}\n";
+    foreach $dtmp (split($delim, $dependent{$ctr})) {
+       push(@tmp, $dtmp) unless ($dtmp =~ /$dep/);
+    }
+    $dependent{$ctr} = join($delim, @tmp);
+}
+
+
+# Uses $after which is defined in the caller (the caller is a generated subroutine)
+# Also uses @curr_sec_id
+#
+#JCL(jcl-tcl) (changed almost everything)
+#
+sub do_cmd_section_helper {
+    local($H,$key) = @_;
+    local($section_number, $titletext, $title_key, @tmp, $align, $dummy);
+    local($anchors,$pre,$run_title,$_) = ('', "\n", '', $after);
+    local($open_tags_R) = [];
+
+    # if we have a $key the current section is not of the *-form, so we need
+    # to update the counters.
+    &do_cmd_stepcounter("${O}0$C$key${O}0$C")
+#      if ($key && !$making_name);
+#      if ($key && !($unnumbered_section_commands{$key}) && !$making_name);
+       if ($key && !($unnumbered_section_commands{$key}));
+#   $latex_body .= "\\stepcounter{$key}\n" if $key;
+#   &reset_dependents($key) if ($dependent{$key});
+
+    local($br_id);
+#    if ($USING_STYLES) {
+#      $txt_style{"H$H.$key"} = " " unless $txt_style{"H$H.$key"}; 
+#      $H .= " CLASS=\"$key\"; 
+#    };
+
+    local ($align, $dummy)=&get_next_optional_argument;
+    if (($align =~/^(left|right|center)$/i)&&($HTML_VERSION > 2.0)) {
+        $align = "ALIGN=\"$1\"";
+    } elsif ($align) {
+       # data was meant to be a running-head !
+       $br_id = ++$global{'max_id'};
+       $run_title = &translate_environments("$O$br_id$C$align$O$br_id$C");
+       $run_title = &translate_commands($run_title) if ($run_title =~ /\\/);
+       $run_title =~ s/($O|$OP)\d+($C|$CP)//g;
+       $align = '';
+    } else {
+    }
+    $titletext = &missing_braces 
+       unless s/$next_pair_rx/$titletext=$2;''/eo;
+    $br_id = ++$global{'max_id'};
+    $titletext = &translate_environments("$O$br_id$C$titletext$O$br_id$C");
+
+    $title_key = $run_title || $titletext;
+    $title_key =~ s/$image_mark\#([^\#]+)\#(\\space)?/&purify_caption($1)/e;
+    # This should reduce to the same information as contained in the .aux file.
+    $title_key = &sanitize(&simplify($title_key));
+
+    # RRM: collect all anchors from \label and \index commands
+    ($anchors,$titletext) = &extract_anchors($titletext);
+    local($saved_title) = $titletext;
+    do {
+        # to ensure a style ID is not saved and re-used in (mini-)TOCs
+       local($USING_STYLES) = 0;
+       $titletext = &translate_environments($titletext);
+       $titletext = &translate_commands($titletext) 
+           if ($titletext =~/\\/);
+    };
+    # but the style ID can be used for the title on the HTML page
+    if (!($titletext eq $saved_title)) {
+       $saved_title = &translate_environments($saved_title);
+       $saved_title = &translate_commands($saved_title) 
+           if ($saved_title =~/\\/);
+       $saved_title = &simplify($saved_title);
+    }
+    local($closures) = &close_all_tags();
+    $saved_title .= $closures;
+    $title_text .= $closures;
+
+    # This is the LaTeX section number read from the $FILE.aux file
+    @tmp = split(/$;/,$encoded_section_number{$title_key});
+    $section_number = shift(@tmp);
+    $section_number = "" if ($section_number eq "-1");
+    $encoded_section_number{$title_key} = join($;, @tmp)
+#      unless (defined $title);
+       unless ($title);
+
+    # need to check also &{wrap_cmd_... also, if \renewcommand has been used; 
+    # thanks Bruce Miller
+    local($thehead,$whead) = ("do_cmd_the$key","wrap_cmd_the$key");
+#    $thehead = ((defined &$thehead)? 
+#      &translate_commands("\\the$key") : '');
+    $thehead = ((defined &$thehead)||(defined &$whead)
+       ? &translate_commands("\\the$key") : '');
+    $thehead .= $SECNUM_PUNCT
+       if ($SECNUM_PUNCT &&($thehead)&& !($thehead =~ /\./));
+    $section_number = $thehead if (($thehead)&&($SHOW_SECTION_NUMBERS));
+
+    #JKR: Don't prepend whitespace 
+    if ($section_number) {
+       $titletext = "$section_number " . $titletext;
+       $saved_title = "$section_number " . $saved_title;
+       $run_title = "$section_number " . $run_title if $run_title;
+    }
+
+#    $toc_sec_title = $titletext;
+#    $toc_sec_title = &purify($titletext);
+    $toc_sec_title = &simplify($titletext);
+    $titletext = &simplify($titletext);
+#    $TITLE = &purify($titletext);
+    local($after) = $_;
+    do {
+       local($_) = $titletext; &remove_anchors; 
+       if ($run_title) {
+           $TITLE = $run_title;
+       } elsif ($_) {
+           $TITLE = $_
+       } else { $TITLE = '.' };
+    };
+    $global{$key}-- if ($key && $making_name);
+    return ($TITLE) if (defined $title);
+
+    #RRM: no preceding \n when this is the first section-head on the page.
+    if (! $key || $key < $MAX_SPLIT_DEPTH) { $pre = '' };
+    if ( defined &make_pre_title) {
+       $pre = &make_pre_title($saved_title, $H);
+    }
+
+    undef $open_tags_R;
+    $open_tags_R = [ @save_open_tags ];
+    
+    join('', $pre, &make_section_heading($saved_title, $H, $align.$anchors)
+       , $open_all, $_);
+}
+
+sub do_cmd_documentclass {
+    local($_) = @_;
+    local ($docclass)=('');
+    local ($cloptions,$dum)=&get_next_optional_argument;
+    $docclass = &missing_braces unless (
+       (s/$next_pair_pr_rx/$docclass = $2;''/eo)
+       ||(s/$next_pair_rx/$docclass = $2;''/eo));
+    local($rest) = $';
+    &do_require_package($docclass);
+    if (! $styles_loaded{$docclass}) {
+       &no_implementation("document class",$docclass);
+    } else {
+       if($cloptions =~ /\S+/) { # are there any options?
+           &do_package_options($docclass,$cloptions);
+       }
+    }
+    $rest;
+}
+sub do_cmd_documentstyle { &do_cmd_documentclass($_[0]); }
+
+sub do_cmd_usepackage {
+    local($_) = @_;
+    # RRM:  allow lists of packages and options
+    local ($package, $packages)=('','');
+    local ($options,$dum)=&get_next_optional_argument;
+    $packages = &missing_braces unless (
+       (s/$next_pair_pr_rx/$packages = $2;''/eo)
+       ||(s/$next_pair_rx/$packages = $2;''/eo));
+    local($rest) = $_;
+    # MRO: The files should have already been loaded by
+    #      TMP_styles, but we better make it sure.
+    foreach $package (split (',',$packages)) { # allow multiple packages
+       $package =~ s/\s|\%|$comment_mark\d*//g; # remove whitespace 
+       $package =~ s/\W/_/g; # replace non-alphanumerics
+       &do_require_package($package);
+       if (! $styles_loaded{$package}) {
+           &no_implementation("package",$package);
+       } else {
+           if($options =~ /\S+/) { # are there any options?
+               &do_package_options($package,$options);
+           }
+       }
+    }
+    $rest;
+}
+
+
+sub no_implementation {
+    local($what,$which)= @_;
+    print STDERR "\nWarning: No implementation found for $what: $which";
+}
+
+sub do_cmd_RequirePackage {
+    local($_)= @_;
+    local($file);
+    local($options,$dum)=&get_next_optional_argument;
+    $file = &missing_braces unless (
+       (s/$next_pair_pr_rx/$file = $2;''/eo)
+       ||(s/$next_pair_rx/$file = $2;''/eo));
+    local($rest) = $_;
+    $file =~ s/^[\s\t\n]*//o;
+    $file =~ s/[\s\t\n]*$//o;
+    # load the package, unless that has already been done
+    &do_require_package($file) unless ($styles_loaded{$file});
+    # process any options
+    if (! $styles_loaded{$file}) {
+           &no_implementation("style",$file);
+    } else {
+       # process any options
+       &do_package_options($file,$options) if ($options);
+    }
+    $_ = $rest;
+    # ignore trailing optional argument
+    local($date,$dum)=&get_next_optional_argument;
+    $_;
+}
+
+sub do_cmd_PassOptionsToPackage {
+    local($_) = @_;
+    local($options,$file);
+    $options = &missing_braces unless (
+        (s/$next_pair_pr_rx/$options = $2;''/eo)
+        ||(s/$next_pair_rx/$options = $2;''/eo));
+    $file = &missing_braces unless (
+        (s/$next_pair_pr_rx/$file = $2;''/eo)
+        ||(s/$next_pair_rx/$file = $2;''/eo));
+    $passedOptions{$file} = $options;
+    $_;
+}
+sub do_cmd_PassOptionsToClass{ &do_cmd_PassOptionsToPackage(@_)}
+
+sub do_package_options {
+    local($package,$options)=@_;
+    local($option);
+    if ($passedOptions{$package}) { $options = $passedOptions{$package}.'.'.$options };
+    foreach $option (split (',',$options)) {
+        $option =~ s/^[\s\t\n]*//o;
+        $option =~ s/[\s\t\n]*$//o;
+       $option =~ s/\W/_/g; # replace non-alphanumerics
+       next unless ($option);
+        if (!($styles_loaded{$package."_$option"})) {
+            &do_require_packageoption($package."_$option");
+            if (!($styles_loaded{$package."_$option"})) {
+               &no_implementation("option","\`$option\' for \`$package\' package\n");
+           }
+       }
+    }
+    $rest;
+}
+
+sub do_class_options {
+    local($class,$options)=@_;
+    local($option);
+    if ($passedOptions{$class}) { $options = $passedOptions{$class}.'.'.$options };
+    foreach $option (split (',',$options)) {
+        $option =~ s/^[\s\t\n]*//o;
+        $option =~ s/[\s\t\n]*$//o;
+       $option =~ s/\W/_/g; # replace non-alphanumerics
+       next unless ($option);
+        &do_require_package($option);
+        if (!($styles_loaded{$class."_$option"})) {
+            &do_require_packageoption($class."_$option");
+            if (!($styles_loaded{$class."_$option"})) {
+               &no_implementation("option","\`$option\' for document-class \`$class\'\n");
+           }
+       }
+    }
+    $rest;
+}
+
+sub do_require_package {
+    local($file)= @_;
+    local($dir);
+    #RRM: make common ps/eps-packages use  epsfig.perl
+    $file = 'epsfig' if ($file =~ /^(psfig|epsf)$/);
+
+    if ($file =~ /^graphicx$/) {
+       # work-around the CVS repository bug: use graphixx , not graphicx
+       foreach $dir (split(/$envkey/,$LATEX2HTMLSTYLES)) {
+           if (-f "$dir${dd}graphixx.perl") {
+               $file = 'graphixx';
+               last;
+           }
+       }
+    }
+
+    
+    if (! $styles_loaded{$file}) {
+       # look for a file named ${file}.perl
+       # MRO: use $texfilepath instead of `..'
+       if ((-f "$texfilepath$dd${file}.perl") && ! $styles_loaded{$file}){
+           print STDOUT "\nPackage: loading $texfilepath$dd${file}.perl";
+           require("$texfilepath$dd${file}.perl");
+           $styles_loaded{$file} = 1;
+       } else {
+           foreach $dir (split(/$envkey/,$LATEX2HTMLSTYLES)) {
+               if ((-f "$dir$dd${file}.perl") && ! $styles_loaded{$file}){
+                   print STDOUT "\nPackage: loading $dir$dd${file}.perl";
+                   require("$dir$dd${file}.perl");
+                   $styles_loaded{$file} = 1;
+                   last;
+               }
+           }
+       }
+    }
+}
+
+sub do_require_extension {
+    local($file)= @_;
+    local($dir);
+
+    if (! $styles_loaded{$file}) {
+       # look for a file named ${file}.pl
+       # MRO: use $texfilepath instead of `..'
+       if (-f "$texfilepath$dd${file}.pl") {
+           print STDOUT "\nExtension: loading $texfilepath$dd${file}.pl";
+           require("$texfilepath$dd${file}.pl");
+           ++$styles_loaded{$file};
+           $NO_UTF = 1 if (($file =~ /latin/)&&($charset =~/utf/));
+       } else {
+           foreach $dir (split(/$envkey/,$LATEX2HTMLVERSIONS)) {
+               if (-f "$dir$dd${file}.pl"){
+                   print STDOUT "\nExtension: loading $dir$dd${file}.pl";
+                   require("$dir$dd${file}.pl");
+                   ++$styles_loaded{$file};
+                   $NO_UTF = 1 if (($file =~ /latin/)&&($charset =~/utf/));
+                   last;
+               }
+           }
+       }
+    } else {
+       if (($file =~ /latin|hebrew/)&&($charset =~/utf|10646/)
+                       && $loading_extensions) {
+           $NO_UTF = 1;
+           $USE_UTF = 0;
+           print STDOUT "\n\n ...producing $CHARSET output\n";
+           $charset = $CHARSET;
+       } 
+    }
+}
+
+sub do_require_packageoption {
+    local($option)= @_;
+    local($do_option);
+    # first look for a file named ${option}.perl
+    &do_require_package($option) unless ($styles_loaded{$option});
+    # next look for a subroutine named  do_$option
+    $do_option = "do_$option";
+    if (!($styles_loaded{$option}) && defined(&$do_option)) {
+       &$do_option();
+       $styles_loaded{$option} = 1;
+    }
+}
+
+############################ Environments ################################
+
+# This is a dummy environment used to synchronise the expansion
+# of order-sensitive macros.
+sub do_env_tex2html_deferred {
+    local($_) = @_;
+    local($tex2html_deferred) = 1;
+    $_ = &process_command($single_cmd_rx,$_);
+}
+
+# catch wrapped commands that need not have been
+sub do_env_tex2html_nomath_inline {
+    local($_) = @_;
+    s/^\s+|\s+$//gs;
+    my($cmd) = $_;
+    if ($cmd=~s/^\\([a-zA-Z]+)//s) { $cmd = $1 };
+    return (&translate_commands($_)) if ($raw_arg_cmds{$cmd}<1);
+    &process_undefined_environment($env, $id, $_);
+}
+
+# The following list environment subroutines still do not handle
+# correctly the case where the list counters are modified (e.g. \alph{enumi})
+# and the cases where user defined bullets are mixed with the default ones.
+# e.g. \begin{enumerate} \item[(1)] one \item two \end{enumerate} will
+# not produce the same bullets as in the dvi output.
+sub do_env_itemize {
+    local($_) = @_;
+    $itemize_level++;
+    #RRM - catch nested lists
+    &protect_useritems($_);
+    $_ = &translate_environments($_);
+
+    local($bullet,$bulletx)=('&nbsp;','');
+    SWITCH: {
+       if ($itemize_level==1) { $bulletx = "\\bullet"; last SWITCH; }
+       if ($itemize_level==2) { $bulletx = "\\mathbf{\\circ}"; last SWITCH; }
+       if ($itemize_level==3) { $bulletx = "\\mathbf{\\ast}"; last SWITCH; }
+    }
+    $itemize_level--;
+
+    if (/\s*$item_description_rx/) {
+       # Contains user defined optional labels
+       $bulletx = &do_cmd_mbox("${O}1$C\$$bulletx\$${O}1$C") if $bulletx;
+       &do_env_description($_, " COMPACT", $bullet.$bulletx)
+    } else { &list_helper($_,'UL'); }
+}
+
+sub do_env_enumerate {
+    local($_) = @_;
+# Reiner Miericke provided the main code; integrated by RRM: 14/1/97
+# works currently only with 'enumerate' and derived environments
+# explicit styled labels are computed for each \item
+# ultimately the environment is done as:  &do_env_description($_, " COMPACT")
+    ++$enum_level;
+    local(%enum) = %enum;              # to allow local changes
+# Reiner: \begin{enumerate}[<standard_label>]
+    local($standard_label) = "";
+    local(@label_fields);
+    local($label_func, $preitems, $enum_type);
+    local($rlevel) = &froman($enum_level); # e.g. 3 => iii
+
+    # \begin{enumerate}[$standard_label]
+    if (s/^$standard_label_rx//s) {            # multiline on/off ?
+       # standard label should be used later to modify
+       # entries in %enum
+       $standard_label = $1;           # save the standard label
+#      s/^$standard_label_rx//;        # and cut it off
+       $standard_label =~ s/([\\\[\]\(\)])/\\$1/g; # protect special chars
+
+       # Search for [aAiI1] which is not between a pair of { }
+       # Other cases like "\theenumi" are not handled
+       @label_fields = $standard_label =~ /$enum_label_rx/;
+       if (($standard_label =~ /^[aAiI1]$/)&&(not(/item\s*\[/))) {
+           $enum_type = ' TYPE="'.$standard_label.'"';
+           $standard_label = '';
+       } else {
+           $label_func = $enum_label_funcs{$label_fields[$#label_fields-1]} . 
+               "(\'enum" . $rlevel . "\')";
+           $enum{'theenum' . $rlevel} = "\&$label_func";
+#      local($thislabel) = "\&$label_func";
+#      do { local($_) = $thislabel; &make_unique($_);
+#           $enum{'theenum' . $rlevel} = $_; };
+           $standard_label = 
+               "\"$label_fields[0]\" . eval(\$enum{\"theenum$rlevel\"})"
+               . ".\"$label_fields[$#label_fields]\"";
+           $enum{'labelenum' . $rlevel} = $standard_label;
+       }
+    }  elsif (s/^((.|\n)+?)\\item/$preitems=$1;"\\item"/es) {
+       my $pre_preitems; local($cmd); $label_part;
+       my $num_styles = join('|', values %enum_label_funcs );
+       while ($preitems =~
+           /\s*\\renew(ed)?command\s*(($O|$OP)\d+($C|$CP))\\?((label|the)enum(\w+))\s*\2/) {
+           # this catches one  \renewcommand{\labelenum}{....} 
+           $pre_preitems .= $`; $preitems = $'; $cmd = $5;
+           &missing_braces unless (
+               ($preitems=~s/$next_pair_pr_rx\s*/$label_part=$2;''/oe)
+               ||($preitems=~s/$next_pair_rx\s*/$label_part=$2;''/oe));
+           $cmd =~ s/^label/the/;
+           $label_part=~s/\\($num_styles)\s*(($O|$OP)\d+($C|$CP))(\w+)\2/".\&$1\(\'$5\'\)."/g;
+           $label_part = '"'.$label_part.'"';
+           $enum{$cmd} = $label_part;
+        }
+       $standard_label = 
+           "\"$label_fields[0]\" . eval(\$enum{\"theenum$rlevel\"})"
+           . ".\"$label_fields[$#label_fields]\"" if ($cmd);
+       $_ = $pre_preitems . $preitems . $_ if ($pre_preitems||$preitems);
+    } else {
+       @enum_default_type = ('A', '1', 'a', 'i', 'A') unless (@enum_default_type);
+       $enum_type = $enum_level%4;
+       $enum_type = ' Type="'.@enum_default_type[$enum_type].'"';
+    }
+
+    # enclose contents of user-defined labels within a group,
+    # in case of style-change commands, which could bleed outside the label.
+    &protect_useritems($_);
+    $_ = &translate_environments($_);  #catch nested lists
+
+    local($enum_result);
+    if (($standard_label)||(/\\item\[/)) {
+       # split it into items
+       @items = split(/\\item\b/,$_);
+       # save anything (non-blank) before the items actually start
+       $preitems = shift(@items);
+       $preitems =~ s/^\s*$//;
+       local($enum_label);
+       # prepend each item with an item label: \item => \item[<label>]
+       foreach $item (@items) {
+#        unless ( $item =~ /^\s*$/ ) { # first line may be empty
+           $enum{"enum" . $rlevel}++;  # increase enumi
+           $enum_label = eval("$enum{'labelenum' . $rlevel}");
+           # insert a label, removing preceding space, BUT...
+           # do NOT handle items with existing labels
+           $item =~ s/^\s*//;
+           if ($item =~ s/^\s*\[([^]]*)\]//) {
+               $enum{"enum" . $rlevel}--;
+               $enum_label = "$1";
+               local($processed) = ($enum_label =~/$OP/);
+               $enum_label = join('',($processed ? "<#0#>" : "<<0>>")
+                   ,$enum_label ,($processed ? "<#0#>" : "<<0>>"))
+                       if ($enum_label =~ /\\/);
+               if ($processed) { &make_unique_p($enum_label) }
+               elsif ($enum_label =~ /$O/) { &make_unique($enum_label) };
+               $item = "[${enum_label}]".$item;
+           } else { 
+               local($processed) = ($enum_label =~/$OP/);
+               $enum_label = join('',($processed ? "<#0#>" : "<<0>>")
+                   ,$enum_label ,($processed ? "<#0#>" : "<<0>>"))
+                       if ($enum_label =~ /\\/);
+               if ($processed) { &make_unique_p($enum_label) }
+               elsif ($enum_label =~ /$O/) { &make_unique($enum_label) };
+               $item = "[$enum_label\]$item";
+               $enum_label =~ s/\.$//;
+           }
+           if ($standard_label) {
+               $item =~ s/(\\labelitem$rlevel|$standard_label)/$enum_label/g
+           } else {
+               $item =~ s/(\\labelitem$rlevel)/$enum_label/g
+           }
+       };
+       $_ = join("\\item ", $preitems, @items);
+
+       # Original, but $enum_result
+       $enum_result = &do_env_description($_, " COMPACT");
+    } else {
+       $enum_result = &list_helper($_, "OL$enum_type", '', '');
+    }
+
+    #clean-up and revert the $enum_level
+    $enum{"enum" . $rlevel} = 0;
+    $enum{"enum" . &froman($enum_level)} = 0;
+    --$enum_level;
+    $enum_result;
+}
+
+sub do_env_list {
+    local ($_) = @_;
+    local ($list_type,$labels,$lengths) = ('UL','','');
+
+    $labels = &missing_braces unless    ( # get the label specifier
+       (s/$next_pair_pr_rx/$labels=$2;''/e)
+       ||(s/$next_pair_rx/$labels=$2;''/e));
+
+    $lengths = &missing_braces unless ( # get the length declarations
+       (s/$next_pair_pr_rx/$lengths=$2;''/e)
+       ||(s/$next_pair_rx/$lengths=$2;''/e));
+    # switch to enumerated style if they include a \usecounter.
+    $list_type = 'OL' if $lengths =~ /\\usecounter/;
+
+    /\\item\b/; local($preitems) = $`;
+       $_ =~ s/^\Q$preamble//s if ($preitems);
+    $preitems =~s/^\s*|\s*$//g;
+    if ($preitems) {
+       $preitems = &translate_environments($preitems);
+       $preitems = &translate_commands($preitems) if ($preitems =~ /\\/);
+#      &write_warnings("\nDiscarding: $preitems before 1st item in list")
+#          if ($preitems);
+    }
+
+    #RRM - catch nested lists
+    #RRM unfortunately any uses of the \\usecounter  within \item s
+    #    may be broken --- sigh.
+    &protect_useritems($_);
+    $_ = &translate_environments($_);
+
+    if (($list_type =~ /OL/)&&($labels)) {
+       local($br_ida,$br_idb,$label,$aft);
+       $br_ida = ++$global{'max_id'};
+       $lengths =~ s/\\usecounter((($O|$OP)\d+($C|$CP))[^<]+\2)/
+               &make_nowrapper(1)."\\stepcounter$1".&make_nowrapper(0)/e;
+       $labels = "$O$br_ida$C$lengths$O$br_ida$C".$labels;
+
+#      s/\\item\b\s*([^\[])/do {
+#              $label = $labels; $aft = $1;
+#              $br_id = ++$global{'max_id'};
+#              $label = &translate_environments(
+#                      "$O$br_id$C$label$O$br_id$C");
+#              join('',"\\item\[" , $label, "\]$aft" );
+#          }/eg;
+#      $labels ='';
+    }
+
+    if (($labels)||(/\\item\[/)) {
+       $_ = &list_helper($_, 'DL', $labels, $lengths)
+    } else {
+       $_ = &list_helper($_, $list_type, '', $lengths)
+    }
+    $_;
+}
+
+sub do_env_trivlist {
+    local($_) = @_;
+    local($compact,$item_sep,$pre_items) = ' COMPACT';
+    &protect_useritems($_);
+
+    # assume no styles initially for this list
+    local($close_tags,$reopens) = &close_all_tags();
+    local($open_tags_R) = [];
+    local(@save_open_tags) = ();
+
+    # include \label anchors from [...] items
+    s/$item_description_rx\s*($labels_rx8)?\s*/
+       (($9)? "<A NAME=\"$9\">$1<\/A>" : $1 ) ."\n"/eg;
+    # remove unwanted space before \item s
+    s/[ \t]*\\item\b/\\item/g;
+    
+    local($this_item,$br_id) = ('','');
+    local($this_sitem,$this_eitem) = ("\n<P>","</P>\n",'');
+
+    # assume no sub-lists, else...  why use {trivlist} ?
+    # extract up to the 1st \item
+    local(@items) = split(/\\item\b/, $_);
+    $pre_items = shift @items;
+    $_ = '';
+    while (@items) {
+       $br_id = ++$global{'max_id'};
+       $this_item = shift @items;
+       $this_item = &translate_environments(
+            "$O$br_id$C".$pre_items.$this_item."$O$br_id$C" );
+       if ($this_item =~ /\\/) {
+           $this_item = &translate_commands($this_item);
+           $_ .= join('' , $this_sitem 
+                      , $this_item
+                      # , $this_eitem
+                      )
+       } else { $_ .= $this_sitem . $this_item }
+    }
+       
+    $_ = &translate_environments($_);
+    $_ = &translate_commands($_);
+
+    join('' , $close_tags , $_ , $reopens);
+
+}
+
+# enclose the contents of any user-defined labels within a group,
+# else any style-change commands may bleed outside the label.
+sub protect_useritems {
+    # MRO: use $_[0] instead: local(*_) = @_;
+    local($preitems, $thisitem);
+    $_[0] =~ s/^$par_rx\s*//s; # discard any \par before 1st item
+
+    # locate \item with optional argument 
+    local($saveRS) = $/; undef $/;
+    local(@preitems);
+    # allow one level of nested []
+    # MRO: Caution! We have a double-wildcarded RX here, this may cause
+    # trouble. Should be re-coded.
+    $_[0] =~ s/\\item[\s\r]*(\b(\[(([^\[\]]|\[[^]]*\])*)\])?|[^a-zA-Z\s])/
+       $thisitem = " $1";
+       if ($2) {
+           $br_id = ++$global{'max_id'};
+           $thisitem = '['.$O.$br_id.$C.$3.$O.$br_id.$C.']';
+       };
+       "\\item".$thisitem
+    /egm;
+
+    $/ = $saveRS;
+    $_[0] = join(@preitems, $_[0]);
+}
+
+sub do_env_description {
+    local($_, $compact, $bullet) = @_;
+    #RRM - catch nested lists
+    &protect_useritems($_);
+    $_ = &translate_environments($_) unless ($bullet);
+
+    # MRO: replaced $* with /m
+    $compact = "" unless $compact;
+    if ($compact) {            # itemize/enumerate with optional labels
+       s/\n?$item_description_rx\s*($labels_rx8)?\s*/"\n<\/DD>\n<DT>". 
+           (($9)? "<A NAME=\"$9\">$1<\/A>" : $1 ) ."<\/DT>\n<DD>"/egm;
+    } else {
+       s/\n?$item_description_rx\s*($labels_rx8)?\s*/"\n<\/DD>\n<DT>". 
+           (($9)? "<A NAME=\"$9\"><STRONG>$1<\/STRONG><\/A>" 
+            : "<STRONG>$1<\/STRONG>") ."<\/DT>\n<DD>"/egm;
+    }
+    # and just in case the description is empty ...
+#JCL(jcl-del) - $delimiter_rx -> ^$letters
+    s/\n?\\item\b\s*([^$letters\\]|)\s*/\n<\/DD>\n<DT>$bullet<\/DT>\n<DD>$1/gm;
+    s/^\s+//m;
+
+    $_ = '<DD>'.$_ unless ($_ =~ s/^\s*<\/D(T|D)>\n?//s);
+    $_ =~ s/\n$//s;
+    "<DL$compact>\n$_\n</DD>\n</DL>";
+}
+
+sub list_helper {
+    local($_, $tag, $labels, $lengths) = @_;
+    local($item_sep,$pre_items,$compact,$etag,$ctag);
+    $ctag = $tag; $ctag =~ s/^(.*)\s.*$/$1/;
+
+    # assume no styles initially for this list
+    local($close_tags,$reopens) = &close_all_tags();
+    local($open_tags_R) = [];
+    local(@save_open_tags) = ();
+
+#    #RRM: cannot have anything before the first <LI>
+#    local($savedRS) = $/; $/='';
+#    $_ =~ /\\item[\b\r]/s;
+#    if ($`) { 
+#      $preitems = $`; $_ = $&.$';
+#      $preitems =~ s/<P( [^>]*)?>//g;
+#      $close_tags .= "\n".$preitems if $preitems;
+#    }
+#    $/ = $savedRS; 
+#
+
+    $* = 1;                    # Multiline matching ON
+    if (($tag =~ /DL/)&&$labels) {
+       local($label,$aft,$br_id);
+       s/\\item\b[\s\r]*([^\[])/do {
+               $label = $labels; $aft = $1;
+               $br_id = ++$global{'max_id'};
+               $label = &translate_environments(
+                       "$O$br_id$C$label$O$br_id$C");
+               join('',"\\item\[" , $label, "\]$aft" );
+           }/eg;
+    }
+    $* = 0;                    # Multiline matching OFF
+
+    # This deals with \item[xxx] ...
+    if ($tag =~ /DL/) {
+       $compact = ' COMPACT';
+       # include \label anchors in the <DT> part
+       # and  $pre_item  tags in the <DD> part:
+       if ($labels && $lengths) { 
+           $item_sep = "\n</DD>\n<DT>";
+       } else {
+           $item_sep = ($labels ? "<DT>$labels\n" : '') ."</DT>\n<DD>";
+       }
+       $etag = "\n</DD>";
+       s/$item_description_rx[\r\s]*($labels_rx8)?[\r\s]*/"<DT>" .
+           (($9)? "<A NAME=\"$9\">$1<\/A>" : $1 ) ."\n<DD>"/egm;
+    } else {
+       $item_sep = "\n</LI>\n<LI>";
+       $etag = "\n</LI>";
+    }
+
+    # remove unwanted space before \item s
+    s/[ \t]*\\item\b/\\item/gm;
+
+    #JCL(jcl-del) - $delimiter_rx -> ^$letters
+    s/\n?\\item\b[\r\s]*/$item_sep/egm;
+
+    #RRM: cannot have anything before the first <LI>
+    local($savedRS) = $/; $/='';
+    $_ =~ /\Q$item_sep\E|<DT>|<LI>/s;
+    #RRM: ...try putting it before the list-open tag
+    if ($`) { 
+       $preitems = $`; $_ = $&.$';
+       $preitems =~ s/<P( [^>]*)?>//gm;
+       $close_tags .= "\n".$preitems if $preitems;
+    }
+    $_ =~ s/^\s*<\/[^>]+>\s*//s;
+
+    # remove \n from end of the last item
+    $_ =~ s/\n$//s;
+    $/ = $savedRS;
+
+    join('' , $close_tags , "\n<$tag$compact>\n" 
+        , $_ , "$etag\n</$ctag>" , $reopens);
+}
+
+
+# RRM:  A figure environment generates a picture UNLESS it contains a 
+# {makeimage} sub-environment; in which case it creates a <DIV>
+# inside which the contents are interpreted as much as is possible.
+# When there are captions, this modifies $before .
+sub do_env_figure {
+    local($_) = @_;
+    local($halign, $anchors) = ('CENTER','');
+    local ($border, $attribs );
+    local($cap_width) = $cap_width;
+    my ($opt, $dummy) = &get_next_optional_argument;
+
+    my $abovedisplay_space = $ABOVE_DISPLAY_SPACE||"<P></P>\n";
+    my $belowdisplay_space = $BELOW_DISPLAY_SPACE||"<P></P>\n";
+
+    ($_,$anchors) = &extract_labels($_); # extract labels
+    # Try to establish the alignment
+    if (/^(\[[^\]]*])?\s*\\begin\s*<<\d*>>(\w*)<<\d*>>|\\(\w*)line/) {
+       $halign = $2.$3;
+       if ($halign =~ /right/i)  { $halign = 'RIGHT' }
+       elsif ($halign =~ /left/i) { $halign = 'LEFT' }
+       elsif ($halign =~ /center/i) { $halign = 'CENTER' }
+       else { $halign = 'CENTER' }
+    }
+
+    # allow caption-alignment to be variable
+    local($cap_align);
+    if ($FIGURE_CAPTION_ALIGN =~ /^(TOP|BOTTOM|LEFT|RIGHT)/i) {
+       $cap_align = join('', ' ALIGN="', $&, $','"')};  
+
+    local($cap_env, $captions,$has_minipage) = ('figure','');
+    if ((/\\begin\s*($O\d+$C)\s*(makeimage|minipage)\s*\1|\\docode/)||
+       (/\\includegraphics/&&(!/$htmlborder_rx|$htmlborder_pr_rx|\\htmlimage/))){
+       $has_minipage = ($2 =~ /minipage/sg );
+       $_ = &translate_environments($_);
+       if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+       elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+       do { local($contents) = $_;
+           &extract_captions($cap_env); $_ = $contents;
+       } if (/\\caption/);
+       $_ = &translate_commands($_);
+       while ($_ =~ s/(^\s*<BR>\s*|\s*<BR>\s*$)//sg){}; # remove unneeded breaks
+    } else {
+       do { local($contents) = $_;
+           # MRO: no effect: &extract_captions($cap_env, *cap_width); $_ = $contents;
+           &extract_captions($cap_env); $_ = $contents;
+       } if (/\\caption/);
+       # Generate picture of the whole environment
+       if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+       elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+       $_ = &process_undefined_environment($env, $id, $_);
+       $_ = &post_latex_do_env_figure($_);
+       $_ =~ s/\s*<BR>\s*$//g;
+    }
+
+    if ($captions) {
+        # MRO: replaced $* with /m
+        $captions =~ s/^\n//m;
+        $captions =~ s/\n$//m;
+    }
+    s/$caption_mark//g;
+
+    local($close_tags) = &close_all_tags;
+    $_ .= $close_tags;
+
+    # place all the pieces inside a TABLE, if available
+    if ($HTML_VERSION > 2.1) {
+       if ($captions) {
+           local($pxs,$len) = &convert_length($cap_width,$MATH_SCALE_FACTOR)
+               if $cap_width;
+           local($table) = "<TABLE$env_id"; # WIDTH="65%"';
+           $table .= " WIDTH=\"$pxs\"" if ($pxs);
+           if ($border) { $table .= " BORDER=\"$border\"" } # no checking !!
+           $table .= ">";
+           s/^\s*|\s*$//g;
+           join (''
+                   , $above_display_space
+                   , "\n<DIV", ($halign ? " ALIGN=\"$halign\"" :'')
+                   , '>', $anchors , $cap_anchors
+                   , "\n$table\n<CAPTION", $cap_align, '>'
+                   , $captions , "</CAPTION>\n<TR><TD>"
+                   , ($cap_width ? '</TD><TD>' : '')
+                   , $_ , '</TD>'
+                   , ($cap_width ? '<TD></TD>' : '')
+                   , "</TR>\n</TABLE>\n</DIV>\n"
+                   , $below_display_space
+           )
+       } elsif ($halign) {
+           if ($border||($attributes)||$env_id) {
+               &make_table( $border, $attribs, $anchors, '', $halign, $_ );
+           } else {
+               join (''
+                       , $above_display_space
+                       , "\n<DIV ALIGN=\"$halign\">\n"
+                       , ($anchors ? "\n<P>$anchors</P>" : '')
+                       , $_
+                       , "\n</DIV>"
+                       , $below_display_space
+               )
+           }
+       } else {
+           if ($border||($attributes)||$env_id) {
+               join (''
+                       , $above_display_space
+                       , "\n<DIV", ($halign ? " ALIGN=\"$halign\"":'')
+                       , '>'
+                       , &make_table( $border, $attribs, $anchors, '', $halign, $_ )
+                       , "\n</DIV><BR"
+                       , (($HTML_VERSION > 3.1)? " CLEAR=\"ALL\"" :'')
+                       , '>'
+                       , $below_display_space
+               );
+           } else {  
+               join (''
+                       , $above_display_space
+                       , "\n<DIV", ($halign ? " ALIGN=\"$halign\"":'')
+                       , ">$anchors\n" , $_ , "\n</DIV><BR"
+                       , (($HTML_VERSION > 3.1)? " CLEAR=\"ALL\"" :'')
+                       , '>'
+                       , $below_display_space
+               );
+           }
+       }
+    } else {
+       # MRO: replaced $* with /m
+        s/^\n//m;
+        s/\n$//m;
+       if ($captions) {
+           join('', "\n<BR>\n", (($anchors) ? "$anchors" : '')
+               , "$cap_anchors\n$captions\n<BR>" 
+               , "\n<P", ($halign ? " ALIGN=\"$halign\"":'')
+               , '>', $_ , "\n</P>");
+       } elsif ($halign) {
+           join ('', "<BR>\n$anchors", $_ , "\n<BR>" )
+       } else {
+           join('', "<BR>\n<P", ($halign ? " ALIGN=\"$halign\"":'')
+               , ">$anchors\n" , $_ , "\n</P><BR>");
+       }
+    }
+}
+
+sub do_env_figurestar { &do_env_figure(@_) }
+
+sub do_env_table {
+    local($_) = @_;
+    local($halign, $anchors) = ('','');
+    local ( $border, $attribs );
+    &get_next_optional_argument;
+
+    # Try to establish the alignment 
+    if (/^(\[[^\]]*])?\s*\\begin\s*<<\d*>>(\w*)<<\d*>>|\\(\w*)line/) {
+       $halign = $2.$3;
+       if ($halign =~ /right/i)  { $halign = 'RIGHT' }
+       elsif ($halign =~ /left/i) { $halign = 'LEFT' }
+       elsif ($halign =~ /center/i) { $halign = 'CENTER' }
+       else { $halign = '' }
+    }
+
+    local($cap_env, $captions) = ('table','');
+
+    # allow caption-alignment to be variable
+    local($cap_align);
+    if ($TABLE_CAPTION_ALIGN =~ /^(TOP|BOTTOM|LEFT|RIGHT)/i) {
+       $cap_align = join('', ' ALIGN="', $&, $','"')};  
+
+    if ((/\\(begin|end)\s*($O\d+$C)\s*makeimage\s*\2/)||
+           ($HTML_VERSION > 2.0 && (
+               /\\begin\s*($O\d+$C)\s*((super)?tabular|longtable)\s*\1/))) {
+       $_ = &translate_environments($_);
+       ($_,$anchors) = &extract_labels($_); # extract labels
+       do { local($contents) = $_;
+           &extract_captions($cap_env); $_ = $contents;
+       } if (/\\caption/);
+       if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+       elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+       $_ = &translate_commands($_);
+       while ($_ =~ s/(^\s*<BR>\s*|\s*<BR>\s*$)//g){};
+    } else {
+       # Make an image of the whole environment.
+       ($_,$anchors) = &extract_labels($_); # extract labels
+       do { local($contents) = $_;
+           &extract_captions($cap_env); $_ = $contents;
+       } if (/\\caption/);
+       if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+       elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+       $_ = &process_undefined_environment($env, $id, $_);
+       $_ = &post_latex_do_env_table($_);
+       $_ =~ s/\s*<BR>\s*$//g;
+    }
+
+    if ($captions) {
+        # MRO: replaced $* with /m
+        $captions =~ s/^\n//m;
+        $captions =~ s/\n$//m;
+    }
+    s/$caption_mark//g;
+
+    local($close_tags) = &close_all_tags;
+    $_ .= $close_tags;
+
+    #  when $captions remain place all the pieces inside a TABLE, if available
+    if ($HTML_VERSION > 2.1) {
+       if ($captions) {
+           $halign = 'CENTER' unless $halign;
+           local($table) = '<TABLE';
+           if ($border) { $table .= " BORDER=\"$border\"" } # no checking !!
+           $table .= ">";
+           join ('', "<BR><P></P>\n<DIV$env_id ALIGN=\"$halign\">"
+               , "$anchors$cap_anchors\n$table\n<CAPTION", $cap_align, '>'
+               , $captions , "</CAPTION>\n<TR><TD>"
+               , $_ , "</TD></TR>\n</TABLE>\n</DIV><P></P><BR>" )
+       } elsif ($halign) {
+           if ($halign) {
+               # MRO: replaced $* with /m
+               s/^\s*(<(P|DIV)$env_id ALIGN=\"\w+[^>]+>)/$1$anchors/m
+                    if ($anchors);
+               join('', "<BR>", $_, "\n<BR>" )
+           } else {
+               join ('', "<BR>\n$anchors", $_ , "\n<BR>" )
+           }
+        } else {
+            join ('', "<BR><P></P>\n<DIV$env_id ALIGN=\"CENTER\">$anchors\n", $_ , "\n</DIV><BR>" )
+        }
+    } else {
+        # MRO: replaced $* with /m
+        s/^\n//m;
+        s/\n$//m;
+        if ($captions) {
+            join('', "<BR>\n", (($anchors) ? "$anchors" : ''), "$cap_anchors\n$captions\n<BR>"
+                , "\n<P ALIGN=\"$halign\">", $_, "\n</P><BR>");
+        } elsif ($halign) {
+            join ('', "<BR><P></P>\n$anchors", $_ , "\n<P></P>" )
+        } else {
+            join('', "<BR>\n<P ALIGN=\"CENTER\">$anchors\n", $_, "\n</P><BR>");
+        }
+    }
+}
+
+sub do_env_tablestar { &do_env_table(@_) }
+
+# RRM:  A makeimage environment generates a picture of its entire contents, 
+#  UNLESS it is empty.
+#
+sub do_env_makeimage {
+    local($_) = @_;
+    local($attribs, $border);
+    s/^\s*//;
+    if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+    elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+    if (/^((\\begin\s*(($O|$OP)\d+($C|$CP))tex2html_deferred\3)?\\par(\\end(($O|$OP)\d+($C|$CP))tex2html_deferred\7)?\%?\s*\n)+$/s) { return("\n<BR>\n") }
+    if (/^(\s\%?\n)+$/s) { return() }
+    $_ = &process_undefined_environment($env, $id, $_);
+    if (($border||($attributes))&&($HTML_VERSION > 2.1 ))
+       { $_ = &make_table( $border, $attribs, '', '', '', $_ ) }
+    $_ . ((!$_=~/^\s*$/)? "\n<BR>\n" :'');
+}
+
+sub do_env_abstract { &make_abstract($_[0]) }
+
+sub do_env_minipage {
+    local($_) = @_;
+    &get_next_optional_argument;
+    local($width);
+    $width = &missing_braces unless (
+       (s/$next_pair_pr_rx/$width=$2;''/e)
+       ||(s/$next_pair_rx/$width=$2;''/e));
+    local($pxs,$len) = &convert_length($width,$MATH_SCALE_FACTOR) if $width;
+    $width = " WIDTH=\"$pxs\"";
+    
+    local ( %mpfootnotes, $mpfootnotes ) unless ($MINIPAGE);
+    local ( $border, $attribs, $footfile);
+    $global{'mpfootnote'} = 0 unless ($MINIPAGE);
+    $MINIPAGE++;
+    print "\n *** doing minipage *** " if ($VERBOSITY > 1);
+    local($open_tags_R) = [ @$open_tags_R ];
+    local($close_tags,$reopens) = &close_all_tags();
+    local(@save_open_tags) = @$open_tags_R;
+   
+    local($minipage_caption) if $cap_env;
+    if ($cap_env &&($HTML_VERSION>2.1)) {
+       do {
+           local($captions);
+           local($contents) = $_;
+           &extract_captions($cap_env) if ($_ =~ /\\caption/m);
+           $minipage_caption = $captions;
+           $_ = $contents;
+           undef $contents; undef $captions;
+       };
+    }
+
+    if (s/^\s*$htmlborder_rx//so) {
+       $attribs = $2; $border = (($4)? "$4" : 1)
+    } elsif (s/^\s*$htmlborder_pr_rx//so) {
+       $attribs = $2; $border = (($4)? "$4" : 1)
+    }
+    if (/^\s*\\/) {
+       local($tmp) = ++$global{'max_id'};
+       $_ = $O.$tmp.$C.$_.$O.$tmp.$C
+    }
+    $_ = &translate_environments($_);
+    if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+    elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+    $_ = &translate_commands($_);
+    $MINIPAGE--; $MINIPAGE='' if ($MINIPAGE==0);
+
+    $_ .= &balance_tags();
+    $attribs .= $width unless ($attribs =~ /WIDTH/i);
+#    if (($border||$attribs)&&$MINIPAGE&&($HTML_VERSION>2.1)) { 
+    if (($border||$attribs||$env_id)&&$MINIPAGE&&($HTML_VERSION>2.1)) { 
+       $_ = &make_table( $border, $attribs, '', '', '', $_ );
+    } elsif ($MINIPAGE) { 
+       $_ = join ('', '<BR><HR>', $_ , '<BR><HR><BR>' );
+    } elsif (($border||($attribs)||$minipage_caption)&&($HTML_VERSION > 2.1 )) {
+       $mpfootnotes = '<DL>'.$mpfootnotes.'</DL>' if $mpfootnotes;
+       $_ = &make_table( $border, $attribs, '', $mpfootnotes, '', $_ );
+       $_ = join('','<BR><HR'
+               , (($HTML_VERSION > 3.0)? ' WIDTH="50\%" ALIGN="CENTER"' : '')
+               , '>', $_ , '<BR><HR'
+               , (($HTML_VERSION > 3.0)? ' WIDTH="50\%" ALIGN="CENTER"' : '')
+               , '><BR>') unless ($border||$attribs||$mpfootnotes);
+    } else {
+       $global{'mpfootnote'} = 0;
+       if ($mpfootnotes) {
+           $mpfootnotes = '<DD>'.$mpfootnotes unless ($mpfootnotes =~ /^\s*<D(T|D)>/);
+           $_ = join('','<BR><HR>', $_ , '<BR><HR'
+               , (($HTML_VERSION > 3.0)? ' WIDTH="200" ALIGN="LEFT"' : '')
+               , '><DL>', $mpfootnotes , '</DL><HR><BR'
+               , (($HTML_VERSION > 3.0)? ' CLEAR="all"' : '')
+               , '>' );
+       } else {
+           $_ = join ('', '<BR><HR><P></P>', $_ , '<BR><HR><BR>' );
+       }
+    }
+    join('', $close_tags, $_, $reopens);
+}
+
+if (($HTML_VERSION > 2.1)&&($HTML_VERSION < 4.0)) {
+    $TABLE_attribs = ",ALIGN,";
+    $TABLE__ALIGN = ",left,right,center,";
+    $TABLE_attribs_rx_list = ",CELLPADDING,BORDER,WIDTH,CELLSPACING,";
+    $TABLE__WIDTH_rx = "\^\\d+%?";
+    $TABLE__BORDER_rx = $TABLE__CELLSPACING_rx = $TABLE__CELLPADDING_rx = "\^\\d+";
+}
+
+sub make_table {
+    local($border, $attribs, $anchors, $extra_cell, $halign, $_) = @_;
+    local($table,$caption,$div,$end,$Tattribs);
+    $caption = join('',"<CAPTION$cap_align>"
+       , $minipage_caption
+       ,'</CAPTION>') if ($minipage_caption);
+    $end = "</TD></TR>\n</TABLE>";
+    $table = join('', "<TABLE$env_id"
+       , ((($caption)&&!($attribs =~/WIDTH/i)) ? " WIDTH=\"100\%\"" : '')
+       , ((($border)&&!($attribs =~/BORDER/i)) ? " BORDER=\"$border\"" : '')
+       );
+    if ($attribs) {
+       if (!($attribs =~ /=/)) {
+           $Tattribs = &parse_valuesonly($attribs,"TABLE");
+       } else {
+           $Tattribs = &parse_keyvalues($attribs,"TABLE");
+       }
+       $table .= " $Tattribs" if ($Tattribs);
+    }
+    print STDOUT "\nTABLE: $table>" if ($VERBOSITY >2 );
+    $table .= ">".$caption."\n<TR><TD>";
+    if ($extra_cell) {
+       local($sep) = "</TD></TR>\n<TR ALIGN=\"LEFT\">\n<TD>";
+       join ('', $div, $anchors, $table, $_ , $sep, $extra_cell, $end );
+    } else {
+       join ('', $div, $anchors, $table, $_ , $end );
+    }
+}
+
+sub do_cmd_etalchar {
+    local($_) = @_;
+    my $etalchar;
+    $etalchar = &missing_braces unless (
+       (s/$next_pair_pr_rx/$etalchar = $2;''/eo)
+       ||(s/$next_pair_rx/$etalchar = $2;''/eo));
+    $etalchar = &translate_commands($etalchar) if ($etalchar =~ /\\/);
+    if ($HTML_VERSION < 3.0) {
+       $etalchar = &process_in_latex("\$^\{$etalchar\}\$");
+    } else {
+       $etalchar = '<SUP>'.$etalchar.'</SUP>';
+    }
+    $etalchar . $_
+}
+
+sub do_env_thebibliography {
+    # Sets $citefile and $citations defined in translate
+    local($_) = @_;
+    $bibitem_counter = 0;
+    $citefile = $CURRENT_FILE;
+    $citefiles{$bbl_nr} = $citefile;
+    local($dummy,$title);
+    $dummy = &missing_braces unless (
+       (s/$next_pair_pr_rx/$dummy=$2;''/e)
+       ||(s/$next_pair_rx/$dummy=$2;''/e));
+    # MRO: replaced $* with /m
+    s/^\s*$//gm; # Remove empty lines (otherwise will have paragraphs!)
+    s/^\s*//m;
+
+    # Replace non-breaking spaces, particularly in author names.
+#    s/([^\\])~/$1 /g; # Replace non-breaking spaces.
+
+    $_ = &translate_environments($_);
+    $_ = &translate_commands($_);
+
+    # RRM: collect all anchors from initial \label and \index commands
+    local($anchors) = &extract_anchors('',1);
+    $_ = '<DD>'.$_ unless ($_ =~ /^\s*<D(T|D)>/);
+    $citations = join('',"<DL COMPACT>", $_, "</DL>");
+    $citations{$bbl_nr} = $citations;
+    local($br_id);
+    if ((defined &do_cmd_bibname)||$new_command{'bibname'}) {
+       $br_id=++$global{'max_id'};
+       $title = &translate_environments("$O$br_id$C\\bibname$O$br_id$C");
+    } else { $title = $bib_title }
+    if (! $title ) {
+       if ((defined &do_cmd_refname)||$new_command{'refname'}) {
+           $br_id=++$global{'max_id'};
+           $title = &translate_environments("$O$br_id$C\\refname$O$br_id$C");
+       } else { $title = $ref_name }
+    }
+    local($closures,$reopens) = &preserve_open_tags();
+    $toc_sec_title = $title ;
+    local $bib_head = $section_headings{'bibliography'};
+    $_ = join('', $closures
+           , &make_section_heading($title, $bib_head, $anchors)
+           , "$bbl_mark#$bbl_nr#" , $reopens );
+    $bbl_nr++ if $bbl_cnt > 1;
+    $_ =~ s/;SPMnbsp;/ /g;  # replace non-breaking spaces with real ones
+    $_;
+}
+
+# IGNORE - We construct our own index
+sub do_env_theindex { "" }
+
+# This is defined in html.sty
+sub do_env_comment { "" }
+
+
+sub do_env_equation{
+    local($_)=@_;  
+    local($attribs, $border, $no_num);
+    if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+    elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+    if (/\\nonumber/) {
+       $no_num = 1;
+       $_ = &process_undefined_environment($env,$id,$_);
+    } else {
+       $latex_body .= join('', "\n\\setcounter{equation}{"
+                       , $global{'eqn_number'}, "}\n");
+
+       #include equation-number into the key, with HTML 2.0
+#      $_ = join("\n", "%EQNO:".$global{'eqn_number'}, $_)
+       $_ .= "%EQNO:".$global{'eqn_number'}."\n" if ($HTML_VERSION < 2.2);
+
+       $_ = &process_undefined_environment($env,$id,$_);
+       $global{'eqn_number'}++;
+       local($save) = $_;
+       $_ = join('', $save, &post_latex_do_env_equation($eqno_prefix));
+    }
+    if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 
+       join('',"<BR>\n<DIV$env_id ALIGN=\"CENTER\">\n"
+           , &make_table( $border, $attribs, '', '', '', $_ )
+           , "\n<BR CLEAR=\"ALL\">");
+    } elsif ($HTML_VERSION < 2.2 ) { 
+       join('', "\n<P>", $_ , "\n<BR></P>" )
+    } elsif ($HTML_VERSION > 2.1 ) { 
+       join('', "\n<P ALIGN="
+           , ((!$no_num &&($EQN_TAGS =~ /L/))?
+               '"LEFT"':($no_num ?'"CENTER"':'"RIGHT"'))
+           , '>', $_ , "\n<BR></P>" )
+    } else { $_ }
+}
+
+sub do_env_eqnarray{
+    local($_)=@_;
+    local($attribs, $border, $no_num);
+    if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+    elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+    local($contents) = $_;
+#    $_ = join("\n", "%EQNO:".$global{'eqn_number'}, $_)
+#      if ($HTML_VERSION < 3.2);  #include equation-number into the key.
+    $_ .= "%EQNO:".$global{'eqn_number'}."\n" if ($HTML_VERSION < 2.2);
+    $_ = &process_undefined_environment($env,$id,$_);
+    $_ .= &post_latex_do_env_eqnarray($eqno_prefix,$contents);
+    if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 
+       join('',"<BR>\n<DIV ALIGN=\"CENTER\">\n"
+            , &make_table( $border, $attribs, '', '', '', $_ )
+           , "\n<BR CLEAR=\"ALL\">");
+    } elsif ($HTML_VERSION < 2.2 ) { 
+       join('', "\n<P>", $_ , "\n<BR></P>" )
+    } elsif ($HTML_VERSION > 3.1 ) { 
+       join('',"<BR>\n<DIV ALIGN=\"CENTER\">\n", $_ 
+            , "\n</DIV><BR CLEAR=\"ALL\">" );
+    } else {
+       join('', "\n<P ALIGN="
+            , (($EQN_TAGS =~ /L/)? '"LEFT"' : '"RIGHT"')
+            , '>' , $_ , "\n<BR></P>" )
+    }
+}
+
+#RRM: these are needed with later versions, when {eqnarray}
+#  environments are split into <TABLE> cells.
+
+sub protect_array_envs {
+    local($_) = @_;
+    local($cnt, $arraybit, $thisbit, $which) = (0,'','','');
+    # MRO: replaced $* with /m
+    while (/\\(begin|end)\s*(<(<|#)\d+(#|>)>)($sub_array_env_rx)(\*|star)?\2/m ) {
+        $thisbit = $` . $&; $_ = $'; $which = $1;
+        do {
+            # mark rows/columns in nested arrays
+            $thisbit =~ s/;SPMamp;/$array_col_mark/g;
+            $thisbit =~ s/\\\\/$array_row_mark/g;
+            $thisbit =~ s/\\text/$array_text_mark/g;
+            $thisbit =~ s/\\mbox/$array_mbox_mark/g;
+        } if ($cnt > 0);
+        $arraybit .= $thisbit;
+        if ($which =~ /begin/) {$cnt++} else {$cnt--};
+    }
+    $_ = $arraybit . $_;
+
+    local($presub,$thisstack) = '';
+    for (;;) {
+      # find \\s needing protection within \substack commands
+      # a while-loop is simpler syntax, but uses longer strings
+      if ( /(\\substack\s*(<(<|#)\d+(#|>)>)(.|\n)*)\\\\((.|\n)*\2)/m ) {
+        $presub .= $`; $thisstack =$1.${array_row_mark}.$6; $_ = $';
+        # convert all \\s in the \substack
+        $thisstack =~ s/\\\\/${array_row_mark}/og;
+        $presub .= $thisstack;
+        } else { last }
+    }
+    $_ = $presub . $_ if ($presub);
+    $_;
+}
+
+sub revert_array_envs {
+    local($array_contents) = @_;
+    $array_contents =~ s/$array_col_mark/$html_specials{'&'}/go;
+    $array_contents =~ s/$array_row_mark/\\\\/go;
+    $array_contents =~ s/$array_text_mark/\\text/go;
+    $array_contents =~ s/$array_mbox_mark/\\mbox/go;
+    $array_contents;
+}
+
+
+
+sub do_env_tabbing {
+    local($_) = @_;
+    local($attribs, $border);
+    if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+    elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
+    $_ = &tabbing_helper($_);
+    if (/$image_mark/) {
+       local($tab_warning) = 
+          "*** Images are not strictly valid within HTML <pre> tags\n"
+          . "Please change your use of {tabbing} to a {tabular} environment.\n\n";
+          &write_warnings("\n".$tab_warning);
+          print "\n\n **** invalid tabbing environment ***\n";
+          print $tab_warning;
+    }
+    if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 
+       join('',"<BR>\n<DIV$env_id ALIGN=\"CENTER\">\n"
+            , &make_table( $border, $attribs, '', '', '', $_ )
+           , "\n</DIV><BR CLEAR=\"ALL\">");
+    } else { $_ }
+}
+
+sub tabbing_helper {
+    local($_) = @_;
+    s/\\=\s*//go;  # cannot alter the tab-stops
+    s/\t/ /g;      # convert any tabs to spaces
+    # MRO: replaced $* with /m
+    s/(^|\n)[^\n]*\\kill *\n/\n/gm;
+    s/( )? *\n/$1/gm; # retain at most 1 space for a \n
+    # replace \\ by \n ... , ignoring any trailing space
+#    s/\\\\ */\n/gm;
+    # ...but make sure successive \\ do not generate a <P> tag
+#    s/\n( *)?\n/\n&nbsp;\n/gm;
+    s/\\\&gt;//go;
+    s/(^| *([^\\]))\\[>]/$2\t\t/go;
+    s/([^\\])\\>/$1\t\t/go;
+    s/\n$//; s/^\n//;           # strip off leading/trailing \n
+    local($inside_tabbing) = 1;
+    $_ = &translate_commands(&translate_environments($_));
+    "<PRE><TT>\n$_\n</TT></PRE>";
+}
+
+################# Post Processing Latex Generated Images ################
+
+# A subroutine of the form post_latex_do_env_<ENV> can be used to
+# format images that have come back from latex
+
+# Do nothing (avoid the paragraph breaks)
+sub post_latex_do_env_figure { $_[0] }
+sub post_latex_do_env_figurestar { &post_latex_do_env_figure(@_) }
+
+sub post_latex_do_env_table { $_[0] }
+sub post_latex_do_env_tablestar { &post_latex_do_env_table(@_) }
+
+sub post_latex_do_env_equation {
+    local($prefix) = @_;
+    $global{'eqn_number'}+=1;
+    # include equation number at the side of the image -- HTML 3.2
+    if ($HTML_VERSION >= 3.2){
+       join('',"<P ALIGN=\"" , (($EQN_TAGS eq "L") ? "left" : "right")
+               , "\">$EQNO_START" , $prefix 
+               , &translate_commands('\theequation')
+               , "$EQNO_END</P>\n<BR CLEAR=\"all\">" );
+    # </P> creates unwanted space in some browsers, but others need it.
+    } else { "" }
+}
+
+sub do_cmd_theequation {
+    if ($USING_STYLES) {
+       $txt_style{'eqn-number'} = " " unless ($txt_style{'eqn-number'});
+       join('', "<SPAN CLASS=\"eqn-number\">"
+               ,&get_counter_value('eqn_number'),"</SPAN>", $_[0]);
+    } else { join('',&get_counter_value('eqn_number'), $_[0]); }
+}
+
+sub post_latex_do_env_eqnarray {
+    local($prefix,$body) = @_;
+    local($num_string,$line,@lines) = '';
+    local($side) = (($EQN_TAGS eq "L") ? "\"left\"" : "\"right\"" );
+    # MRO: replaced $* with /m
+    @lines = split(/\\\\\\\\/m, $body);
+    $line = pop(@lines);
+    if (!($line=~/^\s*$/)&&!($line =~/\\nonumber/)) {
+       $global{'eqn_number'}++;
+       $num_string .= join('', "<BR><BR>\n" , $EQNO_START , $prefix
+           , &translate_commands('\theequation')
+           , $EQNO_END);
+    }
+    foreach $line (@lines) {
+       next if ($line=~/^\s*$/);
+       $num_string .= "\n<BR>". (($MATH_SCALE_FACTOR > 1.3)? '<BR>' : '')
+                       . "<BR CLEAR=$side>";
+       if (!($line =~/\\(nonumber|(no)?tag)/)) {
+           $global{'eqn_number'}+=1;
+           $num_string .= join('', $EQNO_START , $prefix
+               , &translate_commands('\theequation')
+               , $EQNO_END);
+        }
+    }
+    # include equation numbers at the side of the image -- HTML 3.2
+    if ($HTML_VERSION >= 3.2){
+       "<P ALIGN=\"" . (($EQN_TAGS eq "L") ? "left" : "right")
+           . "\">" . (($DISP_SCALE_FACTOR >= 1.2 ) ? '<BIG>' : '')
+           . ${num_string}
+           . (($DISP_SCALE_FACTOR >= 1.2 ) ? '</BIG>' : '')
+           . "</P>\n<BR CLEAR=\"all\">"
+    # </P> creates unwanted space in some browsers, but others need it.
+    } else { "" };
+}
+
+sub post_latex_do_env_eqnarraystar {
+    local($_) = @_;
+    if (($HTML_VERSION >= 3.2)&&(!$NO_SIMPLE_MATH)){
+       join('', "<BR>\n<DIV ALIGN=\"CENTER\">\n"
+           , $_ , "\n<BR CLEAR=\"ALL\">\n<P>");
+    } elsif (($HTML_VERSION >= 2.2)&&(!$NO_SIMPLE_MATH)) {
+       join('', "\n<BR><P ALIGN=\"CENTER\">\n", $_ , "\n<BR></P>\n<P>");
+    } else {
+       join('', "\n<BR><P>\n", $_ , "\n<BR></P>\n<P>");
+    }
+}
+
+############################ Grouping ###################################
+
+sub do_cmd_begingroup { $latex_body .= "\n\\begingroup\n"; $_[0] }
+sub do_cmd_endgroup { $latex_body .= "\\endgroup\n\n"; $_[0] }
+sub do_cmd_bgroup { $latex_body .= "\n\\bgroup\n"; $_[0] }
+sub do_cmd_egroup { $latex_body .= "\\egroup\n\n"; $_[0] }
+
+sub do_env_tex2html_begingroup {
+    local($_) = @_;
+    $latex_body .= "\\begingroup ";
+    $_ = &translate_environments($_);
+    $_ = &translate_commands($_);
+    $latex_body .= "\\endgroup\n";
+    $_;
+}
+
+sub do_env_tex2html_bgroup {
+    local($_) = @_;
+    $latex_body .= "\\bgroup ";
+    $_ = &translate_environments($_);
+    $_ = &translate_commands($_);
+    $latex_body .= "\\egroup\n";
+    $_;
+}
+
+
+############################ Commands ###################################
+
+# Capitalizes what follows the \sc declaration
+# *** POTENTIAL ERROR ****
+# (This is NOT the correct meaning of \sc in the cases when it
+# is followed by another declaration (e.g. \em).
+# The scope of \sc should be limited to the next occurence of a
+# declaration.
+#sub do_cmd_sc {
+#    local($_) = @_;
+#    local(@words) = split(" ");
+# Capitalize the words which are not commands and do not contain any markers
+#   grep (do {tr/a-z/A-Z/ unless /(^\\)|(tex2html)/}, @words);
+#    grep (do {s/([a-z]+)/<small>\U$1\E<\/small>/g unless /(^\\)|(tex2html)/}, @words);
+#    join(" ", @words);
+#}
+sub do_cmd_sc { &process_smallcaps(@_) }
+sub do_cmd_scshape { &do_cmd_sc(@_) }
+
+# This is supposed to put the font back into roman.
+# Since there is no HTML equivalent for reverting
+# to roman we keep track of the open font tags in
+# the current context and close them.
+# *** POTENTIAL ERROR ****#
+# This will produce incorrect results in the exceptional
+# case where \rm is followed by another context
+# containing font tags of the type we are trying to close
+# e.g. {a \bf b \rm c {\bf d} e} will produce
+#       a <b> b </b> c   <b> d   e</b>
+# i.e. it should move closing tags from the end
+sub do_cmd_rm { # clean
+    my ($str, $ot) = @_;
+    $ot = $open_tags_R unless(defined $ot);
+    return("<\#rm\#>".$str) if ($inside_tabular);
+
+    my ($size,$color,$tags);
+    while (@$ot) {
+       my $next = pop (@$ot);
+       print STDOUT "\n</$next>" if $VERBOSITY > 2;
+       if ($next =~ /$sizechange_rx/) {
+           $size = $next unless ($size);
+       }
+#      if ($next =~ /$colorchange_rx/) {
+#          $color = $next unless ($color);
+#      }
+       $declarations{$next} =~ m|</.*$|;
+       $tags .= $& unless ($` =~ /^<>/);
+    }
+    if ($size) {
+       $declarations{$size} =~ m|</.*$|;
+       $tags .= $` unless ($` =~ /^<>/);
+       push (@$ot,$size);
+       print STDOUT "\n<$size>" if $VERBOSITY > 2;
+    }
+    $tags.$str;
+}
+
+sub do_cmd_rmfamily{ &do_cmd_rm(@_) }
+
+sub do_cmd_textrm { 
+    local($_) = @_;
+    local($text,$br_id)=('','0');
+    $text = &missing_braces unless (
+       (s/$next_pair_pr_rx/$text=$2;$br_id=$1;''/eo)
+       ||(s/$next_pair_rx/$text=$2;$br_id=$1;''/eo));
+    join ('' ,
+         &translate_environments("$O$br_id$C\\rm $text$O$br_id$C")
+         , $_ );
+}
+
+sub do_cmd_emph { 
+    local($_) = @_;
+    local($ifstyle,$join_tags) = ('',join(',',@$open_tags_R));
+    $join_tags =~ s/(^|,)(text)?(it|rm|normalfont)/$if_style=$3;''/eg; 
+    if ($if_style =~ /it/) {
+       ($ifstyle,$join_tags) = ('',join(',',@$open_tags_R));
+       $join_tags =~ s/(^|,)(text)?(bf|rm|normalfont)/$if_style=$3;''/eg; 
+       if ($if_style =~ /bf/) { &do_cmd_textrm(@_) }
+       else { &do_cmd_textbf(@_) }
+    } else { &do_cmd_textit(@_) }
+}
+
+#RRM: These cope with declared commands for which one cannot
+#     simply open a HTML single tag.
+#     The do_cmd_... gets found before the $declaration .
+
+sub do_cmd_upshape{&declared_env('upshape',$_[0],$tex2html_deferred)}
+sub do_cmd_mdseries{&declared_env('mdseries',$_[0],$tex2html_deferred)}
+sub do_cmd_normalfont{&declared_env('normalfont',$_[0],$tex2html_deferred)}
+
+
+# This is supposed to put the font back into normalsize.
+# Since there is no HTML equivalent for reverting
+# to normalsize we keep track of the open size tags in
+# the current context and close them.
+sub do_cmd_normalsize { # clean
+    my ($str, $ot) = @_;
+    $ot = $open_tags_R unless(defined $ot);
+
+    my ($font,$fontwt,$closures,$reopens,@tags);
+
+    while (@$ot) {
+       my $next = pop @$ot;
+       $declarations{$next} =~ m|</.*$|;
+       my ($pre,$post) = ($`,$&);
+       if ($post =~ /$block_close_rx|$all_close_rx/ ) {
+           push (@$ot, $next);
+           last;
+       }
+       $closures .= $post unless ($pre =~ /^<>/);
+       print STDOUT "\n</$next>" if $VERBOSITY > 2;
+
+       if ($next =~ /$fontchange_rx/) {
+           $font = $next unless ($font);
+       } elsif ($next =~ /$fontweight_rx/) {
+           $fontwt = $next unless ($fontwt);
+       } elsif ($next =~ /$sizechange_rx/) {
+           # discard it
+       } else {
+           unshift (@tags, $next);
+           print STDOUT "\n<<$next>" if $VERBOSITY > 2;
+           $reopens .= $pre unless ($pre =~ /^<>/);
+       }
+    }
+    push (@$ot, @tags);
+    if ($font) {
+       $declarations{$font} =~ m|</.*$|;
+       $reopens .= $` unless ($` =~ /^<>/);
+       push (@$ot,$font);
+       print STDOUT "\n<$font>" if $VERBOSITY > 2;
+    }
+    if ($fontwt) {
+       $declarations{$fontwt} =~ m|</.*$|;
+       $reopens .= $` unless ($` =~ /^<>/);
+       push (@$ot,$fontwt);
+       print STDOUT "\n<$fontwt>" if $VERBOSITY > 2;
+    }
+    join('', $closures, $reopens, $str);
+}
+
+
+
+#JCL(jcl-tcl)
+# changed everything
+#
+sub do_cmd_title {
+    local($_) = @_;
+    &get_next_optional_argument;
+    local($making_title,$next) = (1,'');
+    $next = &missing_braces unless (
+       (s/$next_pair_pr_rx/$next = $2;''/eo)
+       ||(s/$next_pair_rx/$next = $2;''/eo));
+    $t_title = &translate_environments($next);
+    $t_title = &translate_commands($t_title);
+#    $toc_sec_title = &simplify(&translate_commands($next));
+    $toc_sec_title = &purify(&translate_commands($next));
+    $TITLE = (($toc_sec_title)? $toc_sec_title : $default_title)
+       unless ($TITLE && !($TITLE =~ /^($default_title|\Q$FILE\E)$/));
+#    $TITLE = &purify($TITLE);
+
+    #RRM: remove superscripts inserted due to \thanks
+    $TITLE =~ s/<A[^>]*><SUP>\d+<\/SUP><\/A>/$1/g;
+    $_;
+}
+
+sub do_cmd_author {
+    local($_) = @_;
+    &get_next_optional_argument;
+    my $next;
+    $next = &missing_braces unless (
+       (s/$next_pair_pr_rx/$next = $2;''/seo)
+       ||(s/$next_pair_rx/$next = $2;''/seo));
+    local($after) = $_;
+    if ($next =~ /\\and/) {
+       my @author_list = split(/\s*\\and\s*/, $next);
+       my $t_author, $t_affil, $t_address;
+       foreach (@author_list) {
+           $t_author = &translate_environments($_);
+           $t_author =~ s/\s+/ /g;
+           $t_author = &simplify(&translate_commands($t_author));
+           ($t_author,$t_affil,$t_address) = split (/\s*<BR>s*/, $t_author);
+           push @authors, $t_author;
+           push @affils, $t_affil;
+           push @addresses, $t_address;
+       }
+    } else {
+       $_ = &translate_environments($next);
+       $next = &translate_commands($_);
+       ($t_author) = &simplify($next);
+       ($t_author,$t_affil,$t_address) = split (/\s*<BR>s*/, $t_author);
+       push @authors, $t_author;
+       push @affils, $t_affil if $t_affil;
+       push @addresses, $t_address if $t_address;
+    }
+    $after;
+}
+
+sub do_cmd_address {
+    local($_) = @_;
+    &get_next_optional_argument;
+    local($next);
+    $next = &missing_braces unless (
+       (s/$next_pair_pr_rx/$next = $&;''/eo)
+       ||(s/$next_pair_rx/$next = $&;''/eo));
+    ($t_address) = &simplify(&translate_commands($next));
+    push @addresses, $t_address;
+    $_;
+}
+
+sub do_cmd_institute {
+    local($_) = @_;
+    &get_next_optional_argument;
+    local($next);
+    $next = &missing_braces unless (
+       (s/$next_pair_pr_rx/$next = $&;''/eo)
+       ||(s/$next_pair_rx/$next = $&;''/eo));
+    ($t_institute) = &simplify(&translate_commands($next));
+    push @affils, $t_institute;
+    $_;
+}
+
+sub do_cmd_dedicatory {
+    local($_) = @_;
+    &get_next_optional_argument;
+    local($next);
+    $next = &missing_braces unless (
+       (s/$next_pair_pr_rx/$next = $&;''/eo)
+       ||(s/$next_pair_rx/$next = $&;''/eo));
+    ($t_affil) = &simplify(&translate_commands($next));
+    push @affils, $t_affil;
+    $_;
+}
+
+sub do_cmd_email {
+    local($_) = @_;
+    local($next,$target)=('','notarget');
+    $next = &missing_braces unless (
+       (s/$next_pair_pr_rx/$next = $2;''/eo)
+       ||(s/$next_pair_rx/$next = $2;''/eo));
+    local($mail) = &translate_commands($next);
+    ($t_email) = &make_href("mailto:$mail","$mail");
+    push @emails, $t_email;
+    $_;
+}
+
+sub do_cmd_authorURL {
+    local($_) = @_;
+    local($next);
+    $next = &missing_braces unless (
+       (s/$next_pair_pr_rx/$next = $2;''/eo)
+       ||(s/$next_pair_rx/$next = $2;''/eo));
+    ($t_authorURL) =  &translate_commands($next);
+    push @authorURLs, $t_authorURL;
+    $_;
+}
+
+sub do_cmd_date {
+    local($_) = @_;
+    local($next);
+    $next = &missing_braces unless (
+       (s/$next_pair_pr_rx/$next = $&;''/eo)
+       ||(s/$next_pair_rx/$next = $&;''/eo));
+    ($t_date) = &translate_commands($next);
+    $_;
+}
+
+sub make_multipleauthors_title {
+    local($alignc, $alignl) = (@_);
+    local($t_author,$t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL)
+       = ('','','','','','','');
+    local ($t_title,$auth_cnt) = ('',0);
+    if ($MULTIPLE_AUTHOR_TABLE) {
+       $t_title = '<TABLE' .($USING_STYLES? ' CLASS="author_info_table"' : '')
+               .' WIDTH="90%" ALIGN="CENTER" CELLSPACING=15>'
+               ."\n<TR VALIGN=\"top\">";
+    }
+    foreach $t_author (@authors) {
+       $t_affil = shift @affils;
+       $t_institute = ''; # shift @institutes;
+       $t_address = shift @addresses;
+       $t_email = shift @emails;
+       $t_authorURL = shift @authorURLs;
+       if ($MULTIPLE_AUTHOR_TABLE) {
+           if ($auth_cnt == $MAX_AUTHOR_COLS) {
+               $t_title .= join("\n", '</TR><TR>', '');
+               $auth_cnt -= $MAX_AUTHOR_COLS;
+           }
+           $t_title .= join("\n"
+               , '<TD>'
+               , &make_singleauthor_title($alignc, $alignl ,$t_author
+                   , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL)
+               , '</TD>' );
+           ++$auth_cnt;
+       } else {
+           $t_title .= &make_singleauthor_title($alignc, $alignl ,$t_author
+               , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL);
+       }
+    }
+    if ($MULTIPLE_AUTHOR_TABLE) {
+       $t_title .= "\n</TR></TABLE>\n";
+    }
+    $t_title;
+}
+
+sub do_cmd_maketitle {
+    local($_) = @_;
+    local($the_title) = '';
+    local($alignc, $alignl);
+    if ($HTML_VERSION > 2.1) {
+       $alignc = " ALIGN=\"CENTER\""; 
+       $alignl = " ALIGN=\"LEFT\""; 
+       $alignl = $alignc if ($MULTIPLE_AUTHOR_TABLE);
+    }
+    if ($t_title) {
+       $the_title .= "<H1$alignc>$t_title</H1>";
+    } else { &write_warnings("\nThis document has no title."); }
+    if (($#authors >= 1)||$MULTIPLE_AUTHOR_TABLE) {
+       $the_title .= &make_multipleauthors_title($alignc,$alignl);
+       if ($t_date&&!($t_date=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) {
+           $the_title .= "\n<P$alignc><STRONG>$t_date</STRONG></P>";}
+    } else {
+       $the_title .= &make_singleauthor_title($alignc,$alignl ,$t_author
+           , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL);
+    }
+    $the_title . $_ ;
+}
+
+sub make_singleauthor_title {
+    local($alignc, $alignl , $t_author
+       , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL) = (@_);
+    my $t_title = '';
+    my ($s_author_info, $e_author_info) = ('<DIV','</DIV>');
+    $s_author_info .= ($USING_STYLES ? ' CLASS="author_info"' : '').'>';
+
+    if ($t_author) {
+       if ($t_authorURL) {
+           local($href) = &translate_commands($t_authorURL);
+           $href = &make_named_href('author'
+                       , $href, "<STRONG>${t_author}</STRONG>");
+           $t_title .= "\n<P$alignc>$href</P>";
+       } else {
+           $t_title .= "\n<P$alignc><STRONG>$t_author</STRONG></P>";
+       }
+    } else { &write_warnings("\nThere is no author for this document."); }
+
+    if ($t_institute&&!($t_institute=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) {
+       $t_title .= "\n<P$alignc><SMALL>$t_institute</SMALL></P>";}
+    if ($t_affil&&!($t_affil=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) {
+       $t_title .= "\n<P$alignc><I>$t_affil</I></P>";}
+    if ($t_date&&!($t_date=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) {
+       $t_title .= "\n<P$alignc><STRONG>$t_date</STRONG></P>";}
+    if ($t_address&&!($t_address=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) {
+       $t_title .= "\n<P$alignl><SMALL>$t_address</SMALL></P>";
+    }  # else { $t_title .= "\n<P$alignl>"}
+    if ($t_email&&!($t_email=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) {
+       $t_title .= "\n<P$alignl><SMALL>$t_email</SMALL></P>";
+    }  # else { $t_title .= "</P>" }
+    join("\n", $s_author_info, $t_title, $e_author_info);
+}
+
+sub do_cmd_abstract {
+    local($_) = @_;
+    local($abstract);
+    $abstract = &missing_braces unless (
+       (s/$next_pair_pr_rx/$abstract = $&;''/eo)
+       ||(s/$next_pair_rx/$abstract = $&;''/eo));
+    join('', &make_abstract($abstract), $_);
+}
+
+sub make_abstract {
+    local($_) = @_;
+    # HWS  Removed emphasis (hard to read)        
+    $_ = &translate_environments($_);
+    $_ = &translate_commands($_);
+    local($title);
+    if ((defined &do_cmd_abstractname)||$new_command{'abstractname'}) {
+       local($br_id)=++$global{'max_id'};
+       $title = &translate_environments("$O$br_id$C\\abstractname$O$br_id$C");
+    } else { $title = $abs_title }
+    local($env_id) = " CLASS=\"ABSTRACT\"" if ($USING_STYLES);
+    join('',"\n<H3>", $title, ":</H3>\n"
+       , (($HTML_VERSION > 3)? "<DIV$env_id>" : "<P>"), $_ 
+       , (($HTML_VERSION > 3)? "</DIV>" : "</P>"), "\n<P>");
+}
+
+sub set_default_language {
+    # MRO: local($lang,*_) = @_;
+    my $lang = shift;
+    push(@language_stack, $default_language);
+    $default_language = $lang;
+    $_[0] .= '\popHtmlLanguage';
+}
+
+sub do_cmd_popHtmlLanguage {
+    $default_language = pop(@language_stack);
+    $_[0];
+}
+
+sub do_cmd_today {
+    local($lang);
+    if ($PREAMBLE) {
+       $lang = $TITLES_LANGUAGE || $default_language ;
+    } else {
+       $lang = $current_language || $default_language ;
+    }
+    local($today) = $lang . '_today';
+    if (defined &$today) { join('', eval "&$today()", $_[0]) }
+    else { join('', &default_today(), $_[0]) }
+}
+
+sub default_today {
+    #JKR: Make it more similar to LaTeX
+    ## AYS: moved french-case to styles/french.perl
+    my $today = &get_date();
+
+    $today =~ s|(\d+)/0?(\d+)/|$Month[$1] $2, |;
+    join('',$today,$_[0]);
+}
+
+sub do_cmd_textbackslash { join('','&#92;', $_[0]);}
+sub do_cmd_textbar { join('','|', $_[0]);}
+sub do_cmd_textless { join('',';SPMlt;', $_[0]);}
+sub do_cmd_textgreater { join('',';SPMgt;', $_[0]);}
+sub do_cmd_textasciicircum { join('','&#94;', $_[0]);}
+sub do_cmd_textasciitilde { join('','&#126;', $_[0]);}
+sub do_cmd_textquoteleft { join('','&#96;', $_[0]);}
+sub do_cmd_textquoteright { join('','&#39;', $_[0]);}
+
+sub do_cmd_textcompwordmark { join('','', $_[0]);}
+sub do_cmd_texttrademark { join('','<SUP><SMALL>TM</SMALL></SUP>', $_[0]);}
+
+sub do_cmd_textsubscript   { &make_text_supsubscript('SUB',$_[0]);} 
+sub do_cmd_textsuperscript { &make_text_supsubscript('SUP',$_[0]);}
+
+sub make_text_supsubscript { 
+    local ($supsub, $_) = (@_);
+    my $arg = '';
+    $arg = &missing_braces unless (
+       (s/$next_pair_pr_rx/$arg = $&;''/eo)
+       ||(s/$next_pair_rx/$arg = $&;''/eo));
+    $arg = &translate_commands($arg) if ($arg =~ m!\\!);
+    join('', "<$supsub>", $arg, "</$supsub>", $_);
+}
+
+sub do_cmd_textcircled { 
+    local ($_) = (@_);
+    my $arg = '';
+    $arg = &missing_braces unless (
+       (s/$next_pair_pr_rx/$arg = $&;''/eo)
+       ||(s/$next_pair_rx/$arg = $&;''/eo));
+    my $after = $_;
+    join('', &process_undefined_environment("tex2html_nomath_inline"
+          , ++$global{'max_id'}
+          , "\\vbox{\\kern3pt\\textcircled{$arg}}" )
+       , $after );
+}
+
+# these can be overridded in charset (.pl) extension files:
+sub do_cmd_textemdash { join('','---', $_[0]);}
+sub do_cmd_textendash { join('','--', $_[0]);}
+#sub do_cmd_exclamdown { join('','', $_[0]);}
+#sub do_cmd_questiondown { join('','', $_[0]);}
+sub do_cmd_textquotedblleft { join('',"``", $_[0]);}
+sub do_cmd_textquotedblright { join('',"''", $_[0]);}
+sub do_cmd_textbullet { join('','*', $_[0]);}
+sub do_cmd_textvisiblespace { join('','_', $_[0]);}
+
+sub do_cmd_ldots {
+    join('',(($math_mode&&$USE_ENTITY_NAMES) ? ";SPMldots;" : "..."),$_[0]);
+}
+
+sub do_cmd_dots {
+    join('',(($math_mode&&$USE_ENTITY_NAMES) ? ";SPMldots;" : "..."),$_[0]);
+}
+
+sub do_cmd_hrule {
+    local($_) = @_;
+    &ignore_numeric_argument;
+    #JKR: No need for <BR>
+    local($pre,$post) = &minimize_open_tags('<HR>');
+    join('',$pre,$_);
+}
+
+#sub do_cmd_hrulefill {
+#    "<HR ALIGN=\"right\">\n<BR CLEAR=\"right\">";
+#}
+
+sub do_cmd_linebreak {
+    local($num,$dum) = &get_next_optional_argument;
+    if (($num)&&($num<4)) { return $_[0] }
+    join('',"<BR>", $_[0]);
+}
+
+sub do_cmd_pagebreak {
+    local($_) = @_;
+    local($num,$dum) = &get_next_optional_argument;
+    if (($num)&&($num<4)) { return($_) }
+    elsif (/^ *\n *\n/) {
+       local($after) = $';
+       local($pre,$post) = &minimize_open_tags("<BR>\n<P>");
+       join('',$pre, $')
+    } else { $_ }
+}
+
+
+sub do_cmd_newline { join('',"<BR>", $_[0]); }
+# this allows for forced newlines in tables, etc.
+sub do_cmd_endgraf { join('',"<BR>", $_[0]); }
+
+sub do_cmd_space { join(''," ",$_[0]); }
+sub do_cmd_enspace { join('',"\&nbsp;",$_[0]); }
+sub do_cmd_quad { join('',"\&nbsp;"x4,$_[0]); }
+sub do_cmd_qquad { join('',"\&nbsp;"x8,$_[0]); }
+
+sub do_cmd_par {
+    local ($_) = @_;
+    my ($pre,$post) = &preserve_open_tags();
+    my ($spar, $lcode) = ("\n<P", '');
+    if (($USING_STYLES) &&(!($default_language eq $TITLES_LANGUAGE))) {
+       $lcode = &get_current_language();
+       $spar .= $lcode if $lcode;
+    }
+    join('', $pre, $spar, ">\n",$post,$_);
+}
+
+sub do_cmd_medskip {
+    local ($_) = @_;
+    local($pre,$post) = &preserve_open_tags();
+    join('',$pre,"\n<P><BR>\n",$post,$_);
+}
+
+sub do_cmd_smallskip {
+    local ($_) = @_;
+    local($pre,$post) = &preserve_open_tags();
+    join('',$pre,"\n<P></P>\n",$post,$_);
+}
+
+sub do_cmd_bigskip {
+    local ($_) = @_;
+    local($pre,$post) = &preserve_open_tags();
+    join('',$pre,"\n<P><P><BR>\n",$post,$_);
+}
+
+# MEH: Where does the slash command come from?
+# sub do_cmd_slash {
+#    join('',"/",$_[0]);
+#}
+sub do_cmd_esc_slash { $_[0]; }
+sub do_cmd_esc_hash { "\#". $_[0]; }
+sub do_cmd_esc_dollar { "\$". $_[0]; }
+sub do_cmd__at_ { $_[0]; }
+sub do_cmd_lbrace { "\{". $_[0]; }
+sub do_cmd_rbrace { "\}". $_[0]; }
+sub do_cmd_Vert { "||". $_[0]; }
+sub do_cmd_backslash { "\\". $_[0]; }
+
+#RRM: for subscripts outside math-mode
+# e.g. in Chemical formulae
+sub do_cmd__sub {
+    local($_) = @_;
+    local($next);
+    $next = &missing_braces unless (
+        (s/$next_pair_pr_rx/$next = $2;''/e)
+        ||(s/$next_pair_rx/$next = $2;''/e));
+    join('',"<SUB>",$next,"</SUB>",$_);   
+}
+
+#JCL(jcl-del) - the next two ones must only have local effect.
+# Yet, we don't have a mechanism to revert such changes after
+# a group has closed.
+#
+sub do_cmd_makeatletter {
+    $letters =~ s/@//;
+    $letters .= '@';
+    &make_letter_sensitive_rx;
+    $_[0];
+}
+
+sub do_cmd_makeatother {
+    $letters =~ s/@//;
+    &make_letter_sensitive_rx;
+    $_[0];
+}
+
+
+################## Commands to be processed by Latex #################
+#
+# The following commands are passed to Latex for processing.
+# They cannot be processed at the same time as normal commands
+# because their arguments must be left untouched by the translator.
+# (Normally the arguments of a command are translated before the
+# command itself).
+#
+# In fact, it's worse:  it is not correct to process these
+# commands after we process environments, because some of them
+# (for instance, \parbox) may contain unknown or wrapped
+# environments.  If math mode occurs in a parbox, the
+# translate_environments routine should *not* process it, lest
+# we encounter the lossage outlined above.
+#
+# On the other hand, it is not correct to process these commands
+# *before* we process environments, or figures containing
+# parboxes, etc., will be mishandled.
+#
+# RRM: (added for V97.1) 
+#  \parbox now uses the  _wrap_deferred  mechanism, and has a  do_cmd_parbox
+#  subroutine defined. This means that environments where parboxes are
+#  common (.g. within table cells), can detect the \parbox command and
+#  adjust the processing accordingly.
+#
+# So, the only way to handle these commands is to wrap them up
+# in null environments, as for math mode, and let translate_environments
+# (which can handle nesting) figure out which is the outermost.
+#
+# Incidentally, we might as well make these things easier to configure...
+
+sub process_commands_in_tex {
+    local($_) = @_;
+    local($arg,$tmp);
+    foreach (/.*\n?/g) {
+       chop;
+       # For each line
+       local($cmd, @args) = split('#',$_);
+       next unless $cmd;
+       $cmd =~ s/ //g;
+
+       # skip if a proper implementation already exists
+       $tmp = "do_cmd_$cmd";
+       next if (defined &$tmp);
+
+       # Build routine body ...
+       local ($body, $code, $thisone) = ("", "");
+
+       # alter the pattern here to debug particular commands
+#      $thisone = 1 if ($cmd =~ /mathbb/);
+
+       print "\n$cmd: ".scalar(@args)." arguments" if ($thisone);
+       foreach $arg (@args) {
+           print "\nARG: $arg" if ($thisone);
+           print "\nARG: $next_pair_rx" if ($thisone);
+           if ($arg =~ /\{\}/) {
+# RRM: the $` is surely wrong, allowing no error-checking.
+# Use <<...>> for specific patterns
+#              $body .= '$args .= "$`$&" if s/$next_pair_rx//o;'."\n"; 
+               $body .= '$args .= join("","{", &missing_braces, "}") unless ('."\n";
+               $body .= '  (s/$next_pair_pr_rx/$args.=$`.$&;""/es)'."\n";
+               $body .= '  ||(s/$next_pair_rx/$args.=$`.$&;""/es));'."\n";
+               print "\nAFTER:$'" if (($thisone)&&($'));
+               $body .= $' if ($');
+           } elsif ($arg =~ /\[\]/) {
+               $body .= '($dummy, $pat) = &get_next_optional_argument;'
+                   . '$args .= $pat;'."\n";
+               print "\nAFTER:$'" if (($thisone)&&($'));
+               $body .= $' if ($');
+           } elsif ($arg =~ /^\s*\\/) {                    
+               $body .= '($dummy, $pat) = &get_next_tex_cmd;'
+                   . '$args .= $pat;'."\n";
+               print "\nAFTER:$'" if (($thisone)&&($'));
+               $body .= $' if ($');
+           } elsif ($arg =~ /<<\s*/) {
+               $arg = $';
+               if ($arg =~ /\s*>>/) {
+                    # MRO: replaced $* with /m
+                   $body .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n"
+#                  $body .= '$args .= "$`$&" if (/\\\\'.$`.'/);' . "\n"
+                       . "\$_ = \$\';\n";
+                   print "\nAFTER:$'" if (($thisone)&&($'));
+                   $body .= $' if ($');
+               } else { $body .= $arg ; }
+           } else {
+               print "\nAFTER:$'" if (($thisone)&&($arg));
+               $body .= $arg ;
+           }
+       }
+
+       # Generate a new subroutine
+       local($padding) = " ";
+       $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/));
+       $code = "sub wrap_cmd_$cmd {" . "\n"
+           . 'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";' . "\n"
+           . $body
+           . (($thisone)? "print STDERR \"\\n$cmd:\".\$args.\"\\n\";\n" : '')
+           . '(&make_wrapper(1).$cmd'
+           . ($padding ? '"'.$padding.'"' : '')
+           . '.$args.&make_wrapper(0), $_)}'
+           . "\n";
+       print "\nWRAP_CMD: $code " if ($thisone); # for debugging
+       eval $code; # unless ($thisone);
+       print STDERR "\n*** sub wrap_cmd_$cmd  failed: $@" if ($@);
+
+       # And make sure the main loop will catch it ...
+#      $raw_arg_cmds{$cmd} = 1;
+       ++$raw_arg_cmds{$cmd};
+    }
+}
+
+sub process_commands_nowrap_in_tex {
+    local($_) = @_;
+    local($arg);
+    foreach (/.*\n?/g) {
+       chop;
+       local($cmd, @args) = split('#',$_);
+       next unless $cmd;
+       $cmd =~ s/ //g;
+       # Build routine body ...
+       local ($bodyA, $codeA, $bodyB, $codeB, $thisone) = ("", "", "", "");
+
+       # alter the pattern here to debug particular commands
+#      $thisone = 1 if ($cmd =~ /epsf/);
+
+       print "\n$cmd: ".scalar(@args)." arguments" if ($thisone);
+       foreach $arg (@args) {
+           print "\nARG: $arg" if ($thisone);
+           if ($arg =~ /\{\}/) {
+#              $bodyA .= '$args .= "$`"."$&" if (s/$any_next_pair_rx//);'."\n";
+               $bodyA .= 'if (s/$next_pair_rx//s){$args.="$`"."$&"; $_='."\$'};\n";
+               $bodyB .= '$args .= &missing_braces'."\n unless (";
+               $bodyB .= '(s/$any_next_pair_pr_rx/$args.=$`.$&;\'\'/eo)'."\n";
+               $bodyB .= '  ||(s/$any_next_pair_rx/$args.=$`.$&;\'\'/eo));'."\n";
+               print "\nAFTER:$'" if (($thisone)&&($'));
+#              $bodyA .= $'.";\n" if ($');
+               $bodyB .= $'.";\n" if ($');
+           } elsif ($arg =~ /\[\]/) {
+               $bodyA .= '($dummy, $pat) = &get_next_optional_argument;'
+                   . '$args .= $pat;'."\n";
+               print "\nAFTER:$'" if (($thisone)&&($'));
+#              $bodyA .= $'.";\n" if ($');
+               $bodyB .= $'.";\n" if ($');
+           } elsif ($arg =~ /^\s*\\/) {                    
+               $bodyA .= '($dummy, $pat) = &get_next_tex_cmd;'
+                   . '$args .= $pat;'."\n";
+               $bodyB .= '($dummy, $pat) = &get_next_tex_cmd;'
+                   . '$args .= $pat;'."\n";
+               print "\nAFTER:$'" if (($thisone)&&($'));
+               $bodyA .= $'.";\n" if ($');
+               $bodyB .= $'.";\n" if ($');
+           } elsif ($arg =~ /<<\s*/) {
+               $arg = $';
+               if ($arg =~ /\s*>>/) {
+                    # MRO: replaced $* with /m
+                   $bodyA .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n"
+#                  $bodyA .= '$args .= $`.$& if (/\\\\'.$`.'/);' . "\n"
+                       . "\$_ = \$\';\n";
+                   $bodyB .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n"
+                       . "\$_ = \$\';\n";
+                   print "\nAFTER:$'" if (($thisone)&&($'));
+#                  $bodyA .= $'.";\n" if ($');
+                   $bodyB .= $'.";\n" if ($');
+               } else { 
+                   print "\nAFTER:$arg" if (($thisone)&&($arg));
+#                  $bodyA .= $arg.";\n" if ($arg);
+                   $bodyB .= $arg.";\n" if ($arg);
+               }
+           } else { 
+               print "\nAFTER:$arg" if (($thisone)&&($arg));
+               $bodyA .= '$args .= '.$arg.";\n" if ($');
+               $bodyB .= $arg.";\n" if ($'); 
+           }
+       }
+       local($padding) = " ";
+       $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/));
+       # Generate 2 new subroutines
+       $codeA = "sub wrap_cmd_$cmd {" . "\n"
+           .'local($cmd, $_) = @_; local($args, $dummy, $pat) = "";'."\n"
+           . $bodyA
+           . (($thisone)? "print \"\\nwrap $cmd:\\n\".\$args.\"\\n\";\n" : '')
+           . '(&make_nowrapper(1)."\n".$cmd.'."\"$padding\""
+           . '.$args.&make_nowrapper(0)," ".$_)}'
+           ."\n";
+       print "\nWRAP_CMD: $codeA " if ($thisone); # for debugging
+       eval $codeA;
+       print STDERR "\n\n*** sub wrap_cmd_$cmd  failed: $@\n" if ($@);
+       $codeB = "do_cmd_$cmd";
+       do {
+           $bodyB = '"";' if !($bodyB);
+           $codeB = "sub do_cmd_$cmd {" . "\n"
+               . 'local($_,$ot) = @_;'."\n"
+               . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'."\n"
+               . 'local($cmd,$args,$dummy,$pat)=("'.$cmd.'","","","");'."\n"
+               . $bodyB
+               . (($thisone)? "print \"\\ndo $cmd:\".\$args.\"\\n\";\n" : '')
+#              . '$latex_body.="\\n".&revert_to_raw_tex("'."\\\\$cmd$padding".'$args")."\\n\\n";'
+               . "\$_;}\n";
+           print STDOUT "\nDO_CMD: $codeB " if ($thisone); # for debugging
+           eval $codeB;
+           print STDERR "\n\n*** sub do_cmd_$cmd  failed: $@\n" if ($@);
+       } unless (defined &$codeB );
+
+       # And make sure the main loop will catch it ...
+#      $raw_arg_cmds{$cmd} = 1;
+       ++$raw_arg_cmds{$cmd};
+    }
+}
+
+sub process_commands_wrap_deferred {
+    local($_) = @_;
+    local($arg,$thisone);
+    foreach (/.*\n?/g) {
+       chop;
+       local($cmd, @args) = split('#',$_);
+       next unless $cmd;
+       $cmd =~ s/ //g;
+       # Build routine body ...
+       local ($bodyA, $codeA, $bodyB, $codeB, $after, $thisone);
+
+       # alter the pattern here to debug particular commands
+#      $thisone = 1 if ($cmd =~ /selectlanguage/);
+
+       print "\n$cmd: ".scalar(@args)." arguments" if ($thisone);
+       foreach $arg (@args) {
+           print "\nARG: $arg" if ($thisone);
+           if ($arg =~ /\{\}/) {
+#              $bodyA .= '$args .= "$`$&" if (s/$any_next_pair_rx//o);';
+               $bodyA .= '$args .= "$`$&" if (s/$next_pair_rx//so);';
+               $after = $';
+               print "\nAFTER:$'" if (($thisone)&&($'));
+           } elsif ($arg =~ /\[\]/) {
+               $bodyA .= '($dummy, $pat) = &get_next_optional_argument;' .
+                   "\n". '$args .= $pat;';
+               $after = $';
+               print "\nAFTER:$'" if (($thisone)&&($'));
+           } elsif ($arg =~ /^\s*\\/) {                    
+               $bodyA .= '($dummy, $pat) = &get_next_tex_cmd;'
+                   . '$args .= $pat;'."\n";
+               print "\nAFTER:$'" if (($thisone)&&($'));
+               $bodyA .= $'.";\n" if ($');
+           } elsif (/<<\s*([^>]*)[\b\s]*>>/) {
+               local($endcmd, $afterthis) = ($1,$');
+               $afterthis =~ s/(^\s*|\s*$)//g;
+               $endcmd =~ s/\\/\\\\/g;
+               $bodyA .= "\n". 'if (/'.$endcmd.'/) { $args .= $`.$& ; $_ = $\' };';
+               $after .= $afterthis if ($afterthis);
+               print "\nAFTER:$'" if (($thisone)&&($'));
+           } else { 
+               print "\nAFTER:$arg" if (($thisone)&&($arg));
+                $bodyB .= $arg.";\n" ; $after = ''
+            }
+           $after =~ s/(^\s*|\s*$)//g if ($after);
+           $bodyB .= $after . ";" if ($after);
+           $bodyA .= "\$args .= ".$after . ";" if ($after);
+       }
+       local($padding) = " ";
+       $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/));
+       # Generate 2 new subroutines
+       $codeA = "sub wrap_cmd_$cmd {" . "\n"
+           .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";'."\n"
+           . $bodyA #. ($bodyA ? "\n" : '')
+           . (($thisone)? ";print \"\\nwrap $cmd:\".\$args.\"\\n\";\n" : '')
+           .'(&make_deferred_wrapper(1).$cmd.'.$padding
+               .'$args.&make_deferred_wrapper(0),$_)}'
+           ."\n";
+       print STDERR "\nWRAP_CMD: $codeA " if ($thisone); # for debugging
+       eval $codeA;
+       print STDERR "\n\n*** sub wrap_cmd_$cmd  failed: $@\n" if ($@);
+
+       #RRM: currently these commands only go to LaTeX or access counters.
+       #   They could be implemented more generally, as below with  do_dcmd_$cmd
+       #   requiring replacement to be performed before evaluation.
+       $codeB = "sub do_dcmd_$cmd {" . "\n"
+           .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";'."\n"
+           . $bodyA . "\n" 
+            . (($thisone)? ";print \"\\ndo_def $cmd:\".\$args.\"\\n\";\n" : '')
+            . $bodyB . "}" . "\n";
+       print "\nDEF_CMD: $codeB " if ($thisone); # for debugging
+       local($tmp) = "do_cmd_$cmd";
+       eval $codeB unless (defined &$tmp);
+       print STDERR "\n\n*** sub do_dcmd_$cmd  failed: $@\n" if ($@);
+
+       # And make sure the main loop will catch it ...
+#      $raw_arg_cmds{$cmd} = 1;
+       ++$raw_arg_cmds{$cmd};
+    }
+}
+
+sub process_commands_inline_in_tex {
+    local($_) = @_;
+    foreach (/.*\n?/g) {
+       chop;
+       local($cmd, @args) = split('#',$_);
+       next unless $cmd;
+       $cmd =~ s/ //g;
+       # Build routine body ...
+       local ($body, $code, $thisone) = ("", "");
+
+       # uncomment and alter the pattern here to debug particular commands
+#      $thisone = 1 if ($cmd =~ /L/);
+
+       print "\n$cmd: ".scalar(@args)." arguments" if ($thisone);
+       foreach (@args) {
+           print "\nARG: $_" if ($thisone);
+           if (/\{\}/) {
+#              $body .= '$args .= $`.$& if (/$any_next_pair_rx/);' . "\n"
+#                  . "\$_ = \$\';\n";
+               $body .= '$args .= $`.$& if (s/$next_pair_rx//s);' . "\n"
+           } elsif (/\[\]/) {
+               $body .= 'local($dummy, $pat) = &get_next_optional_argument;' .
+                   "\n". '$args .= $pat;';
+           } elsif ($arg =~ /^\s*\\/) {                    
+               $body .= '($dummy, $pat) = &get_next_tex_cmd;'
+                   . '$args .= $pat;'."\n";
+               print "\nAFTER:$'" if (($thisone)&&($'));
+               $body .= $'.";\n" if ($');
+           } elsif (/<<\s*/) {
+               $_ = $';
+               if (/\s*>>/) {
+                    # MRO: replaced $* with /m
+                   $body .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n"
+                       . "\$_ = \$\';\n"
+               } else { $body .= $_.";\n" ; }
+           } else { $body .= $_.";\n" ; }
+       }
+       local($padding) = " ";
+       $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/));
+       # Generate a new subroutine
+       my $itype = ($cmd =~ /^f.*box$/ ? 'inline' : 'nomath');
+       $code = "sub wrap_cmd_$cmd {" . "\n"
+           .'local($cmd, $_) = @_; local ($args) = "";' . "\n"
+           . $body . "\n"
+            . (($thisone)? ";print \"\\ndo $cmd:\".\$args.\"\\n\";\n" : '')
+           .'(&make_'.$itype.'_wrapper(1).$cmd.$padding.$args.'
+           . '&make_'.$itype.'_wrapper(0),$_)}'
+           ."\n";
+       print "\nWRAP_CMD:$raw_arg_cmds{$cmd}: $code "
+               if ($thisone); # for debugging
+       eval $code;
+       print STDERR "\n\n*** sub wrap_cmd_$cmd  failed: $@\n" if ($@);
+       # And make sure the main loop will catch it ...
+#      $raw_arg_cmds{$cmd} = 1;
+       ++$raw_arg_cmds{$cmd};
+    }
+}
+
+
+# Invoked before actual translation; wraps these commands in
+# tex2html_wrap environments, so that they are properly passed to
+# TeX in &translate_environments ...
+# JCL(jcl-del) - new usage of $raw_arg_cmd_rx
+sub wrap_raw_arg_cmds {
+    local ($processed_text, $cmd, $wrapper, $wrap, $after);
+    print "\nwrapping raw arg commands " if ($VERBOSITY>1);
+    local($seg, $par_wrap, $teststar, @processed);
+#   local(@segments) = split(/\\par\b/,$_);
+#   foreach (@segments) {
+#      $par_wrap = join('',&make_deferred_wrapper(1), "\\par"
+#                      , &make_deferred_wrapper(0));
+#     push(@processed, $par_wrap ) if ($seg); ++$seg;
+    if (%renew_command) {
+       local($key);
+       foreach $key (keys %renew_command) {
+           $raw_arg_cmds{$key} = 1;
+           $raw_arg_cmd_rx =~ s/^(\(\)\\\\\()/$1$key\|/;
+       }
+    }
+    print "\n" if (/$raw_arg_cmd_rx/);
+
+    # MRO: replaced $* with /m
+    while (/$raw_arg_cmd_rx/m) {
+       local($star);
+       push (@processed, $`); print "\@";
+       $after = $';
+       #JCL(jcl-del) - status of starred raw arg cmds yet unclear
+       ($cmd, $star) = ($1.$2,$4);
+       if ($star eq '*') { $star = 'star';}
+       else { $after = $star.$after; $star = ''; }
+       $wrapper = "wrap_cmd_$cmd"; $teststar = $wrapper.'star';
+       if ($star && defined &$teststar) { $wrapper = $teststar; $star = '*'; }
+        # MRO: make {\bf**} work
+       elsif($star) { $after = '*'.$after; $star = '' }
+       print "\nWRAPPED: $cmd as $wrapper" if ($VERBOSITY > 5);
+
+       # ensure that the result is separated from following words...
+       my $padding = ($after =~ /^[a-zA-Z]/s)? ($cmd =~ /\W$/ ? '':' '):'';
+
+       if ($raw_arg_cmds{$cmd} && defined &$wrapper) {
+            $* = 1;
+           ($wrap, $_) = &$wrapper("\\$cmd$star", $padding . $after);
+            $* = 0;
+           # ...but don't leave an unwanted space at the beginning
+           $_ =~ s/^ //s if($padding && $wrap !~ /\w$/m
+               && (length($_) == length($after)+1) );
+           push (@processed, $wrap);
+       } elsif ($raw_arg_cmds{$cmd}) {
+           print STDERR "\n*** $wrapper not defined, cannot wrap \\$cmd";
+           &write_warnings("\n*** $wrapper not defined, cannot wrap \\$cmd ");
+           push (@processed, "\\$cmd$padding");
+           $_ = $after;
+       } else {
+           push (@processed, "\\$cmd$padding");
+           $_ = $after;
+       }
+        last unless ($after =~ /\\/);
+    }
+
+    # recombine the pieces
+    $_ = join('',@processed, $_);
+}
+
+#########################################################################
+
+# To make a table of contents, list of figures and list of tables commands
+# create a link to corresponding files which do not yet exist.
+# The binding of the file variable in each case acts as a flag
+# for creating the actual file at the end, after all the information
+# has been gathered.
+
+sub do_cmd_tableofcontents { &do_real_tableofcontents(@_) }
+sub do_real_tableofcontents {
+#    local($_) = @_;
+    if ((defined &do_cmd_contentsname)||$new_command{'contentsname'}) {
+       local($br_id)=++$global{'max_id'};
+       $TITLE = &translate_environments("$O$br_id$C\\contentsname$O$br_id$C");
+    } else { $TITLE = $toc_title }
+    $toc_sec_title = $TITLE;
+    $tocfile = $CURRENT_FILE;  # sets  $tocfile  this globally
+    local $toc_head = $section_headings{'tableofcontents'};
+    if ($toc_style) {
+       $toc_head .= " CLASS=\"$toc_style\"";
+       $env_style{"$toc_head.$toc_style"} = " "
+           unless ($env_style{"$toc_head.$toc_style"});
+    }
+    local($closures,$reopens) = &preserve_open_tags();
+    join('', "<BR>\n", $closures
+       , &make_section_heading($TITLE, $toc_head), $toc_mark
+       , $reopens, @_[0]);
+}
+sub do_cmd_listoffigures {
+    local($_) = @_;
+    local($list_type) = ($SHOW_SECTION_NUMBERS ? 'UL' : 'OL' );
+    if ((defined &do_cmd_listfigurename)||$new_command{'listfigurename'}) {
+       local($br_id)=++$global{'max_id'};
+       $TITLE = &translate_environments("$O$br_id$C\\listfigurename$O$br_id$C");
+    } else { $TITLE = $lof_title }
+    $toc_sec_title = $TITLE;
+    $loffile = $CURRENT_FILE;  # sets  $loffile  this globally
+    local $lof_head = $section_headings{'listoffigures'};
+    local($closures,$reopens) = &preserve_open_tags();
+    join('', "<BR>\n", $closures
+        , &make_section_heading($TITLE, $lof_head)
+        , "<$list_type>", $lof_mark, "</$list_type>"
+        , $reopens, $_);
+}
+sub do_cmd_listoftables {
+    local($_) = @_;
+    local($list_type) = ($SHOW_SECTION_NUMBERS ? 'UL' : 'OL' );
+    if ((defined &do_cmd_listtablename)||$new_command{'listtablename'}) {
+       local($br_id)=++$global{'max_id'};
+       $TITLE = &translate_environments("$O$br_id$C\\listtablename$O$br_id$C");
+    } else { $TITLE = $lot_title }
+    $toc_sec_title = $TITLE;
+    $lotfile = $CURRENT_FILE;  # sets  $lotfile  this globally
+    local $lot_head = $section_headings{'listoftables'};
+    local($closures,$reopens) = &preserve_open_tags();
+    join('', "<BR>\n", $closures
+        , &make_section_heading($TITLE, $lot_head)
+        , "<$list_type>", $lot_mark, "</$list_type>"
+        , $reopens, $_);
+}
+
+# Indicator for where to put the CHILD_LINKS table.
+sub do_cmd_tableofchildlinks {
+    local($_) = @_;
+    local($thismark) = $childlinks_mark;
+    local($option,$dum) = &get_next_optional_argument;
+    $thismark = &check_childlinks_option($option) if ($option);
+    local($pre,$post) = &minimize_open_tags("$thismark\#0\#");
+    join('', "<BR>", $pre, $_);
+}
+
+# leave out the preceding <BR>
+sub do_cmd_tableofchildlinksstar {
+    local($_) = @_;
+    local($thismark) = $childlinks_mark;
+    local($option,$dum) = &get_next_optional_argument;
+    $thismark = &check_childlinks_option($option) if ($option);
+    local($pre,$post) = &minimize_open_tags("$thismark\#1\#");
+    join('', $pre, $_);
+}
+
+sub check_childlinks_option {
+    local($option) = @_;
+    if ($option =~ /none/i) {
+       $childlinks_mark = $childlinks_null_mark;
+       $childlinks_null_mark }
+    elsif ($option =~ /off/i) { $childlinks_null_mark }
+    elsif ($option =~ /all/i) {
+       $childlinks_mark = $childlinks_on_mark;
+       $childlinks_on_mark }
+    elsif ($option =~ /on/i) { $childlinks_on_mark }
+}
+
+sub remove_child_marks {
+    # Modifies $_
+    s/($childlinks_on_mark|$childlinks_null_mark)\#\d\#//go;
+}
+
+
+sub do_cmd_htmlinfo {
+    local($_) = @_;
+    local($option,$dum) = &get_next_optional_argument;
+    if ($option =~ /^(off|none)/i) { $INFO = 0; return ($_) }
+    local($pre,$post) = &minimize_open_tags($info_title_mark.$info_page_mark);
+    join('', "<BR>", $pre, $_);
+}
+sub do_cmd_htmlinfostar {
+    local($_) = @_;
+    local($option,$dum) = &get_next_optional_argument;
+    if ($option =~ /^(off|none)/i) { $INFO = 0; return ($_) }
+    local($pre,$post) = &minimize_open_tags($info_page_mark);
+    join('', $pre, $_);
+}
+
+# $idx_mark will be replaced with the real index at the end
+sub do_cmd_textohtmlindex {
+    local($_) = @_;
+    if ((defined &do_cmd_indexname )||$new_command{'indexname'}) {
+       local($br_id)=++$global{'max_id'};
+       $TITLE = &translate_environments("$O$br_id$C\\indexname$O$br_id$C");
+    } else { $TITLE = $idx_title }
+    $toc_sec_title = $TITLE;
+    $idxfile = $CURRENT_FILE;
+    if (%index_labels) { &make_index_labels(); }
+    if (($SHORT_INDEX) && (%index_segment)) { &make_preindex(); }
+    else { $preindex = ''; }
+    local $idx_head = $section_headings{'textohtmlindex'};
+    local($heading) = join(''
+       , &make_section_heading($TITLE, $idx_head)
+       , $idx_mark );
+    local($pre,$post) = &minimize_open_tags($heading);
+    join('',"<BR>\n" , $pre, $_);
+}
+
+#RRM: added 17 May 1996
+# allows labels within the printable key of index-entries,
+# when using  makeidx.perl
+sub make_index_labels {
+    local($key, @keys);
+    @keys = keys %index_labels;
+    foreach $key (@keys) {
+       if (($ref_files{$key}) && !($ref_files{$key} eq "$idxfile")) {
+           local($tmp) = $ref_files{$key};
+           &write_warnings("\nmultiple label $key , target in $idxfile masks $tmp ");
+       }
+       $ref_files{$key} .= "$idxfile";
+    }
+}
+#RRM: added 17 May 1996
+# constructs a legend for the SHORT_INDEX, with segments
+# when using  makeidx.perl
+sub make_preindex { &make_real_preindex }
+sub make_real_preindex {
+    local($key, @keys, $head, $body);
+    $head = "<HR>\n<H4>Legend:</H4>\n<DL COMPACT>";
+    @keys = keys %index_segment;
+    foreach $key (@keys) {
+       local($tmp) = "segment$key";
+       $tmp = $ref_files{$tmp};
+       $body .= "\n<DT>$key<DD>".&make_named_href('',$tmp,$index_segment{$key});
+#      $body .= "\n<DT>$key<DD>".&make_named_href('',
+#              $tmp."\#CHILD\_LINKS",$index_segment{$key})
+#                   unless ($CHILD_STAR);
+    }
+    $preindex = join('', $head, $body, "\n</DL>") if ($body);
+}
+
+sub do_cmd_printindex { &do_real_printindex(@_); }
+sub do_real_printindex {
+    local($_) = @_;
+    local($which) = &get_next_optional_argument;
+    $idx_name = $index_names{$which}
+       if ($which && $index_names{$which});
+    @_;
+}
+
+sub do_cmd_newindex {
+    local($_) = @_;
+    local($dum,$key,$title);
+    $key = &missing_braces unless (
+       (s/$next_pair_pr_rx/$key=$2;''/eo)
+       ||(s/$next_pair_rx/$key=$2;''/eo));
+    $dum = &missing_braces unless (
+       (s/$next_pair_pr_rx/$dum=$2;''/eo)
+       ||(s/$next_pair_rx/$dum=$2;''/eo));
+    $dum = &missing_braces unless (
+       (s/$next_pair_pr_rx/$dum=$2;''/eo)
+       ||(s/$next_pair_rx/$dum=$2;''/eo));
+    $title = &missing_braces unless (
+       (s/$next_pair_pr_rx/$title=$2;''/eo)
+       ||(s/$next_pair_rx/$title=$2;''/eo));
+    $index_names{$key} = $title if ($key && $title);
+    @_;
+}
+
+# FOOTNOTES , also within Mini-page environments
+# allow easy way to override and inherit; e.g. for frames 
+
+sub do_cmd_footnotestar { &do_real_cmd_footnote(@_) }
+sub do_cmd_footnote { &do_real_cmd_footnote(@_) }
+sub do_real_cmd_footnote {
+    local($_) = @_;
+    local($cnt,$marker,$smark,$emark)=('', $footnote_mark);
+    local($mark,$dum) = &get_next_optional_argument;
+    local($anchor_name);
+
+    $footfile = "${PREFIX}$FOOT_FILENAME$EXTN"
+       unless ($footfile||$MINIPAGE||$NO_FOOTNODE);
+
+    if ($mark) { 
+       $cnt = $mark;
+       if ($MINIPAGE) { $global{'mpfootnote'} = $cnt }
+       else { $global{'footnote'} = $cnt }
+    } else {
+       $cnt = (($MINIPAGE)? ++$global{'mpfootnote'} : ++$global{'footnote'});
+    }
+    local($br_id, $footnote)=(++$global{'max_id'},'');
+    $footnote = &missing_braces unless (
+        (s/$next_pair_pr_rx/${br_id}=$1; $footnote=$2;''/eo)
+       ||(s/$next_pair_rx/${br_id}=$1; $footnote=$2;''/eo));
+    $br_id = "mp".$br_id if ($MINIPAGE);
+    $marker = &get_footnote_mark($MINIPAGE);
+    local($last_word) = &get_last_word();
+    local($href) = &make_href("$footfile#foot$br_id",$marker);
+    if ($href =~ /NAME="([^"]*)"/) { $anchor_name=$1 }
+    $last_word .= $marker unless ($anchor_name);
+    &process_footnote($footnote,$cnt,$br_id,$last_word,$mark
+             ,($MINIPAGE? $marker : '')
+             ,($MINIPAGE? '' : "$marker:$anchor_name") );
+    # this may not work if there is a <BASE> tag and !($file) !!! #
+#   join('',&make_href("$file#foot$br_id",$marker),$_);
+    $href . $_ 
+}
+
+sub process_image_footnote {
+    # MRO: modified to use $_[0]
+    # local(*math) = @_;
+    local($in_image, $keep, $pre, $this_anchor, $out, $foot_counters_recorded, @foot_anchors) = (1,'','');
+    local($image_contents) = $_[0];
+    $image_contents =~ s/\\(begin|end)(($O|$OP)\d+($C|$CP))tex2html_\w+\2//go;
+    $image_contents =~ s!(\\footnote(mark\b\s*(\[[^\]]*\])?|\s*(\[[^\]]*\])?\s*(($O|$OP)\d+($C|$CP))(.*)\5))!
+       $keep = $`; $out = '\footnotemark '.$3.$4;
+        #MRO: $*=1; local($saveRS) = $/; $/='';
+       if ($8) {
+           $this_anchor = &do_cmd_footnote($2);
+       } else {
+           $this_anchor = &do_cmd_footnotemark($3);
+       }
+        #MRO: $*=0; $/ = $saveRS;
+       $foot_counters_recorded = 1;
+       push(@foot_anchors, $this_anchor);
+       $out!oesg;
+    $_[0] = $image_contents;
+    @foot_anchors;
+}
+
+sub do_cmd_thanks { &do_cmd_footnote(@_); }
+
+sub get_footnote_mark {
+    local($mini) = @_;
+    return($footnote_mark) if ($HTML_VERSION < 3.0 );
+    local($cmd,$tmp,@tmp,$marker);
+    $cmd = "the". (($mini)? 'mp' : '') . "footnote";
+    if ($new_command{$cmd}) {
+       $tmp = "do_cmd_$cmd";
+       @tmp = split (':!:', $new_command{$cmd});
+       pop @tmp; $tmp = pop @tmp;
+       if ($tmp =~ /$O/) {
+###        local($_) = &translate_commands($tmp);
+           $marker = &translate_commands(&translate_environments($tmp));
+           &make_unique($marker);
+###        $marker = $_;
+       } else { $marker = &translate_commands(&translate_environments($tmp)); }
+    } elsif ($mini) {
+       $marker = &translate_commands('\thempfootnote');
+    } elsif ((defined &do_cmd_thefootnote)||$new_command{'thefootnote'}) { 
+       local($br_id)=++$global{'max_id'};
+       $marker = &translate_environments("$O$br_id$C\\thefootnote$O$br_id$C");
+    } else { $marker = $footnote_mark; }
+    join('','<SUP>',$marker,'</SUP>');
+}
+
+sub make_numbered_footnotes {
+    eval "sub do_cmd_thefootnote {\&numbered_footnotes}" }
+sub numbered_footnotes { &do_cmd_arabic('<<0>>footnote<<0>>');}
+
+# default numbering style for minipage notes
+sub do_cmd_thempfootnote { &do_cmd_arabic('<<0>>mpfootnote<<0>>'); }
+
+sub do_cmd_footnotemark { &do_real_cmd_footnotemark(@_) }
+sub do_real_cmd_footnotemark {
+    local($_) = @_;
+    local($br_id, $footnote,$marker,$mpnote,$tmp,$smark,$emark);
+    # Don't use ()'s for the optional argument!
+    local($mark,$dum) = &get_next_optional_argument;
+    local ($cnt,$text_known) = ('','');
+    if ($mark) {
+       $cnt = (($mark =~ /\\/)? &translate_commands($mark) : $mark);
+       if (($MINIPAGE)&&($mpfootnotes{$cnt})) {
+           $mpnote = 1;
+           $br_id  = $mpfootnotes{$cnt};
+           $text_known = 1;
+       } else {
+           $global{'footnote'} = $cnt;
+           local($tmp) = $footnotes{$cnt};
+           if ($tmp) {
+               $br_id  = $tmp;
+               $text_known = 1;
+           } else { $footnotes{$cnt} = $br_id }
+       }
+    } else {
+       $cnt = ++$global{'footnote'};
+       $text_known = 1 if ($footnotes{$cnt});
+    }
+    if ($text_known) {
+       $br_id = ($MINIPAGE ? $mpfootnotes{$cnt} : $footnotes{$cnt});
+       $marker = &get_footnote_mark($mpnote);
+       return (join('', &make_href("$footfile#foot$br_id",$marker),$_));
+    }
+    
+    local($last_word) = &get_last_word() unless ($mpnote);
+
+    # Try to find a  \footnotetext  further on.
+    do {
+       if (s/\\footnotetext\s*\[\s*$cnt\s*]*\]\s*$any_next_pair_pr_rx//o) {
+           ($br_id, $footnote) = ($2, $3);  
+       } else { 
+           $br_id = "fnm$cnt";
+           $footnotes{$cnt} = $br_id;
+       }
+    } unless ($br_id);
+
+    $marker = &get_footnote_mark($mpnote);
+    $last_word .= $marker unless ($marker =~ /$footnote_mark/ );
+    if ($footnote) {
+       # found a  \footnotetext  further on
+       &process_footnote($footnote,$cnt,$br_id,$last_word,$mark);
+       join('',&make_named_href("foot$br_id","$footfile#$br_id",$marker),$_);
+    } elsif ($br_id =~ /fnm/) {
+       # no  \footnotetext  yet, so make the entry in $footnotes
+       &process_footnote('',$cnt,$br_id,$last_word,$mark);
+       # this may not work if there is a <BASE> tag and !($footfile) !!! #
+       join('',&make_named_href("foot$br_id","$footfile#$br_id",$marker),$_);
+    } elsif ($br_id) {
+       # \footnotetext  already processed
+       if ($mpnote) {
+           $mpfootnotes =~ s/(=\"$br_id\">...)(<\/A>)/$1$last_word$3/
+               if ($last_word);
+           # this may not work if there is a <BASE> tag !!! #
+           join('',&make_named_href("foot$br_id","#$br_id",$marker),$_);
+       } else {
+           $footnotes =~ s/(=\"$br_id\">...)(<\/A>)/$1$last_word$3/;
+           # this may not work if there is a <BASE> tag and !($footfile) !!! #
+           join(''
+               ,&make_named_href("foot$br_id","$footfile#$br_id",$marker),$_);
+       }
+    } else { 
+       print "\nCannot find \\footnotetext for \\footnotemark $cnt";
+       # this may not work if there is a <BASE> tag and !($footfile) !!! #
+       join('',&make_named_href("foot$br_id","$footfile",$marker),$_);
+    }
+}
+
+# Under normal circumstances this is never executed. Any commands \footnotetext
+# should have been processed when the corresponding \footnotemark was
+# encountered. It is possible however that when processing pieces of text
+# out of context (e.g. \footnotemarks in figure and table captions)
+# the pair of commands gets separated. Until this is fixed properly,
+# this command just puts the footnote in the footnote file in the hope
+# that its context will be obvious ....
+sub do_cmd_footnotetext {
+    local($_) = @_;
+    local($mark,$dum) = &get_next_optional_argument;
+    local($br_id, $footnote, $prev, $key)=(1,'','','');
+    $footnote = &missing_braces unless (
+       (s/$next_pair_pr_rx/($br_id,$footnote)=($1,$2);''/eo)
+       ||(s/$next_pair_rx/($br_id,$footnote)=($1,$2);''/eo));
+
+    $mark = $global{'footnote'} unless $mark;
+    $prev = $footnotes{$mark};
+    if ($prev) {
+       $prev = ($MINIPAGE ? 'mp' : '') . $prev;
+       # first prepare the footnote-text
+       $footnote = &translate_environments("${OP}$br_id$CP$footnote${OP}$br_id$CP")
+            if ($footnote);
+       $footnote = &translate_commands($footnote) if ($footnote =~ /\\/);
+
+       # now merge it onto the Footnotes page
+       $footnotes =~ s/(=\"$prev\">\.\.\.)(.*<\/A>)(<\/DT>\n<DD>)\n/
+               $1.'<html_this_mark>'.$3.$footnote/e;
+       local($this_mark) = $2;
+       $this_mark =~ s|(<SUP>)(?:<#\d+#>)?(\d+)(?:<#\d+#>)?(<\/SUP>)(<\/A>)$|
+               "$4<A\n HREF=\"$CURRENT_FILE\#foot$prev\">$1$2$3$4"|e;
+       $footnotes =~ s/<html_this_mark>/$this_mark/;
+    } else {
+       &process_footnote($footnote,$mark,$br_id,'','') if $footnote;
+    }
+    $_;
+}
+
+
+sub process_footnote {
+    # Uses $before
+    # Sets $footfile defined in translate
+    # Modifies $footnotes defined in translate
+    local($footnote, $cnt, $br_id, $last_word, $mark, $mini, $same_page) = @_;
+    local($target) = $target;
+
+    # first prepare the footnote-text
+    local($br_idd, $fcnt); $br_id =~ /\D*(\d+)/; $br_idd = $1;
+    $footnote = &translate_environments("$O$br_idd$C$footnote$O$br_idd$C")
+       if ($footnote);
+    $footnote = &translate_commands($footnote) if ($footnote =~ /\\/);
+
+    local($space,$sfoot_style,$efoot_style) = ("\n",'','');
+    if ((!$NO_FOOTNODE)&&(!$mini)&&(!$target)) {
+       $footfile = "${PREFIX}$FOOT_FILENAME$EXTN";
+       $space = ".\n" x 30;
+       $space = "\n<PRE>$space</PRE>";
+    } elsif ($target) {
+       $target = $frame_body_name
+           if (($frame_body_name)&&($target eq $frame_foot_name));
+       $sfoot_style = '<SMALL>';
+       $efoot_style = '</SMALL>';
+    }
+
+    if ($mark) {
+       if ($mini) {
+           $cnt = $mpfootnotes{$mark};
+           if ($in_image) {
+               $fcnt = $global{'mpfootnote'}; --$fcnt if $fcnt;
+               $latex_body .= '\setcounter{mpfootnote}{'.($fcnt||"0")."}\n"
+                   unless ($foot_counters_recorded);
+           }
+       } else {
+           $cnt = $footnotes{$mark};
+           if ($in_image) {
+               $fcnt = $global{'footnote'}; --$fcnt if $fcnt;
+               $latex_body .= '\setcounter{footnote}{'.($fcnt||"0")."}\n"
+                   unless ($foot_counters_recorded);
+           }
+       }
+       if ($cnt) { 
+           &write_warnings("\nredefined target for footnote $mark" )
+               unless ( $cnt eq $br_id )
+       }
+       if ($mini) { $mpfootnotes{$mark} = "$br_id" }
+       elsif ($br_id =~ /fnm\d+/) {
+           $mark = "$footnotes{$cnt}";
+           $footnotes{$cnt} = "$br_id";
+#          $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">..."
+           $footnotes .= "\n<DT>$sfoot_style<A NAME=\"$br_id\">..."
+               . $last_word . "</A>$efoot_style</DT>\n<DD>\n"
+               . $space . "\n</DD>";
+           return;
+       } else { $footnotes{$mark} = "$br_id" }
+    } else {
+       if ($mini) {
+           $mpfootnotes{$cnt} = "$br_id";
+           if ($in_image) {
+               $fcnt = $global{'mpfootnote'}; --$fcnt if $fcnt;
+               $latex_body .= '\setcounter{mpfootnote}{'.($fcnt||"0")."}\n"
+                   unless ($foot_counters_recorded);
+           }
+       } else {
+           $footnotes{$cnt} = "$br_id";
+           if ($in_image) {
+               $fcnt = $global{'footnote'}; --$fcnt if $fcnt;
+               $latex_body .= '\setcounter{footnote}{'.($fcnt||"0")."}\n"
+                   unless ($foot_counters_recorded);
+           }
+       }
+    }
+
+    # catch a \footnotemark *after* the \footnotetext
+    if ((!$footnote)&&($last_word)&&(!$mini)) {
+#      $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">..."
+       $footnotes .= "\n<DT>$sfoot_style<A NAME=\"$br_id\">..."
+           . $last_word
+           . "</A>$efoot_style</DT>\n<DD>\n" . $space . "\n</DD>";
+
+    } elsif ($mini) {
+       if ($HTML_VERSION < 3.0) { $mini .= "." }
+       $mpfootnotes .= "\n<DD>$sfoot_style<A NAME=\"foot$br_id\">$mini</A> " .
+           $footnote . $efoot_style . "\n</DD>\n";
+    } elsif ($same_page) {
+       local($link,$text);
+       $same_page =~ s/:/$text=$`;$link=$';''/e;
+       $same_page = &make_named_href("","$CURRENT_FILE\#$link",$text) if($link);
+       $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">...$last_word</A>"
+           . $same_page . $efoot_style . "</DT>\n<DD>" . $sfoot_style
+           . $footnote . $efoot_style . "\n". $space . "\n</DD>";
+    } else {
+       $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">...$last_word</A>"
+               . $efoot_style . "</DT>\n<DD>" . $sfoot_style
+               . $footnote . "$efoot_style\n" . $space . "\n</DD>";
+    }
+}
+
+
+sub do_cmd_appendix {
+    $latex_body .= "\\appendix\n";
+    if ($section_commands{$outermost_level} == 3) {
+       $global{'section'} = 0;
+       &reset_dependents('section');
+       eval "sub do_cmd_thesection{ &do_cmd_the_appendix(3,\@_) }";
+    } else {
+       $global{'chapter'} = 0;
+       &reset_dependents('chapter');
+       eval "sub do_cmd_thechapter{ &do_cmd_the_appendix(2,\@_) }";
+    }
+    $_[0];
+}
+
+sub do_cmd_the_appendix {
+    local($val,$level) = (0,$_[0]);
+    if ($level == 3) { $val=$global{'section'} }
+    elsif ($level == 2) { $val=$global{'chapter'} }
+    join('', &fAlph($val), '.', $_[1]);
+}
+
+sub do_cmd_appendixname { $app_title . $_[0] }
+sub do_cmd_abstractname { $abs_title . $_[0] }
+sub do_cmd_keywordsname { $key_title . $_[0] }
+sub do_cmd_subjclassname { $sbj_title . $_[0] }
+sub do_cmd_indexname { $idx_title . $_[0] }
+sub do_cmd_contentsname { $toc_title . $_[0] }
+sub do_cmd_datename { $date_name . $_[0] }
+sub do_cmd_refname { $ref_title . $_[0] }
+sub do_cmd_bibname { $bib_title . $_[0] }
+sub do_cmd_figurename { $fig_name . $_[0] }
+sub do_cmd_listfigurename { $lof_title . $_[0] }
+sub do_cmd_tablename { $tab_name . $_[0] }
+sub do_cmd_listtablename { $lot_title . $_[0] }
+sub do_cmd_partname { $part_name . $_[0] }
+sub do_cmd_chaptername { $chapter_name . $_[0] }
+sub do_cmd_sectionname { $section_name . $_[0] }
+sub do_cmd_subsectionname { $subsection_name . $_[0] }
+sub do_cmd_subsubsectionname { $subsubsection_name . $_[0] }
+sub do_cmd_paragraphname { $paragraph_name . $_[0] }
+sub do_cmd_thmname { $thm_title . $_[0] }
+sub do_cmd_proofname { $prf_name . $_[0] }
+sub do_cmd_footnotename { $foot_title . $_[0] }
+sub do_cmd_childlinksname { '<STRONG>'.$child_name.'</STRONG>'. $_[0] }
+sub do_cmd_infopagename { $info_title . $_[0] }
+
+
+sub do_cmd_ref {
+    local($_) = @_;
+    &process_ref($cross_ref_mark,$cross_ref_mark);
+}
+
+sub do_cmd_eqref {
+    local($_) = @_;
+    join('','(',&process_ref($cross_ref_mark,$cross_ref_mark,'',')'));
+}
+
+sub do_cmd_pageref {
+    local($_) = @_;
+    &process_ref($cross_ref_mark,$cross_ref_visible_mark);
+}
+
+# This is used by external style files ...
+sub process_ref {
+    local($ref_mark, $visible_mark, $use_label, $after_label) = @_;
+    $use_label = &balance_inner_tags($use_label) 
+       if $use_label =~ (/<\/([A-Z]+)>($math_verbatim_rx.*)<\1>/);
+    $use_label = &translate_environments($use_label);
+    $use_label = &simplify(&translate_commands($use_label))
+       if ($use_label =~ /\\/ );
+    local($label,$id);
+    local($pretag) = &get_next_optional_argument;
+    $pretag = &translate_commands($pretag) if ($pretag =~ /\\/);    
+    $label = &missing_braces unless (
+       (s/$next_pair_pr_rx/($id, $label) = ($1, $2);''/eo)
+       ||(s/$next_pair_rx/($id, $label) = ($1, $2);''/eo));
+    if ($label) {
+       $label =~ s/<[^>]*>//go ; #RRM: Remove any HTML tags
+       $label =~ s/$label_rx/_/g;      # replace non alphanumeric characters
+
+       $symbolic_labels{"$pretag$label$id"} = $use_label if ($use_label);
+       if (($symbolic_labels{$pretag.$label})&&!($use_label)) {
+           $use_label = $symbolic_labels{$pretag.$label}
+       }
+#      if (!($use_label eq $label)) {
+#          $symbolic_labels{"$label$id"} = $use_label;
+#      };
+       # if $use_label is empty then $label is used as the cross_ref_mark
+       # elseif $use_label is a string then $use_label is used
+        # else the usual mark will be used
+       $use_label = ( (!$use_label && $label) || $use_label);
+
+       print "\nLINK: $ref_mark\#$label\#$id  :$use_label:" if ($VERBOSITY > 3);
+       # The quotes around the HREF are inserted later
+       join('',"<A HREF=$ref_mark#$label#$id>$visible_mark<\/A>",$after_label, $_);
+    }
+    else {
+       print "Cannot find label argument after <$last_word>\n" if $last_word;
+       $after_label . $_;
+    }
+}
+
+#RRM:  This removes unbalanced tags, due to closures for math inside 
+#      the label-text for an <A> anchor.
+sub balance_inner_tags {
+    local($text) = @_;
+    return($text) unless ($text =~ /<\/([A-Z]+)>(\s*$math_verbatim_rx.*)(<\1( [^>]*)?>)/);
+    local($beforeT,$afterT,$tag,$math_verb,$stag) = ($`,$',$1,$2,$3);
+    if (!($beforeT =~ /<$tag>/)) { 
+       $text = join('', $beforeT, $math_verb, $afterT);
+       return (&balance_inner_tags($text));
+    }
+    local(@pieces) = split (/<$tag>/, $beforeT );
+    $beforeT = shift (@pieces);
+    local($cnt,$this) = (0,'');
+    while (@pieces) {
+       $this = shift @pieces;
+       $cnt++;
+       $beforeT .= "<$tag>".$this;
+       $cnt = $cnt - ($this =~ /<\/$tag>/g);
+    }
+    if ($cnt) { 
+       $beforeT .= "<\/$tag>" . $math_verb . $stag;
+       $text = $beforeT . $afterT;
+    } else {
+       $beforeT .= $math_verb;
+       $text = join('', $beforeT, $math_verb, $afterT);
+       return (&balance_inner_tags($text));
+    }
+    $text;
+}
+
+# Uses $CURRENT_FILE defined in translate
+sub do_cmd_label {
+    local($_) = @_;
+    local($label);
+    $label = &missing_braces unless (
+       (s/$next_pair_pr_rx\n?/$label = $2;''/eo)
+       ||(s/$next_pair_rx\n?/$label = $2;''/eo));
+    &anchor_label($label,$CURRENT_FILE,$_);
+}
+
+# This subroutine is also used to process labels in undefined environments
+sub anchor_label { &real_anchor_label(@_) }
+sub real_anchor_label {
+    # Modifies entries in %ref_files defined in translate
+    local($label,$filename,$context) = @_;
+    $label =~ s/<[^>]*>//go;   #RRM: Remove any HTML tags
+    $label =~ s/$label_rx/_/g; # replace non alphanumeric characters
+    # Associate the label with the current file
+    if ($ref_files{$label} ne $filename) {
+       $ref_files{$label} = $filename;
+       $noresave{$label} = 0; $changed = 1; }
+    print "<LABEL: $label>" if ($VERBOSITY > 3);
+    join('',"<A NAME=\"$label\">$anchor_mark</A>",$context);
+}
+
+sub do_cmd_cite {
+    local($_) = @_;
+    &process_cite('','');
+}
+
+
+# This just creates a link from a label (yet to be determined) to the
+# cite_key in the citation file.
+sub process_cite { &process_real_cite(@_) }
+sub process_real_cite {
+    local($mode,$text) = @_;
+    my $has_text = (($text)? 1 : 0);
+#    local($target) = 'contents';print "\nCITE:$text";
+    # process the text from \htmlcite or \hypercite
+    if ($has_text) {
+       $text = &balance_inner_tags($text) 
+           if $use_label =~ (/<\/([A-Z]+)>($math_verbatim_rx.*)<\1>/);
+       $text = &translate_environments($text);
+       $text = &simplify(&translate_commands($text))
+           if ($use_label =~ /\\/ );
+    }
+
+    my $label, $cite_key, $pretag, @cite_keys;
+    local($optional_text,$dummy) =  &get_next_optional_argument;
+    if ($mode =~ /external/) {
+#      $target = '';
+       $pretag = $optional_text; $optional_text = '';
+       $pretag = &translate_commands($pretag) if ($pretag =~ /\\/);
+    } else {
+       $optional_text = ", $optional_text" if $optional_text;
+    }
+    s/^\s*\\space//o;          # Hack - \space is inserted in .aux
+    s/$next_pair_pr_rx//o||s/$next_pair_rx//o;
+    if (!($cite_key = $2)) {
+       print "\n *** Cannot find citation argument\n";
+       return ($_);
+    }
+    @cite_keys = (split(/,/,$cite_key));
+    my ($citations, $join) = ('',',');
+    $join  = '' if ($text);
+    foreach $cite_key (@cite_keys) {
+       $cite_key =~ s/(^\s+|\s+$)//g;
+       $cite_key =~ s/(^\s+|\s+$)//g;
+    # RRM:  if the URL and printable-key are known already, then use them...
+       $cite_key =~ s/$label_rx/_/g;
+       $label = $cite_key;
+       if ($mode eq "nocite") {
+           # nothing more to do, no citations
+       } elsif ( ($SEGMENT) && ($cite_info{$cite_key})
+               && ($ref_files{"cite_$cite_key"}) ) {
+           $join  = "," unless ($text);
+           $text = $cite_info{$cite_key} unless ($text);
+           $citations .= join('', $join
+               , &make_named_href($label,$ref_files{'cite_'."$cite_key"},$text));
+       } elsif (($mode eq "external")&&($external_labels{$pretag."cite_$cite_key"})) {
+           $join  = "," unless ($text);
+           $text = $cross_ref_visible_mark unless ($text);
+           $citations .= join('', $join
+               , &make_named_href($label
+                   , $external_labels{$pretag.'cite_'."$cite_key"}."\#$label"
+                   , $text)
+               );
+       } elsif ($mode eq 'external') {
+           $join  = "," unless ($text);
+           &write_warnings("\nExternal reference missing for citation: $pretag$cite_key");
+           $citations .= "$text$join#!$pretag$cite_key!#";
+        } else {
+           $join  = "," unless ($text);
+           #Replace the key...
+           $citations .= "$join#$cite_key#$cite_mark#$bbl_nr#$text#$cite_mark#";
+        }
+       $text = '';
+    }
+    $citations =~ s/^\s*,\s*//;
+    if ($has_text) { join('', $citations,  $optional_text, $_) }
+    else { join('', "[", $citations,  $optional_text, "]", $_) }
+}
+
+sub do_cmd_index { &do_real_index(@_) }
+sub do_real_index {
+    local($_) = @_;
+    local($br_id, $str);
+    local($idx_option) = &get_next_optional_argument;
+    $str = &missing_braces unless (
+       (s/$next_pair_pr_rx/($br_id, $str) = ($1, $2);''/eo)
+       ||(s/$next_pair_rx/($br_id, $str) = ($1, $2);''/eo));
+    join('',&make_index_entry($br_id,$str),$_);
+}
+sub do_cmd_indexstar { &do_cmd_index(@_) }
+
+# RRM: \bibcite supplies info via the .aux file; necessary with segmented docs.
+sub do_cmd_bibcite {
+    local($_) = @_;
+    local($br_id, $cite_key,$print_key);
+    $cite_key = &missing_braces unless (
+       (s/$next_pair_pr_rx/($br_id, $cite_key) = ($1, $2);''/eo)
+       ||(s/$next_pair_rx/($br_id, $cite_key) = ($1, $2);''/eo));
+    $print_key = &missing_braces unless (
+       (s/$next_pair_pr_rx/($br_id, $print_key) = ($1, $2);''/eo)
+       ||(s/$next_pair_rx/($br_id, $print_key) = ($1, $2);''/eo));
+    $cite_key =~ s/$label_rx/_/g;
+    $cite_info{$cite_key} = $print_key;
+    $_;
+}
+
+# This command will only be encountered inside a thebibliography environment.
+sub do_cmd_bibitem { &do_real_bibitem($CURRENT_FILE, @_) }
+sub do_real_bibitem {
+    local($thisfile, $_) = @_;
+    # The square brackets may contain the label to be printed
+    local($label, $dummy) = &get_next_optional_argument;
+    # Support for the "named" bibliography style
+    if ($label) {
+       $label =~ s/\\protect//g;
+       $label = &translate_commands($label) if ($label =~ /\\/);
+    }
+    local($cite_key);
+    $cite_key = &missing_braces unless (
+       ( s/$next_pair_pr_rx/$cite_key=$2;''/e )
+       ||( s/$next_pair_rx/$cite_key=$2;''/e ));
+
+    $cite_key =~ s/$label_rx/_/g;
+    $label = $cite_info{$cite_key} unless $label; # read from .aux file
+    $label = ++$bibitem_counter unless $label; # Numerical labels
+
+    if ($cite_key) {
+       # Associate the cite_key with the printed label.
+       # The printed label will be substituted back into the document later.
+       $cite_info{$cite_key} = &translate_commands($label);
+       if (!($ref_files{'cite_'."$cite_key"} eq $thisfile)) {
+           $ref_files{'cite_'."$cite_key"} = $thisfile;
+           $changed = 1; }
+
+        #RRM: apply any special styles, as defined below
+       $label = &bibitem_style($label) if (defined &bibitem_style);
+       # Create an anchor around the citation
+       join('',"<P></P><DT><A NAME=\"$cite_key\">$label</A>\n<DD>", $_);
+
+    } else {
+       print "Cannot find bibitem labels: $label\n";
+
+       #RRM: apply any special styles, as defined below
+       $label = &bibitem_style($label) if (defined &bibitem_style);
+       join('',"<P></P><DT>$label\n<DD>", $_); # AFEB added this line
+    }
+}
+
+#RRM: override this with a personal style, defined in  .latex2html-init
+#sub bibitem_style { join('','<STRONG>',$_[0],'</STRONG>') }
+sub bibitem_style {
+    return ($_[0]) unless $BIBITEM_STYLE;
+    local($text) = join(''
+       ,"${O}0$C",$BIBITEM_STYLE,"${O}1$C", @_, "${O}1$C","${O}0$C");
+    $text = &translate_environments($text);
+    &translate_commands($text);
+}
+
+sub do_cmd_newblock {
+    "<BR>".$_[0]
+}
+
+# This just reads in the $FILE.bbl file if it is available and appends
+# it to the items that are still to be processed.
+# The $FILE.bbl should contain a thebibliography environment which will
+# cause its contents to be processed later in the appropriate way.
+# (Note that it might be possible for both the \bibliography command and
+# the thebibliography environment to be present as the former may have been
+# added by the translator as a sectioning command. In this case (both present)
+# the $citefile would have already been set by the thebibliography environment)
+
+sub do_cmd_bibliography { &do_real_bibliography($CURRENT_FILE, @_) }
+sub do_real_bibliography {
+    local($thisfile, $after) = @_;
+    if ((defined &do_cmd_bibname)||$new_command{'bibname'}) {
+       local($br_id)=++$global{'max_id'};
+       $TITLE = &translate_environments("$O$br_id$C\\bibname$O$br_id$C");
+    } else { $TITLE = $bib_title }
+    $toc_sec_title = $TITLE;
+    return($_[0]) if ($making_name);
+    local($bibfile);
+    $bibfile = &missing_braces unless (
+       ($after =~ s/$next_pair_rx/$bibfile=$2;''/eo)||
+       ($after =~ s/$next_pair_rx_rx/$bibfile=$2;''/eo));
+
+    do {
+       unless ($citefile) {
+           $citefile = $thisfile;
+           if (&process_ext_file("bbl")) { # *** BINDS $_ as a side effect ***
+               $after = join('',$_,$after);}
+           else {
+               print "\nCannot open $FILE.bbl $!\n";
+               &write_warnings("\nThe bibliography file was not found.");
+               $after = join('',"\n<H2>No References!</H2>", $after);
+           }
+       }
+    print "\n";
+    } if $bibfile;
+    $after;
+}
+
+# allow for customised info-pages, for different languages
+sub do_cmd_textohtmlinfopage {
+    local($_) = @_;
+    local($linfo) = $TITLES_LANGUAGE . '_infopage';
+    if (defined &$linfo) { eval "&$linfo"; }
+    else { &default_textohtmlinfopage }
+}
+
+sub default_textohtmlinfopage {
+    local($_) = @_;
+    local($argv) = $argv;
+    if (-f "../$argv") { $argv = &make_href ("../$argv", $argv, ); }
+    $_ = ($INFO && $INFO =~ /^\d+$/
+      ? join('', $close_all
+       , "<STRONG>$t_title</STRONG><P>\nThis document was generated using the\n"
+       , "<A HREF=\"$TEX2HTMLADDRESS\"><STRONG>LaTeX</STRONG>2<tt>HTML</tt></A>"
+       , " translator Version $TEX2HTMLVERSION\n"
+       , "<P>Copyright &#169; 1993, 1994, 1995, 1996,\n"
+       , "<A HREF=\"$AUTHORADDRESS\">Nikos Drakos</A>, \n"
+       , "Computer Based Learning Unit, University of Leeds.\n"
+       , "<BR>Copyright &#169; 1997, 1998, 1999,\n"
+       , "<A HREF=\"$AUTHORADDRESS2\">Ross Moore</A>, \n"
+       , "Mathematics Department, Macquarie University, Sydney.\n"
+       , "<P>The command line arguments were: <BR>\n "
+       , "<STRONG>latex2html</STRONG> <TT>$argv</TT>\n"
+       , (($SHOW_INIT_FILE && ($INIT_FILE ne ''))?
+          "\n<P>with initialization from: <TT>$INIT_FILE</TT>\n$init_file_mark\n" :'')
+       , "<P>The translation was initiated by $address_data[0] on $address_data[1]"
+       , $open_all, $_)
+      : join('', $close_all, "$INFO\n", $open_all, $_));
+    $_;
+}
+
+
+# Try to translate LaTeX vertical space in a number of <BR>'s.
+# Eg. 1cm results in one + two extra <BR>'s.
+# To help the browser rendering is quite ugly, but why not.
+#
+sub get_vspace {
+    local($_) = @_;
+    local($vh) = 0;
+
+    return("<BR>") if /-/;
+
+    $vh = int($1 * $vspace_12pt{$2} + 0.5)
+       if (/([0-9.]+)\s*([a-z]+)/);
+    join('',"<BR>","\n<BR>" x $vh);
+}
+
+sub do_cmd_vskip {
+    local($_) = @_;
+    &ignore_numeric_argument;
+    join('',&get_vspace($1),$_);
+}
+
+sub do_cmd_break {
+    local($_) = @_;
+    join('',"<BR>",$_);
+}
+
+sub do_cmd_vspace {
+    local($_) = @_;
+    local($how_much);
+    $how_much = &missing_braces unless (
+       (s/$next_pair_pr_rx/$how_much = $2;''/e)
+       ||(s/$next_pair_rx/$how_much = $2;''/e));
+    join('',&get_vspace($how_much),$_);
+}
+
+sub do_cmd_vspacestar {
+    &do_cmd_vspace;
+}
+
+sub do_cmd_d_backslash {
+    local($_) = @_;
+
+    # Eat space from &pre_process.
+    # We could also modifiy $single_cmd_rx and %normalize, but why not here.
+    s/^ \*?//;
+    local($spc,$dum)=&get_next_optional_argument;
+    # If the [...] occurs on the next line, then it is *not* an argument to \\ .
+    # MRO: replaced $* with /m
+    if ($dum =~ /\n/m) { 
+       $spc = $`;
+        $spc =~ s/\s//gm;
+        $_ = $'.$_ 
+    }
+    join('',(($spc)? &get_vspace($spc): "\n<BR>"),$_);
+}
+
+
+################## Commands used in the $FILE.aux file #######################
+
+sub do_cmd_jobname { $FILE . $_[0] }
+
+# This is used in $FILE.aux
+sub do_cmd_newlabel {
+    local($_) = @_;
+    local($label,$val,$tmp);
+    $label = &missing_braces unless (
+       (s/$next_pair_pr_rx/$label = $2;''/eo)
+       ||(s/$next_pair_rx/$label = $2;''/eo));
+    $tmp = &missing_braces unless (
+       (s/$next_pair_pr_rx/$tmp=$2;''/eo)
+       ||(s/$next_pair_rx/$tmp=$2;''/eo));
+    $val = &missing_braces unless (
+       ($tmp =~ s/$next_pair_pr_rx/$val=$2;''/eo)
+       ||($tmp =~ s/$next_pair_rx/$val=$2;''/eo));
+    $val =~ s/(^\s+|\s+$)//gs;
+    $label =~ s/$label_rx/_/g; # Replace non alphanumeric characters
+    $latex_labels{$label} = $val;
+    &do_labels_helper($label);
+    $_;
+}
+sub do_cmd_oldnewlabel { &do_cmd_newlabel(@_) }
+
+#
+# Sets %encoded_(section|figure|table)_number, which maps encoded
+# section titles to LaTeX numbers
+# .= \$number . \"$;\"";
+sub do_cmd_oldcontentsline { &do_cmd_contentsline(@_) }
+sub do_cmd_contentsline {
+    local($_) = @_;
+    local($arg,$after,$title,$number,$hash,$stype,$page);
+    # The form of the expression is:
+    # \contentsline{SECTION} {... {SECTION_NUMBER} TITLE}{PAGE}
+    $stype = &missing_braces unless (
+        (s/$next_pair_pr_rx/$stype = $2;''/e)
+        ||(s/$next_pair_rx/$stype = $2;''/e));
+    $arg = &missing_braces unless (
+        (s/$next_pair_pr_rx/$arg = $2;''/e)
+        ||(s/$next_pair_rx/$arg = $2;''/e));
+    $page = &missing_braces unless (
+        (s/$next_pair_pr_rx/$page = $2;''/e)
+        ||(s/$next_pair_rx/$page = $2;''/e));
+
+#    s/$any_next_pair_pr_rx/$stype = $2;''/eo; # Chop off {SECTION}
+#    s/$any_next_pair_pr_rx/$arg   = $2;''/eo; # Get {... {SECTION_NUMBER} TITLE}
+#    s/$any_next_pair_pr_rx/$page  = $2;''/eo; # Get page number
+    $hash = $stype if (($stype =~ /^(figure|table)$/)||($SHOW_SECTION_NUMBERS));
+    $hash =~ s/(sub)*(section|chapter|part)/section/;
+    $after = $_;
+    if ($hash) {
+       if ($arg =~ /^$OP/) {
+           $number = &missing_braces unless (
+               ($arg =~ s/$next_pair_pr_rx/$number = $2;''/eo)
+               ||($arg =~ s/$next_pair_rx/$number = $2;''/eo));
+       }       
+       if ($stype eq "part") {
+           while ($arg =~ s/$next_pair_pr_rx//o) {};
+           $number =~ tr/a-z/A-Z/;
+           $number = "Part $number:"}
+       # This cause problem when picking figure numbers...
+       # while ($tmp =~ s/$next_pair_pr_rx//o) {};
+       $number = -1 unless $number;
+#JCL(jcl-tcl)
+##     $_ = $arg;
+#      $title = &sanitize($arg);
+##     &text_cleanup;
+##     $title = &encode_title($_);
+##
+       #remove surrounding brace-numbering
+       $arg =~ s/^($O|$OP)\d+($C|$CP)|($O|$OP)\d+($C|$CP)$//g;
+       $arg =~ s/\\footnote(mark|text)?//g;
+       # \caption arguments should have had environments translated already
+       $arg = &translate_environments($arg) if ($arg =~ /\\begin/);
+       #replace image-markers by the image params
+       $arg =~ s/$image_mark\#([^\#]+)\#/&purify_caption($1)/e;
+
+       #RRM: resolve any embedded cross-references first
+       local($checking_caption) = 1;
+       $title = &simplify($arg);
+       $title = &sanitize($title);
+       $checking_caption = '';
+       eval "\$encoded_${hash}_number{\$title} .= \$number . \"$;\"";
+    }
+    $after;
+}
+
+#
+#  Before normalizing this was \@input.  Used in .aux files.
+#
+sub do_cmd__at_input {
+    local ($_) = @_;
+    local ($file, $after);
+    $file = &missing_braces unless (
+       (s/$next_pair_pr_rx/$file=$2;''/eo)
+       ||(s/$next_pair_rx/$file=$2;''/eo));
+    local($prefix, $suffix) = split(/\./, $file);
+    $after = $_;
+    local($EXTERNAL_FILE) = $prefix;
+    &process_ext_file($suffix);
+    $after;
+}
+
+
+########################### Counter Commands #################################
+# Removes the definition from the input string, adds to the preamble
+# and stores the body in %new_counter;
+sub get_body_newcounter {
+#    local(*_) = @_;
+    local($after_R) = @_;
+    local($_) = $$after_R;
+    local($within,$ctr,$cmd,$tmp,$body,$pat);
+    local($new_ctr) = 'counter';
+    ($ctr,$pat) = &get_next(1);        # Get counter name
+    &write_warnings ("\n*** LaTeX Error: backslash found in counter-name: $ctr")
+       if ($pat =~ s/\\//);
+    $ctr =~ s/^\s*\\//; 
+    $new_ctr .= $pat;
+
+    ($within,$pat) = &get_next(0);     # Get optional within, currently ignored
+    &addto_dependents($within,$ctr);
+    $new_ctr .= $pat;
+    do {
+###    local($_) = "\\arabic<<1>>$ctr<<1>>";
+       $body = "\\arabic<<1>>$ctr<<1>>";
+       &make_unique($body);
+       $cmd = "the$ctr";
+       $tmp = "do_cmd_$cmd";
+       $new_command{$cmd} = join(':!:',0,$body,'}') unless (defined &$tmp);
+           &write_mydb("new_command", $cmd, $new_command{$cmd});
+       undef $body;
+    };
+    &do_body_newcounter($ctr);
+
+    $$after_R = $_;
+    if (!$PREAMBLE) {
+       my $new_cmd = join(''
+           , "counter{$ctr}", ($within ? "[$within]" : '') );
+       &add_to_preamble('counter','\\new'.$new_cmd);
+       return ();
+    }
+    'newed'.$new_ctr;
+}
+
+sub do_body_newcounter {
+    local($ctr) = @_;
+    $latex_body .= &revert_to_raw_tex("\\newcounter{$ctr}\n")
+       unless ($preamble =~ /\\new(counter|theorem){$ctr}/);
+    $global{$ctr} = 0;
+    &process_commands_wrap_deferred("the$ctr ");
+    $_;
+}
+
+
+#RRM: This doesn't work properly yet.
+#     The new booleans need to be stored for use in all partitions.
+#     \if... \else  \fi  is not yet implemented.
+
+sub get_body_newboolean {
+#    local(*_) = @_;
+    local($after_R) = @_;
+    local($_) = $$after_R;
+    my $bool;
+    $bool = &missing_braces unless (
+       (s/$next_pair_pr_rx/$bool=$2;''/e)
+       ||(s/$next_pair_rx/$bool=$2;''/e));
+    $bool =  &process_body_newif('',$bool);
+    $$after_R = $_;
+    'newed'.$bool;
+}
+
+sub get_body_newif {
+#    local(*_) = @_;
+    local($after_R) = @_;
+    local($_) = $$after_R;
+    local($bool);
+    if (!(s/^\s*\\if([a-zA-Z]+)//)) {
+       $$after_R = $_;
+       return();
+    }
+    $bool = $1;
+    $$after_R = $_;
+    join('','newed', &process_body_newif('', $bool));
+}
+
+
+sub process_body_newif {
+    local($texif, $bool) = @_;
+    local($body,$ifbool,$cmd,$tmp,$pat);
+   
+#    ($bool,$pat) = &get_next(1);      # Get boolean name
+
+#    # change the brace-type around the command-name
+#    $pat =~ s/$O/$OP/; $pat =~ s/$C/$CP/; $new_cmd .= $pat;
+
+    $ifbool = "if".$bool;
+    $global{$ifbool} = 0;
+
+    do {
+       $body = "\$global{'$ifbool'} = 1;";
+       $cmd = $bool."true";
+       $code = "sub do_cmd_$cmd { ".$body." \$_[0];}";
+       eval $code;
+       print STDERR "\n*** sub do_cmd_$cmd failed:\n$@\n" if ($@);
+       $raw_arg_cmds{$cmd} = 1;
+
+       $body = "\$global{$ifbool} = 0;";
+       $cmd = $bool."false";
+       $code = "sub do_cmd_$cmd { ".$body." \$_[0];}";
+       eval $code;
+       print STDERR "\n*** sub do_cmd_$cmd failed:\n$@\n" if ($@);
+       $raw_arg_cmds{$cmd} = 1;
+
+       undef $body;
+    };
+    &process_commands_wrap_deferred("${bool}true\n${bool}false\nif$bool\n");
+
+#    $latex_body .= &revert_to_raw_tex("\\newif\\$ifbool\n")
+#      unless ($preamble =~ /\\newif\s*\\$ifbool/);
+
+    if (!$PREAMBLE) {
+       local($new_cmd) = "boolean{\\$bool}";
+       &add_to_preamble ('newif', "\\new$new_cmd" );
+       return ();
+    }
+    local($br_id) = ++$global{'max_id'};
+    'boolean'."$O$br_id$C$bool$O$br_id$C";
+}
+
+
+sub do_cmd_value {
+    local($_) = @_;
+    local($ctr,$val);
+    $ctr = &missing_braces
+       unless ((s/$next_pair_pr_rx/$ctr = $2;''/eo)
+             ||(s/$next_pair_rx/$ctr = $2;''/eo));
+    $val = &get_counter_value($ctr);
+    if ($val) { $val.$_ }
+    else { join(''," 0",$_) }
+}
+
+sub do_cmd_boolean {
+    local($_) = @_;
+    local($bool,$val);
+    $bool = &missing_braces
+       unless ((s/$next_pair_pr_rx/$bool = $2;''/eo)
+             ||(s/$next_pair_rx/$bool = $2;''/eo));
+    $val = &get_boolean_value($bool);
+    if ($val) { $val.$_ }
+    else { "0".$_ }
+}
+
+sub get_counter_value {
+    local($ctr) = @_;
+    local($val,$index);
+    $ctr = 'eqn_number' if ($ctr eq "equation");
+    $index = $section_commands{$ctr};
+
+    if (defined $global{$ctr}) { $val= $global{$ctr}; }
+    elsif (($SEGMENT)&&($index)) { 
+       $val = $segment_sec_id[$index]
+#    if ($index) { 
+#      if ($SEGMENT) { $val = $segment_sec_id[$index] }
+#      else { $val = $curr_sec_id[$index] }
+    } else {
+       &write_warnings ("\ncounter $ctr not defined");
+       $val= 0;
+    }
+    print "\nVAL:$ctr: $val " if ($VERBOSITY > 3);
+    $val;
+}
+
+sub get_boolean_value {
+    local($bool) = @_;
+    local($val,$index);
+    if (defined $global{$bool}) { $val= $global{$bool} }
+    else {
+       &write_warnings ("boolean $bool not defined\n");
+       $val="0";
+    }
+    print "\nBOOL:$bool: $val " if ($VERBOSITY > 3);
+    $val;
+}
+
+sub do_cmd_addtocounter {
+    local($_) = @_;
+    local($ctr,$num,$index);
+    $ctr = &missing_braces
+       unless ((s/$next_pair_rx/$ctr = $2;''/eo)
+             ||(s/$next_pair_pr_rx/$ctr = $2;''/eo));
+    $num = &missing_braces
+       unless ((s/$next_pair_rx/$num = $2;''/eo)
+             ||(s/$next_pair_pr_rx/$num = $2;''/eo));
+
+    $num = &translate_commands($num) if ($num =~ /\\/);
+    if ($num !~ /^\s*(\+|-)?\d+\s*$/) {
+        print STDERR "\n*** cannot set counter $ctr to $num ***\n";
+        return($_);
+    }
+
+    $latex_body .= &revert_to_raw_tex("\\addtocounter{$ctr}{$num}\n");
+    $index = $section_commands{$ctr};
+
+    if (defined $global{$ctr}) { $global{$ctr} += $num }
+    elsif ($index) { 
+       if ($SEGMENT) { $segment_sec_id[$index] += $num }
+       else { $curr_sec_id[$index] += $num }
+       $global{$ctr} += $num;
+    } elsif ($ctr eq "equation") {
+       $global{'eqn_number'} += $num
+    } else { $global{$ctr} += $num };
+    print "\nADD:$ctr:+$num= ". $global{$ctr}." " if ($VERBOSITY > 3);
+#    &reset_dependents($ctr) if ($dependent{$ctr});
+    $_;
+}
+
+sub do_cmd_setcounter {
+    local($_) = @_;
+    local($ctr,$num,$index,$sctr);
+    $ctr = &missing_braces
+       unless ((s/$next_pair_rx/$ctr = $2;''/eo)
+             ||(s/$next_pair_pr_rx/$ctr = $2;''/eo));
+    $num = &missing_braces
+       unless ((s/$next_pair_rx/$num = $2;''/eo)
+             ||(s/$next_pair_pr_rx/$num = $2;''/eo));
+
+    $num = &translate_commands($num) if ($num =~ /\\/);
+    if ($num !~ /^\s*(\+|-)?\d+\s*$/) {
+       print STDERR "\n*** cannot set counter $ctr to $num ***\n";
+       return($_);
+    }
+    if ($ctr =~ /^l/) {
+       $sctr = $';
+       $ctr = $sctr if $section_commands{$sctr};
+    }
+    if (! $AUX_FILE && !($ctr =~ /page/ )) {
+       $latex_body .= &revert_to_raw_tex("\\setcounter{$ctr}{$num}\n");
+       $index = $section_commands{$ctr};
+       if ($index) { 
+           if ($curr_sec_id[$index] <= $num ) {
+               $curr_sec_id[$index] = $num
+           } else {
+               print "\nignoring \\setcounter{$ctr}{$num} currently at ",$curr_sec_id[$index] ;
+               &write_warnings(join('',"\n\\setcounter{$ctr}{$num} ignored,"
+                       ," cannot reduce from ",$curr_sec_id[$index]));
+           }
+           $global{$ctr} = $num;
+       } elsif ($ctr eq "equation") {$global{'eqn_number'} = $num }
+       else { $global{$ctr} = $num };
+    }
+    print "\nSET:$ctr: = $num" if ($VERBOSITY > 3);
+#    &reset_dependents($ctr) if ($dependent{$ctr});
+    $_;
+}
+
+sub do_cmd_setlength {
+    local($_) = @_;
+    local($dimen,$value,$index,$sctr);
+    $dimen = &missing_braces
+       unless ((s/$next_pair_rx/$dimen = $2;''/eo)
+             ||(s/$next_pair_pr_rx/$dimen = $2;''/eo));
+    $value = &missing_braces
+       unless ((s/$next_pair_rx/$value = $2;''/eo)
+             ||(s/$next_pair_pr_rx/$value = $2;''/eo));
+
+    # recognise specific length-parameters
+    if ($dimen =~ /captionwidth/) {
+       local($pxs,$len) = &convert_length($value, $MATH_SCALE_FACTOR);
+       $cap_width = $pxs if ($pxs &&($dimen =~ /captionwidth/));
+    }
+    if ((! $AUX_FILE)&&(! $PREAMBLE)) {
+       $latex_body .= &revert_to_raw_tex("\\setlength{$dimen}{$value}\n");
+       print "\nSETLENGTH:$dimen = $value" if ($VERBOSITY > 3);
+    }
+    $_;
+}
+
+sub do_cmd_setboolean {
+    local($_) = @_;
+    local($bool,$val);
+    $bool = &missing_braces
+       unless ((s/$next_pair_rx/$bool = $2;''/eo)
+             ||(s/$next_pair_pr_rx/$bool = $2;''/eo));
+    $val = &missing_braces
+       unless ((s/$next_pair_rx/$val = $2;''/eo)
+             ||(s/$next_pair_pr_rx/$val = $2;''/eo));
+    if (! $AUX_FILE) {
+       $latex_body .= &revert_to_raw_tex("\\setboolean{$bool}{$val}\n");
+       $global{"if$bool"} = (($val = ~/true/) ? 1 : 0);
+       print "\nSETBOOL:$bool = $val" if ($VERBOSITY > 3);
+    }
+    $_;
+}
+
+sub do_cmd_endsegment {
+    local($_) = @_;
+    local($ctr,$dum) = &get_next_optional_argument;
+    local($index,$steps) = ('',1);
+#    $steps = &missing_braces unless (
+#      (s/$next_pair_pr_rx/$steps = $2;''/e)
+#      ||(s/$next_pair_rx/$steps = $2;''/e));
+    $index = $section_commands{$ctr} if $ctr;
+#    if ($index) { $curr_sec_id[$index] += $steps }
+#    if ($index) { ($after_segment,$after_seg_num) = ($index,$steps) }
+    if ($index) { ($after_segment,$after_seg_num) = ($index,1) }
+    $_;
+}
+
+sub do_cmd_stepcounter {
+    local($_) = @_;
+    local($ctr,$index);
+    $ctr = &missing_braces
+       unless ((s/$next_pair_rx/$ctr = $2;''/eo)
+             ||(s/$next_pair_pr_rx/$ctr = $2;''/eo));
+    if (! $AUX_FILE) {
+       $latex_body .= &revert_to_raw_tex("\\stepcounter{$ctr}\n");
+       $index = $section_commands{$ctr};
+       if ($index) {
+#          if ($SEGMENT) { $segment_sec_id[$index] += 1 }
+#          else { $curr_sec_id[$index] += 1 }
+           $global{$ctr} += 1;
+       } elsif ($ctr eq "equation") { $global{'eqn_number'} += 1 }
+       else { $global{$ctr} += 1 };
+    }
+    print "\nSTP:$ctr:+1" if ($VERBOSITY > 3);
+    &reset_dependents($ctr) if ($dependent{$ctr});
+    $_;
+}
+
+#RRM:   dependent counters are stored as a comma-separated list
+#       in the %dependent hash.
+sub reset_dependents {
+    local($ctr) = @_;
+    local($dep,$subdep,%dependents);
+    @dependents = (split($delim, $dependent{$ctr}));
+    print "\n" if (($VERBOSITY > 3)&&(@dependents));
+    while (@dependents) {
+       $dep = pop(@dependents);
+       print "RESET $dep to 0\n" if ($VERBOSITY > 3);
+       if ($global{$dep}) { $global{$dep} = 0 }
+       elsif ($dep =~ /equation/) { $global{'eqn_number'} = 0 }
+       if ($dependent{$dep}) {
+           push(@dependents,split($delim,$dependent{$dep}));
+       }
+    }
+}
+
+sub do_cmd_numberwithin {
+    local($_) = @_;
+    local($ctr,$within);
+    $ctr = &missing_braces
+       unless ((s/$next_pair_rx/$ctr = $2;''/eo)
+             ||(s/$next_pair_pr_rx/$ctr = $2;''/eo));
+    $within = &missing_braces
+       unless ((s/$next_pair_rx/$within = $2;''/eo)
+             ||(s/$next_pair_pr_rx/$within = $2;''/eo));
+
+    # record the counter dependency
+    &addto_dependents($within,$ctr) if ($within);
+    local($newsub) = "sub do_cmd_the$ctr {"
+       . "\$global{'max_id'}++;\n"
+#        . "local(\$super)=\&do_cmd_the$within();\n"
+       . "local(\$super)=\&translate_commands('\\the$within');\n"
+       . "\$super .= '.' unless (\$super =~/\\.\$/);\n"
+       . "\$super .\&do_cmd_value('<<'.\$global{'max_id'}.'>>"
+       . $ctr . "<<'.\$global{'max_id'}.'>>')}\n";
+    eval $newsub;
+    print " *** sub do_cmd_the$ctr unchanged *** $@ " if ($@);
+    $_;
+}
+
+sub do_cmd_refstepcounter {
+    local($_) = @_;
+    local($ctr);
+    $ctr = &missing_braces
+       unless ((s/$next_pair_rx/$ctr = $2;''/eo)
+             ||(s/$next_pair_pr_rx/$ctr = $2;''/eo));
+    if (! $AUX_FILE) {
+       $latex_body .= &revert_to_raw_tex("\\refstepcounter{$ctr}\n");
+       $index = $section_commands{$ctr};
+       if (defined $global{$ctr}) { $global{$ctr} += 1 }
+       elsif ($index) {
+           if ($SEGMENT) { $segment_sec_id[$index] += 1 }
+           else { $curr_sec_id[$index] += 1 }
+       } elsif ($ctr eq "equation") { $global{'eqn_number'} += 1 }
+       else { $global{$ctr} += 1 };
+    }
+    print "\nSTP: $ctr : +1" if ($VERBOSITY > 3);
+    &reset_dependents($ctr) if ($dependent{$ctr});
+    $_;
+}
+
+sub read_counter_value {
+    local($_) = @_;
+    local($ctr,$br_id,$val);
+    $ctr = &missing_braces
+        unless ((s/$next_pair_pr_rx/$br_id = $1; $ctr = $2;''/eo)
+              ||(s/$next_pair_rx/$br_id = $1; $ctr = $2;''/eo));
+    $val = &get_counter_value($ctr);
+    ($ctr, $val, $br_id, $_)
+}
+
+sub styled_number_text {
+    local($num_style, $val, $txtID) = @_;
+    if ($USING_STYLES) {
+        $txt_style{$num_style} = " " unless ($txt_style{$num_style});
+        join('',"<SPAN CLASS=\"$num_style\">", $val, "</SPAN>", $_);
+    } else { $val.$_ }
+}
+
+sub do_cmd_arabic {
+    local($ctr, $val, $id, $_) = &read_counter_value($_[0]);
+    $val = ($val ? &farabic($val) : "0");
+    &styled_number_text('arabic', $val, $id);
+}
+    
+sub do_cmd_roman {
+    local($ctr, $val, $id, $_) = &read_counter_value($_[0]);
+    if ($val < 0 ) { $val = join('',"-",&froman(-$val)); }
+    elsif ($val) { $val = &froman($val) }
+    else { $val = "0"; }
+    &styled_number_text('roman', $val, $id);
+}
+
+sub do_cmd_Roman {
+    local($ctr, $val, $id, $_) = &read_counter_value($_[0]);
+    if ($val < 0 ) { $val = join('',"-",&fRoman(-$val)); }
+    elsif ($val) { $val = &fRoman($val) }
+    else { $val = "0"; }
+    &styled_number_text('Roman', $val, $id);
+}
+
+sub do_cmd_alph {
+    local($ctr, $val, $id, $_) = &read_counter_value($_[0]);
+    if ($val < 0 ) { $val = join('',"-",&falph(-$val)); }
+    elsif ($val) { $val = &falph($val) }
+    else { $val = "0"; }
+    &styled_number_text('alph', $val, $id);
+}
+
+sub do_cmd_Alph {
+    local($ctr, $val, $id, $_) = &read_counter_value($_[0]);
+    if ($val < 0 ) { $val = join('',"-",&fAlph(-$val)); }
+    elsif ($val) { $val = &fAlph($val) }
+    else { $val = "0"; }
+    &styled_number_text('Alph', $val, $id);
+}
+
+
+sub do_cmd_fnsymbol {
+    local($ctr, $val, $id, $_) = &read_counter_value($_[0]);
+    $val = &process_in_latex_helper($ctr, $val, "fnsymbol{$ctr}");
+    &styled_number_text('Alph', $val, $id);
+}
+
+
+
+# This is a general command for getting counter values;
+# e.g. for section-numbers.
+
+sub do_cmd_thecounter {
+    local($_) = @_;
+    # Uses $counter bound by the caller
+    local($val) = &get_counter_value($counter);
+    $val = &process_in_latex_helper($counter,$val,"the$counter");
+    &styled_number_text($counter, $val, '');
+#   join('',&process_in_latex_helper($counter,$val,"the$counter"),$_[0]);
+}
+
+
+################# Special Naming Macros ##################################
+
+sub do_cmd_LaTeX {
+    local($_) = @_;
+    if ($USING_STYLES) {
+       $env_style{'LaTeX'} = ' ' unless ($env_style{'LaTeX'});
+       $env_style{'logo-LaTeX'} = ' ' unless ($env_style{'logo-LaTeX'});
+       join('',"<SPAN CLASS=\"logo,LaTeX\">",$Laname, $TeXname,"</SPAN>",$_);
+    } else { join('',$Laname, $TeXname, $_); }
+}
+
+sub do_cmd_LaTeXe {
+    local($_) = @_;
+    if ($USING_STYLES) {
+       $env_style{'LaTeX2e'} = ' ' unless ($env_style{'LaTeX2e'});
+       $env_style{'logo-LaTeX2e'} = ' ' unless ($env_style{'logo-LaTeX2e'});
+       join('',"<SPAN CLASS=\"logo,LaTeX2e\">"
+               ,$Laname, $TeXname,'2<SUB>e</SUB>',"</SPAN>",$_);
+    } else { join('',$Laname,$TeXname
+               ,(($HTML_VERSION >= 3.0)? '2<SUB>e</SUB>':'2e'),$_);
+    }
+}
+
+sub do_cmd_latextohtml {
+    local($_) = @_;
+    if ($USING_STYLES) {
+       $env_style{'LaTeX2HTML'} = ' ' unless ($env_style{'LaTeX2HTML'});
+       $env_style{'logo-LaTeX2HTML'} = ' ' unless ($env_style{'logo-LaTeX2HTML'});
+       join('',"<SPAN CLASS=\"logo,LaTeX2HTML\">"
+               ,$Laname, $TeXname,"2<TT>HTML</TT>","</SPAN>",$_);
+    } else { join('',$Laname,$TeXname,"2<TT>HTML</TT>",$_);}
+}
+
+sub do_cmd_TeX {
+    local($_) = @_;
+    if ($USING_STYLES) {
+       $env_style{'logo-TeX'} = ' ' unless ($env_style{'logo-TeX'});
+       join('',"<SPAN CLASS=\"logo-TeX\">",$TeXname,"</SPAN>",$_);
+    } else { join('',$TeXname, $_);}
+}
+
+sub do_cmd_MF {
+    local($_) = @_;
+    if ($USING_STYLES) {
+       $env_style{'logo-Metafont'} = ' ' unless ($env_style{'logo-Metafont'});
+       join('',"<SPAN CLASS=\"logo-Metafont\">",$MFname,"</SPAN>",$_);
+    } else { join('', $MFname, $_);}
+}
+
+sub do_cmd_Xy {
+    local($_) = @_;
+    if ($USING_STYLES) {
+       $env_style{'logo-Xy-pic'} = ' ' unless ($env_style{'logo-Xy-pic'});
+       join('',"<SPAN CLASS=\"logo-Xy-pic\">",$Xyname,"</SPAN>",$_);
+    } else { join('',$Xyname, $_);}
+}
+
+sub do_cmd_AmS {
+    local($_) = @_;
+    if ($USING_STYLES) {
+       $env_style{'logo-AMS'} = ' ' unless ($env_style{'logo-AMS'});
+       join('',"<SPAN CLASS=\"logo-AMS\">",$AmSname,"</SPAN>",$_);
+    } else { join('',$AmSname, $_);}
+}
+
+sub do_cmd_AmSTeX {
+    local($_) = @_;
+    if ($USING_STYLES) {
+       $env_style{'logo-AMS'} = ' ' unless ($env_style{'logo-AMS'});
+       join('',"<SPAN CLASS=\"logo-AMS\">",$AmSname,"-$TeXname","</SPAN>",$_);
+    } else { join('',$AmSname, "-", $TeXname, $_);}
+}
+
+sub do_cmd_char {
+    local($_) = @_;
+# some special characters are already turned into l2h internal
+# representation.
+# Get its represention from the table and use it like as regexp form.
+    local($spmquot) = &escape_rx_chars($html_specials{'"'});
+# Get all internal special char representations as implied during
+# preprocessing.
+    local($spmrx) = join("\000",values %html_specials);
+# escape regexp special chars (not really necessary yet, but why not)
+    $spmrx = &escape_rx_chars($spmrx); #~ s:([\\(){}[\]\^\$*+?.|]):\\$1:g;
+    $spmrx =~ s/\000/|/g;
+    $spmrx = "(.)" unless $spmrx =~ s/(.+)/($1|.)/;
+
+    s/^[ \t]*(\d{1,3})[ \t]*/&#$1;/ &&
+       return($_);
+
+    s/^[ \t]*\'(\d{1,3})[ \t]*/"&#".oct($1).";"/e &&
+       return($_);
+
+    s/^[ \t]*$spmquot(\d{1,2})[ \t]*/"&#".hex($1).";"/e &&
+       return($_);
+
+# This is a kludge to work together with german.perl. Brrr.
+    s/^[ \t]*\'\'(\d{1,2})[ \t]*/"&#".hex($1).";"/e &&
+       return($_);
+# If l2h's special char marker represents more than one character,
+# it's already in the &#xxx; form. Else convert the single character
+# into &#xxx; with the ord() command.
+    s/^[ \t]*\`\\?$spmrx[ \t]*/
+       (length($html_specials_inv{$1}) > 1 ?
+        $html_specials_inv{$1} : "&#".ord($html_specials_inv{$1}||$1).";")/e &&
+            return($_);
+    &write_warnings(join('',
+                        "Could not find character number in \\char",
+                        (/\n/ ? $` : $_), " etc.\n"));
+    $_;
+}
+
+
+sub do_cmd_symbol {
+    local($_) = @_;
+    local($char);
+    $char = &missing_braces
+       unless ((s/$next_pair_pr_rx/$char = $2;''/eo)
+               ||(s/$next_pair_rx/$char = $2;''/eo));
+    join('',&do_cmd_char($char),$_);
+}
+
+################# Accent and Special Symbols ##################################
+
+# Generate code for the accents handling commands that are never
+# applied to i or j.
+# MEH: Now all accents are safe for dotless i or j
+# MEH: Math accents supported as well
+sub generate_accent_commands {
+    local($accent,$accent_cmd);
+    local(%accents) = ("c", "cedil", "pc", "cedil", "d", "bdot", "b", "b",
+                      "tilde", "tilde", "dot", "dot", "bar", "macr",
+                      "hat", "circ", "u", "breve", "v", "caron",
+                      "H", "dblac", "t", "t", "grave", "grave",
+                      "acute", "acute", "ddot", "uml", "check", "caron",
+                      "breve", "breve", "vec", "vec",
+                      "k", "ogon", "r", "ring");
+    foreach $accent (keys(%accents))  {
+       $accent_cmd = "sub do_cmd_$accent {" . 'local($_) = @_;'  .
+           "&accent_safe_for_ij('$accents{$accent}','$accent');" . '$_}';
+       eval $accent_cmd;
+       $accent_cmd = "do_cmd_$accent";
+       print STDERR "\n*** sub do_cmd_$accent failed:\nPERL: $@\n" if ($@);
+    }
+}
+
+# These handle accents, taking care of the dotless i's and j's that
+# may follow (even though accented j's are not part of any alphabet
+# that I know).
+#
+# Note that many forms of accents over dotless i's and j's are
+# handled:
+#   "\^\i rest"
+#   "\^\i
+#    rest"
+#   "\^{\i}rest"
+#   "\^\i{}rest"
+# They all produce "&#238;rest".
+# MEH: now also handles
+#   "\^{}rest"
+#   "\^,rest"
+# and many more
+
+sub accent_safe_for_ij {
+    local($type,$acc_cmd) = @_;
+    local($arg, $first_char,$ij_cmd);
+    #print STDOUT "\nACCENT: $type <$_>\n" ;
+    s/^[ \t]*\n?[ \t]*(\S)/$1/;        # Remove whitespace
+    if (s/^\\([ij])([^a-zA-Z]|$)/$2/) {
+       # Accent of this form: "\^\i rest" or "\^\i{}rest"
+       ($arg) =  $1; $ij_cmd = "\\$1";
+       s/^[ \t]+//o;           # Get rid of whitespaces after \i
+       if (substr($_, 0, 2) =~ /[\n\r][^\n\r]/) {
+           $_ = substr($_, 1); # Get rid of 1 newline after \i
+       }
+    } else {
+       # Accent of this form: "\^{\i}rest" or not an accent on i nor j
+       ($arg) =  &get_next_pair_or_char_pr;
+    }
+    $arg =~ s/([^\s\\<])/$first_char = $1; ''/eo;
+#   print STDOUT "\nACCENT1 type:$type arg:|${arg}| first_char: |$first_char| $ij_cmd 
+#      , $ACCENT_IMAGES\n";
+
+    local($aafter) = $_;
+    local($iso) = &iso_map($first_char,$type); 
+    if ($iso) { $_ = join('', $iso, $arg, $aafter) }
+    elsif ((!($ACCENT_IMAGES))&&(!($ij_cmd))) {
+       local($err_string) = 
+           "\nNo available accent for $first_char$type , using just \"$first_char$arg\"";
+       print $err_string if ($DEBUG||$VERBOSITY > 1);
+       &write_warnings("\n ...set \$ACCENT_IMAGES  to get an image ");
+       $_ = join('', $first_char, $arg, $aafter) }
+    else { 
+       print ", making image of accent: $first_char$type " if ($VERBOSITY > 1);
+       $_ = join('', &mbox_accent($acc_cmd, $first_char, $ij_cmd) , $arg, $aafter)
+    }
+}
+
+sub mbox_accent {
+    local($type, $char, $ij_cmd) = @_;
+    if (length($type) > 1 ) {
+       if ($text_accent{$type}) {
+           $type = $text_accent{$type};
+       } elsif ($type =~ /^(math)?accent/) {
+       } else {
+           print "\n unrecognised accent $type for `$char' ";
+           return $char;
+       }
+    }
+    local(@styles);
+    local($cmd,$style,$bstyle,$estyle) = ('','','','');
+    local(@styles) = split(',',$ACCENT_IMAGES);
+    foreach $style (@styles) {
+       $style =~ s/(^\s*\\|\s*)//g; 
+       $cmd = "do_cmd_$style";
+       if (defined &$cmd) { 
+           $bstyle .= "\\$style\{" ;
+           $estyle .= "\}";
+       } else {
+           &write_warnings("\nunrecognized style \\$style for accented characters");
+       }
+    }
+    if (!($bstyle)) {
+       $bstyle = "\{";
+       $estyle = "\}";
+    } elsif ($bstyle =~ /textit|itshape/) {
+       $bstyle = '\raise.5pt\hbox{' . $bstyle ;        
+       $estyle .= "\}";
+    }
+    $char = $ij_cmd if ($ij_cmd);
+    print STDOUT "\nACCENT: $type, $char" if ($VERBOSITY > 2);
+    local($afterkern); # serifs extend too far on some letters...
+    $afterkern = "\\kern.05em" if (($char =~ /m|n/)||($type=~/[Hv]/));
+    # ...or the accent is wider than the letter, so pad it out a bit
+    $afterkern = "\\kern.15em" if ($char =~ /i|l/); #||($type=~/v/));
+
+    &process_undefined_environment("tex2html_accent_inline"
+        , ++$global{'max_id'}, "${bstyle}\\${type}\{$char\\/\}$estyle$afterkern");
+}
+
+# MEH: Actually tries to find a dotless i or j
+sub do_cmd_i { join('',&iso_map('i', 'nodot') || 'i', $_[0]) }
+sub do_cmd_j { join('',&iso_map('j', 'nodot') || 'j', $_[0]) }
+
+sub do_cmd_accent {
+    local($_) = @_;
+    local($number);
+    if (s/\s*(\d+)\s*//o) {$number = $1}
+    elsif (s/\s*&SMPquot;(\d)(\d)\s*//o) { $number = $1*16 + $2 }
+    elsif (s/\s*\'(\d)(\d)(\d)\s*//o) { $number = $1*64 + $2*8 + $3 }
+    else { s/\s*(\W\w+)([\s\W])/$2/o;  $number = $1 }
+    local($type) = $accent_type{uc($number)};
+    #print STDOUT "\ndo_cmd_accent: $number ($type) |$_|\n";
+    if (! $type) {
+       &write_warnings("Accent number $number is unknown.\n");
+       return $_;
+    }
+    &accent_safe_for_ij($type , 'accent$number' );
+    $_;
+}
+
+sub do_cmd_ae { join('', &iso_map("ae", "lig"), $_[0]);}
+sub do_cmd_AE { join('', &iso_map("AE", "lig"), $_[0]);}
+sub do_cmd_aa { join('', &iso_map("a", "ring"), $_[0]);}
+sub do_cmd_AA { join('', &iso_map("A", "ring"), $_[0]);}
+sub do_cmd_o { join('', &iso_map("o", "slash"), $_[0]);}
+sub do_cmd_O { join('', &iso_map("O", "slash"), $_[0]);}
+sub do_cmd_ss { join('', &iso_map("sz", "lig"), $_[0]);}
+sub do_cmd_DH { join('', &iso_map("ETH", ""), $_[0]);}
+sub do_cmd_dh { join('', &iso_map("eth", ""), $_[0]);}
+sub do_cmd_TH { join('', &iso_map("THORN", ""), $_[0]);}
+sub do_cmd_th { join('', &iso_map("thorn", ""), $_[0]);}
+
+sub do_cmd_pounds { join('', &iso_map("pounds", ""), $_[0]);}
+sub do_cmd_S { join('', &iso_map("S", ""), $_[0]);}
+sub do_cmd_copyright { join('', &iso_map("copyright", ""), $_[0]);}
+sub do_cmd_P { join('', &iso_map("P", ""), $_[0]);}
+
+
+sub brackets { ($OP, $CP);}
+
+sub get_date {
+    local($format,$order) = @_;
+    local(@lt) = localtime;
+    local($d,$m,$y) = @lt[3,4,5];
+    if ($format =~ /ISO/) {
+       sprintf("%4d-%02d-%02d", 1900+$y, $m+1, $d);
+    } elsif ($format) {
+       if ($order) { eval "sprintf(".$format.",".$order.")"; }
+       else { sprintf($format, $d, $m+1, 1900+$y); }
+    } else { sprintf("%d/%d/%d", $m+1, $d, 1900+$y); }
+}
+
+sub address_data {
+    local($user, $date, $_);
+    local($format,$order) = @_;
+    # Get author, (email address) and current date.
+    ($user = L2hos->fullname()) =~ s/,.*//;
+    ($user, &get_date($format,$order));
+}
+
+
+#################################### LaTeX2e ##################################
+
+sub missing_braces {
+#    local($cmd) = @_;
+    local($next, $revert, $thisline);
+    local($this_cmd) = $cmd;
+    $this_cmd =~ s/^\\// unless ($cmd eq "\\");
+    &write_warnings("\n? brace missing for \\$this_cmd");
+    if (/^[\s%]*([^\n]*)\n/ ) {
+       $thisline = &revert_to_raw_tex($1)
+    } else { 
+       $thisline = &revert_to_raw_tex($_); 
+    }
+    print "\n\n*** no brace for \\$this_cmd , before:\n$thisline";
+    s/^\s*//;
+    if ($_ =~ s/$next_token_rx//) { $next = $& };
+    $next =~ s/$comment_mark(\d+\n?)?//g;
+#    $next = &translate_commands($next) if ($next =~ /^\\/);
+    if ($next =~ /^\\(\W|\d|[a-zA-z]*\b)/) {
+       $revert = $next = "\\".$1;
+    } elsif ($next =~ /\W/) {
+       $revert = &revert_to_raw_tex($next);
+    } else { $revert = $next };
+    print "\n*** using \"$revert\" as the argument instead; is this correct?  ***\n\n";
+    $next;
+}
+
+#RRM:
+#     &styled_text_chunk  provides an interface for pieces of styled text,
+# within a single paragraph. The visual markup can be obtained through either
+# 1. link to a stylesheet (CSS)
+# 2. direct markup placed into the output
+# 3. calling another function to process the text
+# 
+# parameters (in order):
+#  $def_tag   : markup tag to be used, unless $USING_STYLES or no $property given,
+#              attributes can be included, only 1st word is used for closing-tag;
+#  $prefix    : prefix for the Unique ID identifier, defaults to 'txt'
+#           OR  contains  CLASS= identifier  when $property is empty(see below);
+#  $type      : general type of the style-sheet information
+#  $class     : specific type of the style-sheet information
+#  $property  : value to be set, applicable to the $type & $class
+#  $alt_proc  : name of procedure to use, if $USING_STYLES == 0, and no $def_tag
+#  $_         : current data-stream
+#  $open_tags_R : current open-tags (not used in this procedure)
+
+sub styled_text_chunk {
+    local($def_tag, $prefix, $type, $class, $property, $alt_proc, $_,
+        $ot) = @_;
+    local($open_tags_R) = defined $ot ? $ot : $open_tags_R;
+    local($text, $env_id, $def_end);
+    local($span_tag) = 'SPAN';
+    $text = &missing_braces
+        unless ((s/$next_pair_pr_rx/$text = $2; $env_id = $1;''/eo)
+           || (s/$next_pair_rx/$text = $2; $env_id = $1;''/eo));
+    $text = &balance_inner_tags($text);
+
+    #start from no open tags
+    local(@save_open_tags) = ();
+    local($open_tags_R) = [];
+
+#    local($decl); 
+#    if ($prefix =~ /CLASS="(\w+)"/ ) {
+#      $decl=$1;
+#      push (@$open_tags_R, $decl);
+#    }
+#    push (@$open_tags_R, $color_env) if $color_env;
+    if (!$inside_math) {
+       $text = &translate_environments($text);
+       $text = &translate_commands($text) if ($text =~ /\\/);
+       $text .= &balance_tags;
+    }
+    
+    if (($USING_STYLES)&&($env_id =~ /^\d+$/)&&($property)) { 
+       $prefix = 'txt' unless ($prefix);
+       $env_id = $prefix.$env_id;
+       $styleID{$env_id} = join('',"$type", ($class ? "-$class" : '')
+                                ,": ", $property,"; ");
+       return(join('',"<$span_tag ID=\"$env_id\">",$text,"<\/$span_tag>", $_));
+    }
+
+    if (($USING_STYLES)&&($prefix =~ /($span_tag )?CLASS=\"(\w+)\"/o)) {
+       local($span_class) = $2;
+       $def_tag = (($1)? $1 : $span_tag." ");
+       $txt_style{$span_class} = "$type: $class "
+           unless ($txt_style{$span_class});
+       return(join('',"<$def_tag CLASS=\"$span_class\">"
+               , $text,"<\/$span_tag>", $_));
+    }
+
+    if (($def_tag) && (!$USING_STYLES)) {
+       $def_tag =~ s/^($span_tag)?CLASS=\"(\w+)\"$// ;
+    }
+
+    if ($def_tag =~ /^(\w+)/) {
+       $def_end = $1;
+       return(join('',"<$def_tag>",$text,"<\/$def_end>", $_));
+    }
+
+    return (join('', eval ("&$alt_proc(\$text)") , $_)) if (defined "&$alt_proc");
+
+    &write_warnings(
+       "\ncannot honour request for $type-$class:$property style at br$env_id");
+    join('', $text, $_);
+}
+
+sub multi_styled_text_chunk {
+    local($def_tag, $prefix, $type, $class, $property, $_, $ot) = @_;
+    local($open_tags_R) = defined $ot ? $ot : $open_tags_R;
+    $prefix = 'txt' unless ($prefix);
+    my(@def_tags) = split(',',$def_tag);
+    my(@types) = split(',',$type);
+    my(@classes) = split(',',$class);
+    my(@properties) = split(',',$property);
+    $text = &missing_braces
+        unless ((s/$next_pair_pr_rx/$text = $2; $env_id = $1;''/eo)
+           || (s/$next_pair_rx/$text = $2; $env_id = $1;''/eo));
+    if (($USING_STYLES)&&($env_id =~ /^\d+$/)&&($property)) { 
+        # $1 contains the bracket-id
+       $env_id = $prefix.$env_id;
+       while (@properties) {
+           $class = shift @classes;
+           $property = shift @properties;
+           $styleID{$env_id} .= join(''
+               , shift @types,
+               , ($class ? "-".$class : '')
+               , ($property ? " : $property" : ''), " ; ");
+           $styleID{$env_id} .= "\n\t\t  " if (@properties);
+       }
+    }
+    join('',"<SPAN ID=\"$env_id\">",$text,"<\/SPAN>", $_);
+}
+
+#RRM: 
+#   This one takes care of commands with argument that really should be
+#   environments; e.g.  \centerline, \rightline, etc.
+#   Note that styles are inherited also from the existing @$open_tags_R.
+#
+sub styled_text_block {
+    local($def_tag, $attrib, $value, $class, $_, $ot) = @_;
+    local($open_tags_R) = defined $ot ? $ot : $open_tags_R;
+    local($text, $env_id, $attribs);
+    if ($attribs =~ /,/ ) {
+        local(@attribs) = split(',',$attrib);
+       local(@values) = split(',',$value);
+       while (@attribs) { 
+            $attribs .= join('', " " , shift @attribs 
+               ,"=\"" , shift @values, "\"") }
+    } elsif($value) { 
+        $attribs = join(''," ",$attrib,"=\"",$value,"\"")
+    } else { $attribs = " " . $attrib }
+
+    local(@save_open_tags) = @$open_tags_R;
+    local($closures) = &close_all_tags();
+    local($reopens)=&balance_tags();
+    $text = &missing_braces
+        unless ((s/$next_pair_pr_rx/$text = $2; $env_id = $1;''/eo)
+           || (s/$next_pair_rx/$text = $2; $env_id = $1;''/eo));
+    if (($USING_STYLES)&&($env_id =~ /^\d+$/)) {
+       $env_id = ++$global{'max_id'};
+       $env_id = "par".$env_id;
+       $styleID{$env_id} = " ";
+       $env_style{$class} = " " if (($class)&&!($env_style{$class}));
+       $class = " CLASS=\"$class\"" if ($class);
+       $env_id = " ID=\"$env_id\"";
+    } else { $class = ''; $env_id = '' };
+
+    $text = &translate_environments($text);
+    $text = &translate_commands($text);
+
+    local($closuresA)=&close_all_tags();
+    local($reopensA) = &balance_tags();
+    $text =~ s/^\n?/\n/o; 
+    join('', $closures
+        , "<$def_tag$class$env_id$attribs>"
+        , $reopens, $text, $closuresA
+        , "</$def_tag>\n", $reopensA,  $_);
+}
+
+
+# this gives a separate ID for each instance
+#sub do_cmd_textbf { &styled_text_chunk('B','','font','weight'
+#                  ,'bold', '', @_); }
+#
+# this uses a single CLASS for all instances
+sub do_cmd_textbf { &styled_text_chunk('B','CLASS="textbf"'
+                   ,'font-weight','bold', '', '', @_); }
+
+
+# this gives a separate ID for each instance
+sub do_cmd_texttt { &styled_text_chunk('TT','','font','','', '', @_); }
+
+# this uses a single CLASS for all instances
+#sub do_cmd_textit { &styled_text_chunk('TT','CLASS="textit"'
+#                  ,'font-family','monospace', '', '', @_); }
+#
+# this gives a separate ID for each instance
+#sub do_cmd_textit { &styled_text_chunk('I','','font','style'
+#                  ,'italic', '', @_); }
+#
+# this uses a single CLASS for all instances
+sub do_cmd_textit { &styled_text_chunk('I','CLASS="textit"'
+                   ,'font-style','italic', '', '', @_); }
+
+
+
+# this gives a separate ID for each instance
+#sub do_cmd_textsl { &styled_text_chunk('I','','font','style'
+#                  ,'oblique', '', @_); }
+#
+# this uses a single CLASS for all instances
+#sub do_cmd_textsl { &styled_text_chunk('I','CLASS="textsl"'
+#                  ,'font-style','oblique', '', '', @_); }
+#
+# ... NS4 implements Italic, not oblique
+sub do_cmd_textsl { &styled_text_chunk('I','CLASS="textsl"'
+                   ,'font-style','italic', '', '', @_); }
+
+
+# this gives a separate ID for each instance
+#sub do_cmd_textsf { &styled_text_chunk('I','','font','family'
+#                  ,'sans-serif', '', @_); }
+#
+# this uses a single CLASS for all instances
+#sub do_cmd_textsf { &styled_text_chunk('I','CLASS="textsf"'
+#                  ,'font-family','sans-serif', '', '', @_); }
+#
+# ... NS4 doesn't implement sans-serif
+sub do_cmd_textsf { &styled_text_chunk('I','CLASS="textsf"'
+                   ,'font-style','italic', '', '', @_); }
+
+
+#sub do_cmd_textsc {
+#    local($_) = @_;
+#    local($text, $next, $scstr, $before, $special);
+#    $text = &missing_braces
+#        unless ((s/$next_pair_pr_rx/$text = $2;''/eo)
+#          || (s/$next_pair_rx/$text = $2;''/eo));
+#    join('', &process_smallcaps($text), $_);
+#}
+
+sub lowercase_entity {
+    local($char) = @_;
+    local($exent);
+    if ($exent = $low_entities{$char}) { "\&#$exent;" }
+    elsif ($exent = $extra_small_caps{$char}) { $exent }
+    else { "\&#$char;" }
+}
+
+sub process_smallcaps {
+    local($text) = @_;
+    local($next, $scstr, $scbef, $special, $char);
+    # is this enough for \sc and \scshape ?
+    $text = &translate_environments($text);
+
+    # MRO: replaced $* with /m
+    while ($text =~ /(\\[a-zA-Z]+|[&;]SPM\w+;|<[^>]+>)+/m ) {
+       $scbef = $`; $special = $&; $text = $';
+       while ( $scbef =~ /(&#\d+;|[a-z$sclower])+[a-z\W\d$sclower]*/m) {
+           $scstr .= $`; $scbef = $';
+           $next = $&; 
+           $next =~ s/&#(\d+);/&lowercase_entity($1)/egm;
+           eval "\$next =~ $scextra" if ($scextra);
+           eval "\$next =~ tr/a-z$sclower/A-Z$scupper/";
+           $scstr .= "<SMALL>" . $next ."<\/SMALL>";
+       }
+       $scstr .= $scbef . $special;
+    }
+    if ($text) {
+       while ( $text =~ /(&#\d+;|[a-z$sclower])+[a-z\W\d$sclower]*/m) {
+           $scstr .= $`; $text = $';
+           $next = $&;
+           $next =~ s/&#(\d+);/&lowercase_entity($1)/egm;
+           eval "\$next =~ $scextra" if ($scextra);
+           eval "\$next =~ tr/a-z$sclower/A-Z$scupper/";
+           $scstr .= "<SMALL>" . $next ."<\/SMALL>";
+       }
+       $scstr .= $text;
+    }
+    $scstr;
+}
+
+# this gives a separate ID for each instance
+#sub do_cmd_textsc { &styled_text_chunk('','','font','variant'
+#                  ,'small-caps', 'process_smallcaps', @_); }
+#
+# this uses a single CLASS for all instances
+#sub do_cmd_textsc { &styled_text_chunk('', 'CLASS="textsc"'
+#                  ,'font-variant','small-caps','', 'process_smallcaps', @_); }
+#
+# ...but NS 4.03 doesn't implement  small-caps !!!
+sub do_cmd_textsc { &styled_text_chunk('',''
+                   ,'font-variant','small-caps','', 'process_smallcaps', @_); }
+
+
+#sub do_cmd_emph { &styled_text_chunk('EM','em','font','variant','','', @_); }
+
+
+# this gives a separate ID for each instance
+#sub do_cmd_underline { &styled_text_chunk('U','','text','decoration','underline','', @_); }
+
+# this uses a single CLASS for all instances
+sub do_cmd_underline { &styled_text_chunk('U','CLASS="underline"'
+                      ,'text-decoration','underline','','', @_); }
+sub do_cmd_underbar { &do_cmd_underline(@_) }
+
+
+# this gives a separate ID for each instance
+#sub do_cmd_strikeout { &styled_text_chunk('STRIKE',''
+#                     ,'text','decoration','line-through','', @_); }
+
+# this uses a single CLASS for all instances
+sub do_cmd_strikeout { &styled_text_chunk('STRIKE','CLASS="strikeout"',
+                      'text-decoration','line-through','','', @_); }
+
+
+sub do_cmd_uppercase {
+    local($_) = @_;
+    local($text,$next,$done,$special,$after);
+    $text = &missing_braces unless (
+           (s/$next_pair_pr_rx/$text = $2;''/eo)
+           ||(s/$next_pair_rx/$text = $2;''/eo));
+    $after = $_;
+    while ($text =~ /(\\[a-zA-Z]+|[&;]SPM\w+;)/ ) {
+       $next = $`;
+       $special = $&;
+       $text = $';
+       $next =~ tr /a-z/A-Z/ if ($next);
+       $done .= $next . $special;
+    }
+    $text =~ tr /a-z/A-Z/ if ($text);
+    $done .= $text;
+    $done = &convert_iso_latin_chars($done) if ($done);
+    join('',$done,$after);
+}
+
+sub do_cmd_lowercase {
+    local($_) = @_;
+    local($text,$next,$done,$special,$after);
+    $text = &missing_braces
+        unless ((s/$next_pair_pr_rx/$text = $2;''/seo)
+           || (s/$next_pair_rx/$text = $2;''/seo));
+    $after = $_;
+    while ($text =~ /(\\[a-zA-Z]+|[&;]SPM\w+;)/ ) {
+       $next = $`;
+       $special = $&;
+       $text = $';
+       $next =~ tr /A-Z/a-z/ if ($next);
+       $done .= $next . $special;
+    }
+    $text =~ tr /A-Z/a-z/ if ($text);
+    $done .= $text;
+    $done = &convert_iso_latin_chars($done) if ($done);
+    join('',$done,$after);
+}
+
+sub do_cmd_MakeUppercase { &do_cmd_uppercase(@_) }
+sub do_cmd_MakeLowercase { &do_cmd_lowercase(@_) }
+
+
+
+sub do_cmd_ensuremath {
+    local($_) = @_;
+    local ($id, $value);
+    $value = &missing_braces unless (
+       (s/$next_pair_pr_rx/$value=$2;''/eo)
+       ||(s/$next_pair_rx/$value=$2;''/eo));
+    join('', &simple_math_env($value), $');
+}
+
+#
+#  This is mainly for \special{header=PostScript_Prologue},
+#      and \graphicspath{path} which occur OUTSIDE of an environment
+#      passed to TeX.  \special's INSIDE such environments are, of
+#      course, left alone.
+
+sub do_cmd_special {
+    local($_) = @_;
+    local ($id, $value);
+    $value = &missing_braces unless (
+       (s/$next_pair_pr_rx/$value=$2;''/eo)
+       ||(s/$next_pair_rx/$value=$2;''/eo));
+    local($special_cmd) = &revert_to_raw_tex($value);
+    &add_to_preamble($cmd,"\\$cmd\{$special_cmd\}");
+    $_;
+}
+
+
+########################## Input and Include commands #########################
+
+sub do_cmd_input {
+    local($_) = @_;
+    local($file,$output);
+    (s/\s*(.*)\s*\n/$file =$1;''/s) unless (
+       (s/$next_pair_pr_rx/$file=$2;''/eo)
+       ||(s/$next_pair_rx/$file=$2;''/eo));
+    local($after) = $_;
+    $file = &revert_to_raw_tex("\\input{$file}\n") if $file;
+    if ($PREAMBLE) { &add_to_preamble('include',$file)}
+    elsif (!($file=~/^\s*$/)) {
+       $output = &process_undefined_environment('center'
+               , ++$global{'max_id'},"\\vbox{$file}");
+    }
+    $output.$after;
+}
+
+sub do_cmd_include {
+    local($_) = @_;
+    local($file,$output);
+    $file = &missing_braces unless (
+       (s/$next_pair_pr_rx/$file=$2;''/eo)
+       ||(s/$next_pair_rx/$file=$2;''/eo));
+    local($after) = $_;
+    $file = &revert_to_raw_tex("\\include{$file}\n") if $file;
+    if ($PREAMBLE) { &add_to_preamble('include',$file)}
+    else {
+       $output = &process_undefined_environment('figure'
+               , ++$global{'max_id'},"\\vbox{$file}");
+    }
+    $output.$after;
+}
+
+########################## Messages #########################
+
+sub do_cmd_message {
+    local($_) = @_;
+    local($message);
+    $message = &missing_braces unless (
+       (s/$next_pair_pr_rx/$message=$2;''/eo)
+       ||(s/$next_pair_rx/$message=$2;''/eo));
+    local($after) = $_;
+    $message = &translate_commands($message);
+    $message =~ s/$comment_mark(\d+)//og;
+    print STDOUT "\n*** $message ***\n";
+    $after;
+}
+
+sub do_cmd_typeout {
+    print STDOUT "\n";
+    local($_) = &do_cmd_message(@_);
+    print STDOUT "\n";
+    $_;
+}
+
+sub do_cmd_expandafter {
+    local($_) = @_;
+    print "\nEXPANDAFTER: " if ($VERBOSITY >3);
+    return($_) unless (s/^\s*(\\\w+)\s*\\//o);
+    print " delaying $1 " if ($VERBOSITY >3);
+    local($delay,$cmd) = ($1,'');
+    s/^(\w+|\W)/$cmd=$1;''/eo;
+    local($nextcmd) = "do_cmd_$cmd";
+    if (defined &$nextcmd) { $_ = &$nextcmd($_) }
+    elsif ($new_command{$cmd}) { 
+        local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd});
+       do { ### local($_) = $body;
+           &make_unique($body);
+       } if ($body =~ /$O/);
+       if ($argn) {
+           do {
+               local($before) = '';
+               local($after) = "\\$cmd ".$_;
+               $after = &substitute_newcmd;   # may change $after
+                $after =~ s/\\\@#\@\@/\\/o unless ($after);
+            };
+       } else { $_ = $body . $_; }
+    } else { print "\nUNKNOWN COMMAND: $cmd "; }
+
+    # now put the delayed function back for processing
+    join('',$delay, " ", $_);
+}
+
+sub do_cmd_tracingall {
+    print "\nTRACING:\n$ref_contents\n$after\n";
+    $VERBOSITY = 8; ""; }
+
+sub do_cmd_htmltracenv { &do_cmd_htmltracing }
+
+sub do_cmd_htmltracing {
+    local($_) = @_;
+    local($value);
+    $value = &missing_braces
+        unless ((s/$next_pair_rx/$value = $2;''/eo)
+           ||(s/$next_pair_pr_rx/$value = $2;''/eo));
+    if ($value =~ /^\s*(\d+)\s*$/) { 
+       $VERBOSITY = $1;
+       if ($VERBOSITY) { 
+           print "\n\n *** setting trace-level to $VERBOSITY ***\n";
+       } else {
+           print "\n\n *** cancelling all tracing ***\n\n";
+       }
+    } else {
+       &write_warnings("argument to \\htmltracing must be a number");
+     }
+    $_ ;
+}
+
+
+############################ Initialization ####################################
+
+sub initialise {
+    ############################ Global variables ###############################
+    $PREAMBLE = 2;             # 1 while translating preamble, 0 while translating body 
+    $NESTING_LEVEL = undef;    #counter for TeX group nesting level
+    $OUT_NODE = 0;             # Used in making filenames of HTML nodes unique
+    $eqno_prefix = '';         # default prefix on equation numbers
+    ($O , $C, $OP, $CP) = ('<<' , '>>', '<#', '#>'); # Open/Close Markers
+    $href_name = 0;            # Used in the HREF NAME= field
+    $wrap_toggle = 'end';
+    $delim = '%:%';            # Delimits items of sectioning information
+                               # stored in a string
+
+    $LATEX2HTML_META = '<META NAME="Generator" CONTENT="LaTeX2HTML v'.$TEX2HTMLV_SHORT.'">'
+       . "\n<META HTTP-EQUIV=\"Content-Style-Type\" CONTENT=\"text/css\">"
+             unless ($LATEX2HTML_META);
+
+    $TeXname = (($HTML_VERSION ge "3.0")? "T<SMALL>E</SMALL>X" : "TeX");
+    $Laname = (($HTML_VERSION ge "3.0")? "L<SUP><SMALL>A</SMALL></SUP>" : "La");
+    $MFname = (($HTML_VERSION ge "3.0")? "M<SMALL>ETAFONT</SMALL>" : "Metafont");
+    $Xyname = (($HTML_VERSION ge "3.0")? "X<SUB><BIG>Y</BIG></SUB>" : "Xy");
+    $AmSname = (($HTML_VERSION ge "3.0")? "A<SUB><BIG>M</BIG></SUB>S" : "AmS");
+
+    $EQN_TAGS = "R" unless ($EQN_TAGS);
+    $EQNO_START = "(";
+    $EQNO_END   = ")";
+
+    $AtBeginDocument_hook  = "\$AtBeginDocument_hook\=\'\'; "
+       unless $AtBeginDocument_hook;
+    $cross_ref_mark = '<tex2html_cr_mark>';
+    $external_ref_mark = '<tex2html_ext_cr_mark>';
+    $cite_mark = '<tex2html_cite_mark>';
+    $hash_mark = '<tex2html_hash_mark>';
+    $protected_hash = '<tex2html_protected_hash>';
+    $param_mark = '<tex2html_param_mark>';
+    $bbl_mark = '<tex2html_bbl_mark>';
+    $toc_mark = '<tex2html_toc_mark>';
+    $lof_mark = '<tex2html_lof_mark>';
+    $lot_mark = '<tex2html_lot_mark>';
+    $info_page_mark = '<tex2html_info_page_mark>';
+    $info_title_mark = '<tex2html_info_title_mark>';
+    $init_file_mark = '<tex2html_init_file_mark>';
+    $childlinks_on_mark = '<tex2html_childlinks_mark>';
+    $childlinks_null_mark = '<tex2html_childlinks_null_mark>';
+    $childlinks_mark = $childlinks_on_mark;
+    $more_links_mark = '<tex2html_morelinks_mark>';
+    $idx_mark = '<tex2html_idx_mark>';
+    $verbatim_mark = '<tex2html_verbatim_mark>';
+    $unfinished_mark = '<tex2html_unfinished_mark>';
+    $verb_mark = '<tex2html_verb_mark>';
+    $verbstar_mark = '<tex2html_verbstar_mark>';
+    $image_mark = '<tex2html_image_mark>';
+    $mydb_mark =  '<tex2html_mydb_mark>';
+    $percent_mark = '<tex2html_percent_mark>';
+    $ampersand_mark = '<tex2html_ampersand_mark>';
+    $dol_mark = '<tex2html_lone_dollar>';
+    $comment_mark = '<tex2html_comment_mark>';
+    $caption_mark = '<tex2html_caption_mark>';
+    $array_col_mark = '<tex2html_col_mark>';
+    $array_row_mark = '<tex2html_row_mark>';
+    $array_text_mark = '<tex2html_text_mark>';
+    $array_mbox_mark = '<tex2html_mbox_mark>';
+
+    $bibitem_counter = 0;
+    $undef_mark = '<tex2html_undef_mark>';
+    $file_mark = '<tex2html_file>';
+    $endfile_mark = '<tex2html_endfile>';
+
+    # This defines textual markers for all the icons
+    # e.g. $up_visible_mark = '<tex2html_up_visible_mark>';
+    # They will be replaced with the real icons at the very end.
+    foreach $icon (keys %icons) {eval "\$$icon = '<tex2html_$icon>'"};
+
+    # Make sure $HTML_VERSION is in the right range and in the right format.
+#    $HTML_VERSION =~ /[\d.]*/;
+#    $HTML_VERSION = 0.0 + $&;
+#    $HTML_VERSION = 2 if ( $HTML_VERSION < 2 );
+#    $HTML_VERSION = 9 if ( $HTML_VERSION > 9 );
+#    $HTML_VERSION = sprintf("%3.1f",$HTML_VERSION);
+
+    &banner();
+    print "Revised and extended by:"
+       . "\n Marcus Hennecke, Ross Moore, Herb Swan and others\n";
+
+    # Collect HTML options and figure out HTML version
+    $HTML_OPTIONS = '' unless ($HTML_OPTIONS);
+    $HTML_VERSION =~ s/^html|\s+//g;
+    local(@HTML_VERSION) = split(/,/, $HTML_VERSION);
+    foreach ( @HTML_VERSION ) {
+       if (/^[\d\.]+$/) {
+           # Make sure $HTML_VERSION is in the right range and in the right format.
+           $HTML_VERSION = 0.0 + $_;
+           $HTML_VERSION = 2 if ( $HTML_VERSION < 2 );
+           $HTML_VERSION = 9 if ( $HTML_VERSION > 9 );
+           $HTML_VERSION = sprintf("%3.1f",$HTML_VERSION);
+       } else {
+           $HTML_OPTIONS .= "$_,";
+       }
+    }
+    $HTML_OPTIONS =~ s/\W$//;  # remove any trailing punctuation
+
+    print "...producing markup for HTML version $HTML_VERSION  ";
+    print ($HTML_OPTIONS ? "with $HTML_OPTIONS extensions\n\n\n" : "\n\n\n");
+
+    # load the character defs for latin-1, but don't set the charset yet
+    &do_require_extension('latin1');
+    $charset = $CHARSET = $PREV_CHARSET = '';
+
+    if ($HTML_VERSION =~ /(2.0|3.0|3.2|4.0|4.1)/) {
+       # Require the version specific file 
+       do { $_ = "$LATEX2HTMLVERSIONS${dd}html$1.pl";
+            if (!(-f $_)) {  s/(\d).(\d.pl)$/$1_$2/ };
+            if (!(-f $_)) {  s/(\d)_(\d.pl)$/$1-$2/ };
+            require $_ || die "\n*** Could not load $_ ***\n";
+            print "\nHTML version: loading $_\n";
+       } unless ($HTML_VERSION =~ /2.0/);
+       $DOCTYPE = "-//".(($HTML_VERSION eq "2.0")? "IETF" : "W3C")
+           . "//DTD HTML $HTML_VERSION"
+           .(($HTML_VERSION eq "3.2")? " Final" : "")
+           .(($HTML_VERSION eq "4.0")? " Transitional" : "");
+
+       if ($HTML_OPTIONS) {
+           local($ext);
+           local($loading_extensions) = 1;
+           # Require the option specific files 
+           @HTML_VERSION = split(/,/, $HTML_OPTIONS);
+           foreach $ext ( @HTML_VERSION ) {
+               &do_require_extension($ext);
+#              do {
+#                  print "\nLoading $LATEX2HTMLVERSIONS$dd$ext.pl";
+#                  require "$LATEX2HTMLVERSIONS$dd$ext.pl";
+#              } if (-f "$LATEX2HTMLVERSIONS$dd$ext.pl");
+           }
+           undef $loading_extensions;
+       }
+    } else {
+       print "\n You specified an invalid version: $HTML_VERSION\n"
+           . "In future please request extensions by name:\n"
+           . "  i18n  table  math  frame  latin1  unicode  etc.\n";
+
+    # Require all necessary version specific files
+       foreach ( sort <$LATEX2HTMLVERSIONS${dd}html[1-9].[0-9].pl> ) {
+           last if ( $_ gt "$LATEX2HTMLVERSIONS${dd}html$HTML_VERSION.pl" );
+           do { print "\nloading $_" if ($DEBUG);
+                require $_; } unless (
+               ($NO_SIMPLE_MATH)&&($_ eq "$LATEX2HTMLVERSIONS${dd}html3.1.pl"));
+       };
+       $STRICT_HTML = 0;
+    }
+
+    # packages automatically implemented, or clearly irrelevant
+    %styles_loaded = 
+     ( 'theorem' , 1 , 'enumerate', 1 , 'a4paper' , 1 , 'b5paper' , 1
+     , '10pt' , 1 , '11pt' , 1 , '12pt' , 1
+     , %styles_loaded );
+
+
+    %declarations =
+    ('em' , '<EM></EM>',
+     'it' , '<I></I>',
+     'bf' , '<B></B>',
+     'tt' , '<TT></TT>',
+     'sl' , '<I></I>',         # Oops!
+     'sf' , '<I></I>',         # Oops!
+     'rm' ,  '<></>',
+     'rmfamily'   ,'<></>',     # see $fontchange_rx
+     'normalfont' ,'<></>',     # see $fontweight_rx and $fontchange_rx
+     'mdseries'   ,'<></>',     # see $fontweight_rx
+     'upshape'    ,'<></>',     # see $fontchange_rx
+     'itshape' ,  '<I></I>',
+     'bfseries' , '<B></B>',
+     'ttfamily' , '<TT></TT>',
+     'slshape' ,  '<I></I>',   # Oops!
+     'sffamily' , '<I></I>',   # Oops!
+##     'scshape' ,  '<I></I>', # Oops!
+#     'boldmath' , '<B></B>',
+#     'quote', '<BLOCKQUOTE></BLOCKQUOTE>',
+#     'quotation', '<BLOCKQUOTE></BLOCKQUOTE>',
+     %declarations     # Just in case someone extends it in the init file
+     );
+
+
+%declarations = (
+     'tiny', '<FONT SIZE="-2"></FONT>',
+     'Tiny', '<FONT SIZE="-2"></FONT>',
+     'scriptsize', '<FONT SIZE="-2"></FONT>',
+     'small', '<FONT SIZE="-1"></FONT>',
+     'Small', '<FONT SIZE="-1"></FONT>',
+     'SMALL', '<FONT SIZE="-1"></FONT>',
+     'smaller', '<SMALL></SMALL>',
+     'footnotesize', '<FONT SIZE="-1"></FONT>',
+     'larger', '<BIG></BIG>',
+     'large', '<FONT SIZE="+1"></FONT>',
+     'Large', '<FONT SIZE="+2"></FONT>',
+     'LARGE', '<FONT SIZE="+2"></FONT>',
+     'huge', '<FONT SIZE="+3"></FONT>',
+     'Huge', '<FONT SIZE="+4"></FONT>',
+#     'centering', '<DIV ALIGN="CENTER"></DIV>',
+#     'center', '<DIV ALIGN="CENTER"></DIV>',
+#     'flushleft', '<DIV ALIGN="LEFT"></DIV>',
+#     'raggedright', '<DIV ALIGN="LEFT"></DIV>',
+#     'flushright', '<DIV ALIGN="RIGHT"></DIV>',
+#     'raggedleft', '<DIV ALIGN="RIGHT"></DIV>',
+     %declarations
+    ) if ($HTML_VERSION > 2.0 );
+
+#  no alignment in HTML 2.0
+#%declarations = (
+#     'centering', '<P ALIGN="CENTER"></P>',
+#     'center', '<P ALIGN="CENTER"></P>',
+#     'flushleft', '<P ALIGN="LEFT"></P>',
+#     'raggedright', '<P ALIGN="LEFT"></P>',
+#     'flushright', '<P ALIGN="RIGHT"></P>',
+#     'raggedleft', '<P ALIGN="RIGHT"></P>',
+
+%declarations = (
+#     'centering', '<P></P>',
+     'center', '<P></P>',
+     'flushleft', '<P></P>',
+     'raggedright', '<P></P>',
+     'flushright', '<P></P>',
+     'raggedleft', '<P></P>',
+     'quote', '<BLOCKQUOTE></BLOCKQUOTE>',
+     'quotation', '<BLOCKQUOTE></BLOCKQUOTE>',
+     'verse', '<BLOCKQUOTE></BLOCKQUOTE>',
+     'preform', '<PRE></PRE>',
+     'unord', '<UL></UL>',
+     'ord', '<OL></OL>',
+     'desc', '<DL></DL>',
+     'list', '',
+     'par', '<P></P>'
+    ) if ($HTML_VERSION == 2.0 );
+
+    &generate_declaration_subs;        # Generate code to handle declarations
+
+    # ...but these block-level divisions must be handled differently...
+%declarations = (
+     'quote', '<BLOCKQUOTE></BLOCKQUOTE>',
+     'quotation', '<BLOCKQUOTE></BLOCKQUOTE>',
+     'verse', '<BLOCKQUOTE></BLOCKQUOTE>',
+     'preform', '<PRE></PRE>',
+     'unord', '<UL></UL>',
+     'ord', '<OL></OL>',
+     'desc', '<DL></DL>',
+#     'list', '<DIV></DIV>',
+     'par', '<P></P>',
+     'samepage', '',
+#     'centering', '<DIV ALIGN="CENTER"></DIV>',
+     'center', '<DIV ALIGN="CENTER"></DIV>',
+     'flushleft', '<DIV ALIGN="LEFT"></DIV>',
+     'raggedright', '<DIV ALIGN="LEFT"></DIV>',
+     'flushright', '<DIV ALIGN="RIGHT"></DIV>',
+     'raggedleft', '<DIV ALIGN="RIGHT"></DIV>',
+     %declarations
+    ) if ($HTML_VERSION > 2.0 );
+
+
+    %section_commands =
+       ('partstar' , '1' , 'chapterstar', '2', 'sectionstar', '3'
+       , 'subsectionstar', '4', 'subsubsectionstar', '5', 'paragraphstar'
+       , '6', 'subparagraphstar', '7'
+       , 'part' , '1' , 'chapter', '2', 'section', '3','subsection', '4'
+       , 'subsubsection', '5', 'paragraph', '6', 'subparagraph', '7'
+       , 'slidehead', '3', %section_commands);
+    # The tableofcontents, listoffigures, listoftables, bibliography and
+    # textohtmlindex are set after determining what is the outermost level
+    # in sub set_depth_levels. Appendix is implemented as a command.
+
+    %standard_section_headings =
+       ('part' , 'H1' , 'chapter' , 'H1', 'section', 'H1', 'subsection', 'H2'
+       , 'subsubsection', 'H3', 'paragraph', 'H4', 'subparagraph', 'H5'
+       , %standard_section_headings );
+
+    # Generates code to handle sectioning commands
+    # for those sections which take an argument.
+    &generate_sectioning_subs;
+
+    %section_headings =
+       ('partstar' , 'H1' , 'chapterstar' , 'H1', 'sectionstar', 'H1'
+       , 'subsectionstar', 'H2', 'subsubsectionstar', 'H3', 'paragraphstar'
+       , 'H4', 'subparagraphstar', 'H5', %section_headings);
+
+    # These need their own custom code but are treated as sectioning commands
+    %section_headings =
+       ('tableofcontents', 'H2', 'listoffigures', 'H2', 'listoftables', 'H2'
+       , 'bibliography', 'H2', 'textohtmlindex', 'H2'
+       , %standard_section_headings
+       , %section_headings);
+
+    &generate_accent_commands; # Code to handle accent commands
+
+    # These are replaced as soon as the text is read in.
+    %html_specials = (  '<', ';SPMlt;'
+               ,  '>', ';SPMgt;'
+               ,  '&', ';SPMamp;'
+#              ,  '``', '\lq\lq '  # probably not a good idea
+#              ,  "''", '\rq\rq ',  # probably not a good idea
+               ,  '"', ';SPMquot;'
+               );
+
+    %html_specials = ( %html_specials
+               , '``', ';SPMldquo;', "''", ';SPMrdquo;'
+               ) if ($HTML_VERSION >= 5 );
+
+    # This mapping is needed in sub revert_to_raw_tex
+    # before passing stuff to latex for processing.
+    %html_specials_inv = (
+                ';SPMlt;' ,'<'
+               , ';SPMgt;','>'
+               , ';SPMamp;','&'
+               , ';SPMquot;','"'
+               , ';SPMldquo;','``'
+               , ';SPMrdquo;',"''"
+               , ';SPMdollar;', '$'    # for alltt
+               , ';SPMpct;', '%'
+               , ';SPMtilde;', '&#126;'
+               );
+
+    # normalsize vertical dimension factors for 12pt (1.0 <=> <BR>)
+    %vspace_12pt = ('ex', 1.0, 'em', 1.0, 'pt', 0.1, 'pc', 1.0,
+       'in', 6.0, 'bp', 0.1, 'cm', 2.3, 'mm', 0.2, 'dd', 0.1,
+       'cc', 1.0, 'sp', 0.0);
+
+    # For some commands such as \\, \, etc it is not possible to define
+    # perl subroutines because perl does not allow some non-ascii characters
+    # in subroutine names. So we define a table and a subroutine to relate
+    # such commands to ascii names.
+    %normalize = ('\\', 'd_backslash'
+                 , '/', 'esc_slash', "`", 'grave'
+                 , "'", 'acute', "^", 'hat', '"', 'ddot'
+                 , '~', 'tilde', '.', 'dot', '=', 'bar'
+                 , '{', 'lbrace' , '}', 'rbrace', '|', 'Vert'
+                 , '#', 'esc_hash', '$', 'esc_dollar'
+                 );
+
+    %text_accent = (  'cedil','c', 'bdot','d', 'b','b' , 'tilde','~'
+                    , 'circ' ,'^', 'hat','^', 'check','v' , 'caron','v'
+                    , 'acute','\'' , 'grave','`' , 'dot','.' , 'breve','u'
+                    , 'ddot','"' , 'uml','"' , 'bar','=','macr','='
+                    , 'dblacc','H' , 't','t' , 'ogon','k' , 'ring','r'
+                  );
+
+    # %languages_translations holds for each known language the
+    # appropriate translation function. The function is called in
+    # slurp_input.
+    # The translation functions subtitute LaTeX macros
+    # with ISO-LATIN-1 character references
+    %language_translations = (
+          'english',   'english_translation'
+        , 'USenglish', 'english_translation'
+        , 'original',  'english_translation'
+        , 'german',    'german_translation'
+        , 'austrian',  'german_translation'
+        , 'finnish',   'finnish_translation'
+        , 'french',    'french_translation'
+        , 'spanish',   'spanish_translation'
+        , 'swedish',   'swedish_translation'
+        , 'turkish',   'turkish_translation'
+       );
+
+# Reiner: 
+#    $standard_label_rx = 
+#      "\\s*[[]\\s*(((\$any_next_pair_rx4)|([[][^]]*[]])|[^]])*)[]]";
+#    $enum_label_rx = "^((({[^{}]*})|([^{}]))*)([aAiI1])(.*)";
+#    $enum_level = 0;  # level for enumerate (1-4, i-iv)
+    %enum = ( 
+               'enumi',        0,                      # counter for level 1
+               'enumii',       0,                      # counter for level 2
+               'enumiii',      0,
+               'enumiv',       0,
+               'theenumi',     "&arabic('enumi')",     # eval($enum{"theenumi"})
+               'theenumii',    "&alph('enumii')",
+               'theenumiii',   "&roman('enumiii')",
+               'theenumiv',    "&Alph('enumiv')",
+                       # e.g. eval("$enum{'labelenumi'}")
+               'labelenumi',   'eval($enum{"theenumi"}) . "."', 
+               'labelenumii',  '"(" . eval($enum{"theenumii"}) . ")"', 
+               'labelenumiii', 'eval($enum{"theenumiii"}) . "."',
+               'labelenumiv',  'eval($enum{"theenumiv"}) . "."'
+               );
+
+    %RomanI = ( '1',"I",'2',"II",'3',"III",'4',"IV"
+                   ,'5',"V",'6',"VI",'7',"VII", '8',"VIII",'9',"IX");
+    %RomanX = ( '1',"X",'2',"XX",'3',"XXX",'4',"XL"
+                   ,'5',"L",'6',"LX",'7',"LXX", '8',"LXXX",'9',"XC");
+    %RomanC = ( '1',"C",'2',"CC",'3',"CCC",'4',"CD"
+                   ,'5',"D",'6',"DC",'7',"DCC", '8',"DCCC",'9',"CM");
+    %RomanM = ( '1',"M",'2',"MM",'3',"MMM",'4',"MH"
+                   ,'5',"H",'6',"HM",'7',"HMM",'8',"HMMM");
+
+    %enum_label_funcs = ( 
+       "a", "alph", "A", "Alph", "i", "roman", "I", "Roman", "1", "arabic" );
+
+sub farabic{
+    local($_)=@_;
+    $_;
+}
+sub arabic{
+    local($_)=@_;
+    eval($enum{$_});
+}
+
+sub falph{
+    local($num)=@_;
+#    chr($num+64);
+    substr(" abcdefghijklmnopqrstuvwxyz",$num,1)
+}
+sub alph{
+    local($num)=@_;
+    &falph(eval($enum{$num}));
+}
+sub fAlph{
+    local($num)=@_;
+#    chr($num+32);
+    substr(" ABCDEFGHIJKLMNOPQRSTUVWXYZ",$num,1)
+}
+sub Alph{
+    local($num)=@_;
+    &falph(eval($enum{$num}));
+}
+
+sub Roman{
+    local($num)=@_;
+    &fRoman(eval($enum{$num}));
+}
+sub fRoman{
+    local($num)=@_;
+    local($RmI)= $num%10; ($RmI) = (($RmI) ? $RomanI{"$RmI"} : '' );
+    $num = $num/10; local($RmX)= $num%10; ($RmX) = (($RmX) ? $RomanX{"$RmX"} : '' );
+    $num = $num/10; local($RmC)= $num%10; ($RmC) = (($RmC) ? $RomanC{"$RmC"} : '' );
+    $num = $num/10; local($RmM)= $num%10; ($RmM) = (($RmM) ? $RomanM{"$RmM"} : '' );
+    "$RmM" . "$RmC" . "$RmX" . "$RmI";
+}
+sub froman{
+    local($_)=@_;
+    $_ = &fRoman($_);
+    $_ =~ tr/A-Z/a-z/;
+    $_;
+}
+sub roman{
+    local($num)=@_;
+    &froman(eval($enum{$num}));
+}
+
+
+    %unitscale = ("in",72,"pt",72.27/72,"pc",12,"mm",72/25.4,"cm",72/2.54
+                 ,"\\hsize",100,"\\vsize",100
+                 ,"\\textwidth",100,"\\textheight",100
+                 ,"\\pagewidth",100,"\\linewidth",100
+                 );
+    %units = ("in","in","pt","pt","pc","pi","mm","mm","cm","cm"
+             ,"\\hsize","%","\\vsize","%","\\textwidth","%","\\textheight","%");
+
+sub convert_length { # clean
+    my ($this,$scale) = @_;
+    $scale = 1 unless $scale;
+    my ($pxs,$len,$full);
+    if ( $this =~ /([\d.]*)\s*(in|pt|pc|mm|cm|\\[hv]size|\\\w+(width|height))?/ ) {
+       $len = ($1 ? $1 : 1); $full = $2;
+       if ($full &&($full =~ /\\([hv]size|\w+(width|height))/)) { $scale = 1;};
+       $pxs = (($full) ? int($len * $unitscale{$full}*$scale + 0.5)
+                : int($len*$scale + .5) );
+       if ( $full =~ /\\([hv]size|\w+(width|height))/) { $pxs .= '%';};
+    };
+    ($pxs,$len);
+}
+
+
+
+    # Inclusion in this list will cause a command or an environment to be ignored.
+    # This is suitable for commands without arguments and for environments.
+    # If however a do_env|cmd_<env|cmd> exists then it will be used.
+    %ignore = ('sloppypar', 1,  'document', 1, 'newblock', 1,
+              ',', 1,  '@', 1, ' ', 1,  '-', 1,
+               'sloppy', 1,
+              'hyphen', 1, 'titlepage', 1, 'htmlonly', 1,
+              'flushleft', 1, 'flushright', 1, 'slide', 1,
+              'tiny', 1, 'Tiny', 1, 'scriptsize', 1, 'footnotesize', 1,
+              'small', 1, 'normalsize', 1, 'large', 1, 'Large', 1,
+              'LARGE', 1, 'huge', 1, 'Huge', 1,
+              %ignore);
+
+    # Specify commands with arguments that should be ignored.
+    # Arbitrary code can be placed between the arguments
+    # to be executed while processing the command.
+    #
+# Note that some commands MAY HAVE ARGUMENTS WHICH SHOULD BE LEFT AS TEXT
+    # EVEN THOUGH THE COMMAND IS IGNORED (e.g. hbox, center, etc)
+
+&ignore_commands( <<_IGNORED_CMDS_);
+NeedsTeXFormat # {} # []
+ProvidesClass # {} # []
+ProvidesFile # {} # []
+ProvidesPackage # {} # []
+abovedisplayskip # &ignore_numeric_argument
+abovedisplayshortskip # &ignore_numeric_argument
+addcontentsline # {} # {} # {}
+addtocontents # {} # {}
+addvspace # {} # &ignore_numeric_argument
+and
+and # \$_ = join(''," - ",\$_)
+backmatter
+baselineskip # &ignore_numeric_argument
+belowdisplayskip # &ignore_numeric_argument
+belowdisplayshortskip # &ignore_numeric_argument
+bibdata
+bibliographystyle # {}
+bibstyle # {}
+bigskipamount # &ignore_numeric_argument
+smallskipamount # &ignore_numeric_argument
+medskipamount # &ignore_numeric_argument
+center
+citation # {}
+citeauthoryear
+clearpage
+cline # {}
+#documentclass # [] # {}
+#documentstyle # [] # {}
+#end # {}
+enlargethispage # {}
+evensidemargin # &ignore_numeric_argument
+filecontents
+filbreak
+fil
+fill
+flushbottom
+fontsize # {} # {}
+footheight # &ignore_numeric_argument
+footskip  # &ignore_numeric_argument
+frontmatter
+fussy
+global
+goodbreak
+hbox
+headheight # &ignore_numeric_argument
+headsep # &ignore_numeric_argument
+hfil
+hfill
+hfuzz # &ignore_numeric_argument
+hline
+hspace # {} # \$_ = join(''," ",\$_)
+hspacestar # {} # \$_ = join(''," ",\$_)
+html
+ifcase
+ignorespaces
+indent
+itemindent # &ignore_numeric_argument
+itemsep # &ignore_numeric_argument
+labelsep # &ignore_numeric_argument
+labelwidth # &ignore_numeric_argument
+leavevmode
+leftmargin # &ignore_numeric_argument
+listparindent # &ignore_numeric_argument
+lower # &ignore_numeric_argument
+long
+mainmatter
+makebox # [] # []
+makeindex
+marginpar # {}
+marginparsep # &ignore_numeric_argument
+marginparwidth # &ignore_numeric_argument
+markboth # {} # {}
+markright # {}
+mathord
+mathbin
+mathindent # &ignore_numeric_argument
+mathrel
+mathop
+mathtt
+#mdseries
+newpage
+#newedboolean # {}
+#newedcommand # {} # [] # [] # {}
+#newedcounter # {} # []
+#newedenvironment # {} # [] # [] # {} # {}
+#newedtheorem # {} # [] # {} # []
+#providedcommand # {} # [] # [] # {}
+#renewedcommand # {} # [] # [] # {}
+#renewedenvironment # {} # [] # [] # {} # {}
+nobreakspace # \$_ = join('',";SPMnbsp;",\$_)
+nonbreakingspace # \$_ = join('',";SPMnbsp;",\$_)
+noalign
+nobreak
+nocite # {}
+noindent
+nolinebreak# []
+nopagebreak #[]
+normalmarginpar
+numberline
+oddsidemargin # &ignore_numeric_argument
+omit
+onecolumn
+outer
+pagenumbering #{}
+pagestyle # {}
+parindent # &ignore_numeric_argument
+parsep # &ignore_numeric_argument
+parskip # &ignore_numeric_argument
+partopsep # &ignore_numeric_argument
+penalty # &ignore_numeric_argument
+phantom # {}
+protect
+raggedright
+raggedbottom
+raise # &ignore_numeric_argument
+raisebox # {} # [] # []
+relax
+reversemarginpar
+rightmargin # &ignore_numeric_argument
+#rmfamily
+rule # [] # {} # {}
+samepage
+selectfont
+startdocument # \$SEGMENT=1;\$SEGMENTED=1; \$_
+strut
+suppressfloats # []
+textheight # &ignore_numeric_argument
+textwidth # &ignore_numeric_argument
+textnormal
+#textrm
+textup
+theorempreskipamount # &ignore_numeric_argument
+theorempostskipamount # &ignore_numeric_argument
+thispagestyle # {}
+topmargin # &ignore_numeric_argument
+topsep # &ignore_numeric_argument
+topskip # &ignore_numeric_argument
+twocolumn
+unskip
+#upshape
+vfil
+vfill
+vfilll
+vline
+_IGNORED_CMDS_
+
+    # Commands which need to be passed, ALONG WITH THEIR ARGUMENTS, to TeX.
+    # Note that this means that the arguments should *not* be translated,
+    # This is handled by wrapping the commands in the dummy tex2html_wrap
+    # environment before translation begins ...
+
+    # Also it can be used to specify environments which may be defined
+    # using do_env_* but whose contents will be passed to LaTeX and
+    # therefore should not be translated.
+    # Note that this code squeezes spaces out of the args of psfig;
+
+
+    # Images are cropped to the minimum bounding-box for these...
+
+&process_commands_in_tex (<<_RAW_ARG_CMDS_);
+psfig # {} # \$args =~ s/ //g;
+usebox # {}
+framebox # [] # [] # {}
+_RAW_ARG_CMDS_
+
+    # ... but these are set in a box to measure height/depth 
+    # so that white space can be preserved in the images.
+
+&process_commands_inline_in_tex (<<_RAW_ARG_CMDS_);
+#etalchar # {} \$args =~ s/(.*)/\$\^\{\$1\}\\\$/o; 
+fbox # {}
+#frac # [] # {} # {}
+dag
+ddag
+l
+L
+oe
+OE
+textexclamdown
+textquestiondown
+textregistered
+textperiodcentered
+#textcircled # {}
+#raisebox # {} # [] # [] # {}
+_RAW_ARG_CMDS_
+
+
+
+# These are handled by wrapping the commands in the dummy tex2html_nowrap
+# environment before translation begins. This environment will be
+# stripped off later, when the commands are put into  images.tex  ...
+
+&process_commands_nowrap_in_tex (<<_RAW_ARG_NOWRAP_CMDS_);
+#begingroup
+#endgroup
+#bgroup
+#egroup
+errorstopmode
+nonstopmode
+scrollmode
+batchmode
+psfigurepath # {}
+pssilent
+psdraft
+psfull
+thinlines
+thicklines
+linethickness # {}
+hyphenation # {}
+hyphenchar # \\ # &get_numeric_argument
+hyphenpenalty # &get_numeric_argument
+#let # \\ # <<\\(\\W|\\w+)>>
+newedboolean # {}
+newedcommand # {} # [] # [] # {}
+newedcounter # {} # []
+newedenvironment # {} # [] # [] # {} # {}
+newedtheorem # {} # [] # {} # []
+#providedcommand # {} # [] # [] # {}
+#renewedcommand # {} # [] # [] # {}
+#renewedenvironment # {} # [] # [] # {} # {}
+DeclareMathAlphabet # {} # {} # {} # {} # {}
+SetMathAlphabet # {} # {} # {} # {} # {} # {}
+DeclareMathSizes # {} # {} # {} # {}
+DeclareMathVersion # {}
+DeclareSymbolFont # {} # {} # {} # {} # {}
+DeclareSymbolFontAlphabet # {} # {}
+DeclareMathSymbol # {} # {} # {} # {}
+SetSymbolFont # {} # {} # {} # {} # {} # {}
+DeclareFontShape # {} # {} # {} # {} # {} # {}
+DeclareFontFamily # {} # {} # {}
+DeclareFontEncoding # {} # {} # {}
+DeclareFontSubstitution # {} # {} # {} # {}
+mathversion # {}
+#newfont # {} # {}
+#normalfont
+#rmfamily
+#mdseries
+newlength # {}
+setlength # {} # {}
+addtolength # {} # {}
+settowidth # {}# {}
+settoheight # {} # {}
+settodepth # {} # {}
+newsavebox # {}
+savebox # {} # [] # {}
+sbox # {} # {}
+setbox # {}
+TagsOnLeft  # \$EQN_TAGS = \"L\" if \$PREAMBLE;
+TagsOnRight # \$EQN_TAGS = \"R\" if \$PREAMBLE;
+_RAW_ARG_NOWRAP_CMDS_
+
+
+&process_commands_wrap_deferred (<<_RAW_ARG_DEFERRED_CMDS_);
+alph # {}
+Alph # {}
+arabic # {}
+author # [] # {}
+boldmath
+unboldmath
+captionstar # [] # {}
+caption # [] # {}
+#endsegment # []
+#segment # [] # {} # {} # {}
+fnsymbol # {}
+footnote # [] # {}
+footnotemark # []
+footnotetext # [] # {}
+#thanks # {}
+roman # {}
+Roman # {}
+#mbox # {}
+parbox # [] # [] # [] # {} # {}
+#selectlanguage # [] # {}
+setcounter # {} # {}
+addtocounter # {} # {}
+stepcounter # {}
+refstepcounter # {}
+value # {}
+par
+hrule # &ignore_numeric_argument
+linebreak # []
+pagebreak # []
+newfont # {} # {}
+smallskip
+medskip
+bigskip
+centering
+raggedright
+raggedleft
+itshape
+#textit # {}
+upshape
+slshape
+#scshape
+rmfamily
+sffamily
+ttfamily
+mdseries
+bfseries
+#textbf # {}
+em
+normalfont
+it
+rm
+sl
+bf
+tt
+sf
+Tiny
+tiny
+scriptsize
+footnotesize
+small
+Small
+SMALL
+normalsize
+large
+Large
+LARGE
+huge
+Huge
+lowercase # {}
+uppercase # {}
+MakeLowercase # {}
+MakeUppercase # {}
+htmlinfo # []
+htmlinfostar # []
+tableofchildlinks # []
+tableofchildlinksstar # []
+tableofcontents
+listoffigures
+listoftables
+thepart
+thepage
+thechapter
+thesection
+thesubsection
+thesubsubsection
+theparagraph
+thesubparagraph
+theequation
+htmltracenv # {}
+HTMLsetenv # [] # {} # {}
+#newedboolean # {}
+#newedcounter # {} # []
+#newedcommand # {} # [] # [] # {}
+#newedtheorem # {} # [] # {} # []
+#newedenvironment # {} # [] # [] # {} # {}
+providedcommand # {} # [] # [] # {}
+renewedcommand # {} # [] # [] # {}
+renewedenvironment # {} # [] # [] # {} # {}
+url # {}
+htmlurl # {}
+latextohtml
+TeX
+LaTeX
+LaTeXe
+LaTeXiii
+Xy
+MF
+AmS
+AmSTeX
+textcircled # {}
+_RAW_ARG_DEFERRED_CMDS_
+
+
+#rrm
+# implement the XBit-Hack for Apache servers, to handle
+# Server-Side Includes (SSIs) with .html filename extension
+#
+sub check_htaccess {
+    my $access_file = '.htaccess';
+    my $has_access = '';
+    local $_;
+    print "\nChecking for .htaccess  file";
+    if (-f $access_file) {
+       print STDOUT " ... found";
+       open(HTACCESS, "<$access_file");
+       while (<HTACCESS>) {
+           if (/^\s*XBitHack\s*on\s*$/) {
+               print STDOUT " with XBitHack on";
+               $has_access =1; last;
+           };
+       }
+       print STDOUT "\n";
+       close HTACCESS;
+       return() if $has_access;
+       open (HTACCESS, ">>$access_file");
+       &write_warnings("appended to .htaccess in $DESTDIR");
+    } else {
+       open (HTACCESS, ">$access_file");
+       chmod 0644, $access_file;
+       &write_warnings("created .htaccess file in $DESTDIR");
+    }
+    print HTACCESS "\nXBitHack on\n";
+    close HTACCESS;
+}
+
+# This maps the HTML mnemonic names for the ISO-LATIN-1 character references
+# to their numeric values. When converting latex specials characters to
+# ISO-LATIN-1 equivalents I use the numeric values because this makes any
+# conversion back to latex (using revert_raw_tex) more reliable (in case
+# the text contains "&mnemonic_name"). Errors may occur if an environment
+# passed to latex (e.g. a table) contains the numeric values of character
+# references.
+
+# RRM: removed this portion; load from  latin1.pl instead
+#&do_require_extension('latin1');
+
+sub make_isolatin1_rx {
+    local($list) = &escape_rx_chars(join($CD,(values %iso_8859_1_character_map_inv)));
+    $list =~ s/$CD/|/g;
+    $isolatin1_rx = "($list)";
+}
+
+
+    ################### Frequently used regular expressions ###################
+    # $1 : preamble
+
+    $preamble_rx = "(^[\\s\\S]*)(\\\\begin\\s*$O\\d+$C\\s*document\\s*$O\\d+$C|\\\\startdocument)";
+
+    # \d (number) should sometimes also be a delimiter but this causes
+    # problems with command names  that are allowed to contain numbers (eg tex2html)
+    # \d is a delimiter with commands which take numeric arguments?
+    # JCL: I can't see that. \tex2html is also no valid LaTeX (or TeX).
+    # It is parsed \tex 2html, and \tex may take 2html as argument, but this
+    # is invalid LaTeX. \d must be treated as delimiter.
+
+# JCL(jcl-del) - Characters to be treated as letters, everything else
+# is a delimiter.
+    # internal LaTeX command separator, shouldn't be equal to $;
+    $CD = "\001";
+    &make_cmd_spc_rx; # determines space to follow a letter command
+#old    $delimiters = '\'\\s[\\]\\\\<>(=).,#;:~\/!-';
+    $letters = 'a-zA-Z';
+    $delimiter_rx = "([^$letters])";
+#
+
+    # liberalized environment names (white space, optional arg, interpunctuation signs etc.)
+    # $1 : br_id, $2 : <environment>
+    $begin_env_rx="(\\\\protect)?\\\\begin\\s*(\\[([^\\]]*)])?$O(\\d+)$C\\s*([^'[\\]\\\\#~]+)\\s*$O\\4$C";
+    $begin_env_pr_rx="(\\\\protect)?\\\\begin\\s*(\\[([^\\]]*)])?$OP(\\d+)$CP\\s*([^'[\\]\\\\#~]+)\\s*$OP\\4$CP";
+
+    $mbox_rx = "\\\\mbox\\s*";
+
+    $match_br_rx = "\\s*$O\\d+$C\\s*";
+
+    $opt_arg_rx = "\\s*\\[([^\\]]*)\\]\\s*";   # Cannot handle nested []s!
+    $optional_arg_rx = "^\\s*\\[([^]]*)\\]";   # Cannot handle nested []s!
+
+    $block_close_rx = "^<\\/(DIV|P|BLOCKQUOTE)>\$";
+    $all_close_rx = "^<\\/(BODY|PRE|OL|UL|DL|FORM|ADDRESS)>\$";
+
+    # Matches a pair of matching brackets
+    # $1 : br_id
+    # $2 : contents
+    $next_pair_rx = "^[\\s%]*$O(\\d+)$C([\\s\\S]*)$O\\1$C($comment_mark\\d*\\n?)?";
+
+    # will comments be a problem after these ???
+    $any_next_pair_rx = "$O(\\d+)$C([\\s\\S]*)$O\\1$C";
+    $any_next_pair_rx4 = "$O(\\d+)$C([\\s\\S]*)$O\\4$C";
+    $any_next_pair_pr_rx4 = "$OP(\\d+)$CP([\\s\\S]*)$OP\\4$CP";
+    $any_next_pair_rx5 = "$O(\\d+)$C([\\s\\S]*)$O\\5$C";
+    $any_next_pair_rx6 = "$O(\\d+)$C([\\s\\S]*)$O\\6$C";
+
+    # used for labels in {enumerate} environments
+    $standard_label_rx = 
+       "\\s*[[]\\s*((($any_next_pair_rx4)|([[][^]]*[]])|[^]])*)[]]";
+    $enum_label_rx = "^((({[^{}]*})|([^{}]))*)([aAiI1])(.*)";
+    $enum_level = 0;   # level for enumerate (1-4, i-iv)
+
+
+    # Matches the \ensuremath command
+    $enspair = "\\\\ensuremath\\s*" . $any_next_pair_rx;
+#    $enspair = "\\\\ensuremath\\s*$O(\\d+)$C([\\s\\S]*[\\\\\$&]+[\\s\\S]*)$O\\1$C";
+
+    # Matches math comments, from  math.pl
+    $math_verbatim_rx = "$verbatim_mark#math(\\d+)#";
+    $mathend_verbatim_rx = "$verbatim_mark#mathend([^#]*)#";
+
+    # Matches math array environments
+    $array_env_rx = "array|cases|\\w*matrix";
+
+    # initially empty; has a value in HTML 3.2 and 4.0
+    $math_class = '' unless ($math_class);
+    $eqno_class = '' unless ($eqno_class);
+
+    # Matches to end-of-line and subsequent spaces
+    $EOL = "[ \\t]*\\n?";
+
+    # Matches wrapped \par command
+    $par_rx = "\\n?\\\\begin(($O|$OP)\\d+($C|$CP))tex2html_deferred\\1\\\\par\\s\*"
+        . "\\\\end(($O|$OP)\\d+($C|$CP))tex2html_deferred\\4\\n?";
+
+    # $1 : br_id
+    $begin_cmd_rx = "$O(\\d+)$C";
+
+    # $1 : image filename prefix
+    $img_rx = "(\\w*T?img\\d+)";
+
+    # $1 : largest argument number
+    $tex_def_arg_rx = "^[#0-9]*#([0-9])($O|$OP)";
+
+    #   only some non-alphanumerics are allowed in labels,  Why?
+    $label_rx = "[^\\w\.\\\-\\\+\\\:]";
+
+#JCL(jcl-del) - new face, see also &do_cmd_makeatletter et.al.
+#    $cmd_delims = q|-#,.~/\'`^"=\$%&_{}@|; # Commands which are also delimiters!
+#    $single_cmd_atletter_rx = "\\\\([a-zA-Z\\\@]+\\*?|[$cmd_delims]|\\\\)";
+#    $single_cmd_atother_rx = "\\\\([a-zA-Z]+\\*?|[$cmd_delims]|\\\\)";
+    # $1 : declaration or command or newline (\\)
+    &make_single_cmd_rx;
+#
+
+    # $1 : description in a list environment
+    $item_description_rx =
+#      "\\\\item\\s*[[]\\s*((($any_next_pair_rx4)|([[][^]]*[]])|[^]])*)[]]";
+       "\\\\item\\s*[[]\\s*((($any_next_pair_pr_rx4)|([[][^]]*[]])|[^]])*)[]]";
+
+    $fontchange_rx = 'rm|em|it|sl|sf|tt|sc|upshape|normalfont';
+    $fontweight_rx = 'bf|mdseries|normalfont';
+    $colorchange_rx = "(text)?color\\s*(\#\\w{6})?";
+    $sizechange_rx = 'tiny|Tiny|scriptsize|footnotesize|small|Small|SMALL' .
+       '|normalsize|large|Large|LARGE|huge|Huge';
+
+#    $image_switch_rx = "makeimage";
+    $image_switch_rx = "makeimage|scshape|sc";
+    $env_switch_rx = "writetolatex";
+    $raw_arg_cmds{'font'} = 1;
+
+    # Matches the \caption command
+    # $1 : br_id
+    # $2 : contents
+     $caption_suffixes = "lof|lot";
+#    $caption_rx = "\\\\caption\\s*([[]\\s*((($any_next_pair_rx5)|([[][^]]*[]])|[^]])*)[]])?$O(\\d+)$C([\\s\\S]*)$O\\8$C$EOL";
+
+    $caption_rx = "\\\\(top|bottom|table)?caption\\s*\\\*?\\s*([[]\\s*((($any_next_pair_rx6)|([[][^]]*[]])|[^]])*)[]])?$O(\\d+)$C([\\s\\S]*)$O\\9$C$EOL";
+    $caption_width_rx = "\\\\setlength\\s*(($O|$OP)\\d+($C|$CP))\\\\captionwidth\\1\\s*(($O|$OP)\\d+($C|$CP))([^>]*)\\4";
+
+    # Matches the \htmlimage command
+    # $1 : br_id
+    # $2 : contents
+    $htmlimage_rx = "\\\\htmlimage\\s*$O(\\d+)$C([\\s\\S]*)$O\\1$C$EOL";
+    $htmlimage_pr_rx = "\\\\htmlimage\\s*$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP$EOL";
+
+    # Matches the \htmlborder command
+    # $1 : optional argument...
+    # $2 : ...contents  i.e. extra attributes
+    # $3 : br_id
+    # $4 : contents i.e. width
+    $htmlborder_rx = "\\\\htmlborder\\s*(\\[([^]]*)\\])?\\s*$O(\\d+)$C(\\d*)$O\\3$C$EOL";
+    $htmlborder_pr_rx = "\\\\htmlborder\\s*(\\[([^]]*)\\])?\\s*$OP(\\d+)$CP(\\d*)$OP\\3$CP$EOL";
+
+    # Matches a pair of matching brackets
+    # USING PROCESSED DELIMITERS;
+    # (the delimiters are processed during command translation)
+    # $1 : br_id
+    # $2 : contents
+#    $next_pair_pr_rx = "^[\\s%]*$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP";
+    $next_pair_pr_rx = "^[\\s%]*$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP($comment_mark\\d*\\n?)?";
+    $any_next_pair_pr_rx = "$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP($comment_mark\\d*\\n?)?";
+    $next_token_rx = "^[\\s%]*(\\\\[A-Za-z]+|\\\\[^a-zA-Z]|.)";
+
+    $HTTP_start = 'http:';
+
+    # This will be used to recognise escaped special characters as such
+    # and not as commands
+    $latex_specials_rx = '[\$]|&|%|#|{|}|_';
+    $html_escape_chars = '<>&';
+
+    # This is used in sub revert_to_raw_tex before handing text to be processed
+    # by latex.
+    $html_specials_inv_rx = join("|", keys %html_specials_inv);
+
+    # These are used for direct replacements in/from  ALT=... strings
+    %html_special_entities = ('<','lt','>','gt','"','quot','&','amp');
+    %html_spec_entities_inv = ('lt','<','gt','>','quot','"','amp','&');
+
+    # This is also used in sub revert_to_raw_tex
+    $character_entity_rx = '(&#(\d+);)';
+    $named_entity_rx = '&(\w+);';
+
+    #commands for altering theorem-styles
+    $theorem_cmd_rx = 'theorem(style|(header|body)font)';
+
+
+    # Matches a \begin or \end {tex2html_wrap}. Also used by revert_to_raw_tex
+    $tex2html_wrap_rx = '\\\\(begin|end)\\s*\{\\s*(tex2html_(wrap|nowrap|deferred|nomath|preform|\\w*_inline)[_a-z]*|makeimage)\\s*\}'."($EOL)";
+    $tex2html_deferred_rx = '\\\\(begin|end)(<<\\d+>>)tex2html_deferred\\2';
+    $tex2html_deferred_rx2 = '\\\\(begin|end)(<<\\d+>>)tex2html_deferred\\4';
+    $tex2html_envs_rx = "\\\\(begin|end)\\s*(($O|$OP)\\d+($C|$CP))\\s*(tex2html_(wrap|nowrap|deferred|nomath|preform|\w+_inline)[_a-z]*||makeimage)\\s*\\2";
+
+    # The first empty parenthese pair is for non-letter commands.
+    # $2: meta command, $4: delimiter (may be empty)  ignore the *-version distinction
+#    $meta_cmd_rx = "()\\\\(providecommand|renewcommand|renewenvironment|newcommand|newenvironment|newtheorem|newcounter|newboolean|newif|let)(([^$letters$cmd_spc])|$cmd_spcs_rx)";
+    $meta_cmd_rx = "()\\\\(providecommand|renewcommand|renewenvironment|newcommand|newenvironment|newtheorem|newcounter|newboolean|newif|DeclareRobustCommand|DeclareMathOperator\\*?)\\\*?(([^$letters$cmd_spc])|$cmd_spcs_rx)";
+
+    &make_counters_rx;
+
+    # Matches a label command and its argument
+    $labels_rx = "\\\\label\\s*$O(\\d+)$C([\\s\\S]*)$O\\1$C$EOL";
+    $labels_rx8 = "\\\\label\\s*$O(\\d+)$C([\\s\\S]*)$O\\8$C$EOL";
+
+    # Matches environments that should not be touched during the translation
+#   $verbatim_env_rx = "\\s*{(verbatim|rawhtml|LVerbatim)[*]?}";
+    $verbatim_env_rx = "\\s*(\\w*[Vv]erbatim|rawhtml|imagesonly|tex2html_code)[*]?";
+    $image_env_rx = "\\s*(picture|xy|diagram)[*]?";
+    $keepcomments_rx = "\\s*(picture|makeimage|xy|diagram)[*]?";
+
+    # names of different math environment types
+    $display_env_rx = "displaymath|makeimage|eqnarray|equation";
+    $inline_env_rx = "inline|indisplay|entity|xy|diagram";
+    $sub_array_env_rx = "array|(small|\\w)\?matrix|tabular|cases";
+
+    # Matches environments needing pre-processing for images
+    $pre_processor_env_rx = "\\\\(begin|end)\\s*(($O|$OP|\{)\\d+($C|$CP|\}))pre_(\\w+)\\2";
+
+    # Matches icon markers
+    $icon_mark_rx = "<tex2html_(" . join("|", keys %icons) . ")>";
+
+    $start_time = time;
+    print STDOUT join(" ", "Starting at", $start_time, "seconds\n")
+        if ($TIMING||$DEBUG||($VERBOSITY>2));
+
+}      # end of &initialise
+
+# Frequently used regular expressions with arguments
+sub make_end_env_rx {
+    local($env) = @_;
+    $env = &escape_rx_chars($env);
+    "\\\\end\\s*$O(\\d+)$C\\s*$env\\s*$O\\1$C".$EOL;
+}
+
+sub make_begin_end_env_rx {
+    local($env) = @_;
+    $env = &escape_rx_chars($env);
+    "\\\\(begin|end)\\s*$O(\\d+)$C\\s*$env\\s*$O\\3$C(\\s*\$)?";
+}
+
+sub make_end_cmd_rx {
+    local($br_id) = @_;
+    "$O$br_id$C";
+}
+
+#JCL(jcl-del) - see also &tokenize.
+# Arrange commands into a regexp for tokenisation.
+# Any letter command will gobble spaces, but avoids to match
+# on ensuing letters (\foo won't match on \foox).
+# Any non-letter command retains spaces and matches always
+# by itself (\| matches \|... regardless of ...).
+#
+# This all is a huge kludge. The commands names should stay fix,
+# regardless of changing catcodes. If we have \makeatletter,
+# and LaTeX2HTML marks \@foo, then \@foo will be expanded
+# properly before \makeatother, but does weird things on \@foo
+# after \makeatother (\@foo in LaTeX is then \@ and foo, which
+# isn't recognized as such).
+# The reason is that the text to match the command \@foo
+# in LaTeX mustn't be \@foo at all, because any text in LaTeX
+# is also attributed with the category codes.
+#
+# But at least we have proper parsing of letter and non-letter
+# commands as long as catcoding won't upset LaTeX2HTML too much.
+#
+sub make_new_cmd_rx {
+    return("") if $#_ < 0; # empty regexp if list is empty!
+
+    # We have a subtle treatment of ambivalent commands like
+    # \@foo in situations depicted above!
+    # Get every command that contains no letters ...
+    local($nonlettercmds) =
+       &escape_rx_chars(join($CD, grep(!/[$letters]/,@_)));
+    # and every command that contains a letter
+    local($lettercmds) =
+       &escape_rx_chars(join($CD, grep(/[$letters]/,@_)));
+
+    if (%renew_command) {
+       local($renew);
+       foreach $renew (keys %renew_command) {
+           $lettercmds =~ s/(^|$CD)$renew//; }
+        $lettercmds =~ s/^$CD$//;
+    }
+
+    # replace the temporary $CD delimiter (this enables eg. \| command)
+    $nonlettercmds =~ s/$CD/|/g;
+    $lettercmds =~ s/$CD/|/g;
+
+    # In case we have no non-letter commands, insert empty parentheses
+    # to align match strings.
+    #
+    $nonlettercmds =~ s/^\||\|$//g;
+    $lettercmds =~ s/^\||\|$//g;
+    local($rx) = (length($nonlettercmds) ? "\\\\($nonlettercmds)" : "");
+    if (length($lettercmds)) {
+       $rx .= ( length($rx) ? "|" : "()" );
+       $rx .= "\\\\($lettercmds)(([^$letters$cmd_spc])|$cmd_spcs_rx|\$)";
+    }
+    # $1: non-letter cmd, $2: letter cmd, $4: delimiter
+    # Eg. \\(\@|...|\+)|\\(abc|...|xyz)(([^a-zA-Z \t])|[ \t]+)
+    # $1 and $2 are guaranteed to alternate, $4 may be empty.
+    $rx;
+}
+
+# Build a simple regexp to use after tokenisation for
+# faster translation.
+sub make_new_cmd_no_delim_rx {
+    return("") if $#_ < 0; # empty regexp if list is empty!
+    # Get every command that contains no letters ...
+    local($_) = &escape_rx_chars(join($CD, @_));
+    s/$CD/|/g;
+
+    join('',"\\\\(",$_,")");
+}
+
+
+#JCL(jcl-del) - new face: w/o arg (was 'begin' only), escapes env names
+sub make_new_env_rx {
+    local($envs) = &escape_rx_chars(join($CD, keys %new_environment));
+    $envs =~ s/$CD/|/g;
+    length($envs) ? "\\\\begin\\s*$O(\\d+)$C\\s*($envs)\\s*$O\\1$C\\s*" : "";
+}
+
+sub make_new_end_env_rx {
+    local($envs) = &escape_rx_chars(join($CD, keys %new_environment));
+    $envs =~ s/$CD/|/g;
+    length($envs) ? "\\\\end\\s*$O(\\d+)$C\\s*($envs)\\s*$O\\1$C\\s*" : "";
+}
+
+#JCL(jcl-del) - $delimiter_rx -> ^$letters
+# don't care for $cmd_spc_rx; space after sectioning commands
+# is unlikely and I don't want to try too much new things
+#
+sub make_sections_rx {
+    local($section_alts) = &get_current_sections;
+    # $section_alts includes the *-forms of sectioning commands
+    $sections_rx = "()\\\\($section_alts)(([^$letters$cmd_spc])|$cmd_spcs_rx|\$)";
+#    $sections_rx = "()\\\\($section_alts)([^$letters])";
+}
+
+sub make_order_sensitive_rx {
+    local(@theorem_alts, $theorem_alts);
+    @theorem_alts = ($preamble =~ /\\newtheorem\s*{([^\s}]+)}/og);
+    $theorem_alts = join('|',@theorem_alts);
+#
+#  HWS: Added kludge to require counters to be more than 2 characters long
+#      in order to be flagged as order-sensitive.  This will permit equations
+#      with \theta to remain order-insensitive.  Also permit \alpha and
+#      the eqnarray* environment to remain order-insensitive.
+#
+    $order_sensitive_rx =
+#        "(equation|eqnarray[^*]|\\\\caption|\\\\ref|\\\\the[a-z]{2,2}[a-z]|\\\\stepcounter" .
+        "(\\\\caption|\\\\ref|\\\\the[a-z]{2,2}[a-z]|\\\\stepcounter" .
+        "|\\\\arabic|\\\\roman|\\\\Roman|\\\\alph[^a]|\\\\Alph|\\\\fnsymbol)";
+    $order_sensitive_rx =~ s/\)/|$theorem_alts)/ if $theorem_alts;
+}
+
+sub make_language_rx {
+    local($language_alts) = join("|", keys %language_translations);
+#    $setlanguage_rx = "\\\\se(lec)?tlanguage\\s*{\\\\?($language_alts)}";
+    $setlanguage_rx = "\\\\setlanguage\\s*{\\\\?($language_alts)}";
+    $language_rx = "\\\\($language_alts)TeX";
+    $case_change_rx = "(\\\\(expandafter|noexpand)\s*)?\\\\((Make)?([Uu]pp|[Ll]ow)ercase)\s*";
+}
+
+sub addto_languages {
+    local($lang) = @_;
+    local($trans) = "main'".$lang.'_translation';
+    if (defined &$trans) {
+       $language_translations {$lang} = $lang.'_translation';
+    }
+}
+
+# JCL(jcl-del) - new rexexp type
+sub make_raw_arg_cmd_rx {
+    # $1 or $2 : commands to be processed in latex (with arguments untouched)
+    # $4 : delimiter
+    $raw_arg_cmd_rx = &make_new_cmd_rx(keys %raw_arg_cmds);
+    $raw_arg_cmd_rx;
+}
+
+# There are probably more.
+# Interferences not checked out yet, thus in makeat... only.
+sub make_letter_sensitive_rx {
+    $delimiter_rx = "([^$letters])";
+    &make_sections_rx;
+    &make_single_cmd_rx;
+    &make_counters_rx;
+}
+
+#JCL(jcl-del) - this could eat one optional newline, too.
+# But this might result in large lines... anyway, it *should* be
+# handled. A possible solution would be to convert adjacent newlines
+# into \par's in preprocessing.
+sub make_cmd_spc_rx {
+    $cmd_spc = " \\t";
+    $cmd_spc_rx = "[ \\t]*"; # zero or more
+    $cmd_spcs_rx = "[ \\t]+"; # one or more
+}
+
+sub make_single_cmd_rx {
+    $single_cmd_rx = "\\\\([^$letters])|\\\\([$letters]+\\*?)(([^$letters$cmd_spc])|$cmd_spcs_rx|\n|\$)";
+}
+
+sub make_counters_rx {
+    # Matches counter commands - these are caught early and are appended to the
+    # file that is passed to latex.
+#JCL(jcl-del) - $delimiter_rx -> ^$letters
+    $counters_rx = "()\\\\(newcounter|addtocounter|setcounter|refstepcounter|stepcounter|arabic|roman|Roman|alph|Alph|fnsymbol)(([^$letters$cmd_spc])|$cmd_spcs_rx|\$)";
+}
+
+
+# Creates an anchor for its argument and saves the information in
+# the array %index;
+# In the index the word will use the beginning of the title of
+# the current section (instead of the usual pagenumber).
+# The argument to the \index command is IGNORED (as in latex)
+sub make_index_entry { &make_real_index_entry(@_) }
+sub make_real_index_entry {
+    local($br_id,$str) = @_;
+    local($this_file) = $CURRENT_FILE;
+    $TITLE = $saved_title if (($saved_title)&&(!($TITLE)||($TITLE eq $default_title)));
+    # Save the reference
+    $str = "$str###" . ++$global{'max_id'}; # Make unique
+    $index{$str} .= &make_half_href($this_file."#$br_id");
+    "<A NAME=\"$br_id\">$anchor_invisible_mark<\/A>";
+}
+
+sub image_message { # clean
+    print <<"EOF";
+
+To resolve the image conversion problems please consult
+the "Troubleshooting" section of your local User Manual
+or read it online at
+   http://www-texdev.ics.mq.edu.au/l2h/docs/manual/
+
+EOF
+}
+
+sub image_cache_message { # clean
+   print <<"EOF";
+
+If you are having problems displaying the correct images with Mosaic,
+try selecting "Flush Image Cache" from "Options" in the menu-bar
+and then reload the HTML file.
+EOF
+}
+
+__DATA__
+
+# start of POD documentation
+
+=head1 NAME
+
+latex2html - Translate LaTeX files to HTML (HyperText Markup Language)
+
+=head1 SYNOPSIS
+
+B<latex2html> S<[ B<-help> | B<-h> ]> S<[ B<-version> | B<-V> ]>
+
+B<latex2html> S<[ B<-split> I<num> ]>
+S<[ B<-link> I<num> ]>
+S<[ B<-toc_depth> I<num> ]>
+S<[ B<->(B<no>)B<toc_stars> ]>
+S<[ B<->(B<no>)B<short_extn> ]>
+S<[ B<-iso_language> I<lang> ]>
+S<[ B<->(B<no>)B<validate> ]>
+S<[ B<->(B<no>)B<latex> ]>
+S<[ B<->(B<no>)B<djgpp> ]>
+S<[ B<->(B<no>)B<fork> ]>
+S<[ B<->(B<no>)B<external_images> ]>
+S<[ B<->(B<no>)B<ascii_mode> ]>
+S<[ B<->(B<no>)B<lcase_tags> ]>
+S<[ B<->(B<no>)B<ps_images> ]>
+S<[ B<-font_size> I<size> ]>
+S<[ B<->(B<no>)B<tex_defs> ]>
+S<[ B<->(B<no>)B<navigation> ]>
+S<[ B<->(B<no>)B<top_navigation> ]>
+S<[ B<->(B<no>)B<buttom_navigation> ]>
+S<[ B<->(B<no>)B<auto_navigation> ]>
+S<[ B<->(B<no>)B<index_in_navigation> ]>
+S<[ B<->(B<no>)B<contents_in_navigation> ]>
+S<[ B<->(B<no>)B<next_page_in_navigation> ]>
+S<[ B<->(B<no>)B<previous_page_in_navigation> ]>
+S<[ B<->(B<no>)B<footnode> ]>
+S<[ B<->(B<no>)B<numbered_footnotes> ]>
+S<[ B<-prefix> I<output_filename_prefix> ]>
+S<[ B<->(B<no>)B<auto_prefix> ]>
+S<[ B<-long_titles> I<num> ]>
+S<[ B<->(B<no>)B<custom_titles> ]>
+S<[ B<-title>|B<-t> I<top_page_title> ]>
+S<[ B<->(B<no>)B<rooted> ]>
+S<[ B<-rootdir> I<output_directory> ]>
+S<[ B<-dir> I<output_directory> ]>
+S<[ B<-mkdir> ]>
+S<[ B<-address> I<author_address> | B<-noaddress> ]>
+S<[ B<->(B<no>)B<subdir> ]>
+S<[ B<-info> I<0> | I<1> | I<string> ]>
+S<[ B<->(B<no>)B<auto_link> ]>
+S<[ B<-reuse> I<num> | B<-noreuse> ]>
+S<[ B<->(B<no>)B<antialias_text> ]>
+S<[ B<->(B<no>)B<antialias> ]>
+S<[ B<->(B<no>)B<transparent> ]>
+S<[ B<->(B<no>)B<white> ]>
+S<[ B<->(B<no>)B<discard> ]>
+S<[ B<-image_type> I<type> ]>
+S<[ B<->(B<no>)B<images> ]>
+S<[ B<-accent_images> I<type> | B<-noaccent_images> ]>
+S<[ B<-style> I<style> ]>
+S<[ B<->(B<no>)B<parbox_images> ]>
+S<[ B<->(B<no>)B<math> ]>
+S<[ B<->(B<no>)B<math_parsing> ]>
+S<[ B<->(B<no>)B<latin> ]>
+S<[ B<->(B<no>)B<entities> ]>
+S<[ B<->(B<no>)B<local_icons> ]>
+S<[ B<->(B<no>)B<scalable_fonts> ]>
+S<[ B<->(B<no>)B<images_only> ]>
+S<[ B<->(B<no>)B<show_section_numbers> ]>
+S<[ B<->(B<no>)B<show_init> ]>
+S<[ B<-init_file> I<Perl_file> ]>
+S<[ B<-up_url> I<up_URL> ]>
+S<[ B<-up_title> I<up_title> ]>
+S<[ B<-down_url> I<down_URL> ]>
+S<[ B<-down_title> I<down_title> ]>
+S<[ B<-prev_url> I<prev_URL> ]>
+S<[ B<-prev_title> I<prev_title> ]>
+S<[ B<-index> I<index_URL> ]>
+S<[ B<-biblio> I<biblio_URL> ]>
+S<[ B<-contents> I<toc_URL> ]>
+S<[ B<-external_file> I<external_aux_file> ]>
+S<[ B<->(B<no>)B<short_index> ]>
+S<[ B<->(B<no>)B<unsegment> ]>
+S<[ B<->(B<no>)B<debug> ]>
+S<[ B<-tmp> I<path> ]>
+S<[ B<->(B<no>)B<ldump> ]>
+S<[ B<->(B<no>)B<timing> ]>
+S<[ B<-verbosity> I<num> ]>
+S<[ B<-html_version> I<num> ]>
+S<[ B<->(B<no>)B<strict> ]>
+I<file.tex> S<[ I<file2.tex> ... ]>
+
+=head1 DESCRIPTION
+
+I<LaTeX2HTML> is a Perl program that translates LaTeX source files into
+HTML. For each source file given as an argument the translator will create
+a directory containing the corresponding HTML files.
+
+=head1 OPTIONS
+
+Many options can be specified in a true/false manner. This is indicated by
+I<(no)>, e.g. to enable passing unknown environments to LaTeX, say "-latex",
+to disable the feature say "-nolatex" or "-no_latex" (portability mode).
+
+=over 4
+
+=item B<-help> | B<-h>
+
+Print this online manual and exit.
+
+=item B<-version> | B<-V>
+
+Print the LaTeX2HTML release and version information and exit.
+
+=item B<-split> I<num>
+
+Stop making separate files at this depth (say "-split 0" for one huge HTML
+file).
+
+=item B<-link> I<num>
+
+Stop showing child nodes at this depth.
+
+=item B<-toc_depth> I<num>
+
+MISSING_DESCRIPTION
+
+=item B<->(B<no>)B<toc_stars>
+
+MISSING_DESCRIPTION
+
+=item B<->(B<no>)B<short_extn>
+
+If this is set all HTML file will have extension C<.htm> instead of
+C<.html>. This is helpful when shipping the document to PC systems.
+
+=item B<-iso_language> I<lang>
+
+MISSING_DESCRIPTION
+
+=item B<->(B<no>)B<validate>
+
+When this is set true, the HTML validator specified in F<l2hconf.pm>
+will run.
+
+=item B<->(B<no>)B<latex>
+
+Pass unknown environments to LaTeX. This is the default.
+
+=item B<->(B<no>)B<djgpp>
+
+Specify this switch if you are running DJGPP on DOS and need to avoid
+running out of filehandles.
+
+=item B<->(B<no>)B<fork>
+
+Enable/disable forking. The default is reasonable for this platform.
+
+=item B<->(B<no>)B<external_images>
+
+If set, leave the images outside the document.
+
+=item B<->(B<no>)B<ascii_mode>
+
+This is different from B<-noimages>.
+If this is set, B<LaTeX2HTML> will show textual tags rather than
+images, both in navigation panel and text (Eg. C<[Up]> instead the up
+icon).
+You could use this feature to create simple text from your
+document, eg. with 'Save as... Text' from B<Netscape> or with
+B<lynx -dump>.
+
+=item B<->(B<no>)B<lcase_tags>
+
+writes out HTML tag names using lowercase letters, rather than uppercase.
+
+=item B<->(B<no>)B<ps_images>
+
+If set, use links to external postscript images rather than inlined bitmaps.
+
+=item B<-font_size> I<size>
+
+To set the point size of LaTeX-generated GIF files, specify the desired
+value (i.e., C<10pt>, C<11pt>, C<12pt>, etc.).
+The default is to use the point size of the original LaTeX document.
+This value will be magnified by I<$FIGURE_SCALE_FACTOR> and
+I<$MATH_SCALE_FACTOR> defined in F<l2hconf.pm>.
+
+=item B<->(B<no>)B<tex_defs>
+
+Enable interpretation of raw TeX commands (default).
+Note: There are many variations of C<\def> that B<LaTeX2HTML> cannot process
+correctly!
+
+=item B<->(B<no>)B<navigation>
+
+Put a navigation panel at the top of each page (default).
+
+=item B<->(B<no>)B<top_navigation>
+
+Enables navigation links at the top of each page (default).
+
+=item B<->(B<no>)B<buttom_navigation>
+
+Enables navigation links at the buttom of each page.
+
+=item B<->(B<no>)B<auto_navigation>
+
+Put navigation links at the top of each page. If the page exceeds
+I<$WORDS_IN_PAGE> number of words then put one at the bottom of the page.
+
+=item B<->(B<no>)B<index_in_navigation>
+
+Put a link to the index page in the navigation panel.
+
+=item B<->(B<no>)B<contents_in_navigation>
+
+Put a link to the table of contents in the navigation panel.
+
+=item B<->(B<no>)B<next_page_in_navigation>
+
+Put a link to the next logical page in the navigation panel.
+
+=item B<->(B<no>)B<previous_page_in_navigation>
+
+Put a link to the previous logical page in the navigation panel.
+
+=item B<->(B<no>)B<footnode>
+
+Puts all footnotes onto a separate HTML page, called F<footnode.html>,
+rather than at the bottom of the page where they are referenced.
+
+=item B<->(B<no>)B<numbered_footnotes>
+
+If true, you will get every footnote applied with a subsequent number, else
+with a generic hyperlink icon.
+
+=item B<-prefix> I<output_filename_prefix>
+
+Set the output file prefix, prepended to all C<.html>, C<.gif> and C<.pl>
+files. See also B<-auto_prefix>.
+
+=item B<->(B<no>)B<auto_prefix>
+
+Set this to automatically insert the equivalent of B<-prefix >C<basename->",
+where "basename" is the base name of the file being translated.
+
+=item B<-long_titles> I<num>
+
+MISSING_DESCRIPTION
+
+=item B<->(B<no>)B<custom_titles>
+
+MISSING_DESCRIPTION
+
+=item B<-title>|B<-t> I<top_page_title>
+
+The title (displayed in the browser's title bar) the document shall get.
+
+=item B<->(B<no>)B<rooted>
+
+MISSING_DESCRIPTION
+
+=item B<-rootdir> I<output_directory>
+
+MISSING_DESCRIPTION
+
+=item B<-dir> I<output_directory>
+
+Put the result in this directory instead of parallel to the LaTeX file,
+provided the directory exists, or B<-mkdir> is specified.
+
+=item B<-mkdir>
+
+Allow directory specified with B<-dir> to be created if necessary.
+
+=item B<-address> I<author_address> | B<-noaddress>
+
+Supply your own string if you don't like the default 
+"E<lt>NameE<gt> E<lt>DateE<gt>". B<-noaddress> suppresses the
+generation of an address footer.
+
+=item B<->(B<no>)B<subdir>
+
+If set (default), B<LaTeX2HTML> creates (or reuses) another file directory.
+When false, the generated HTML files will be placed in the current
+directory.
+
+=item B<-info> I<0> | I<1> | I<string>
+
+=item B<-noinfo>
+
+If 0 is specified (or B<-noinfo> is used), do not generate an I<"About this
+document..."> section. If 1 is specified (default), the standard info page is
+generated. If a custom string is given, it is used as the info page.
+
+=item B<->(B<no>)B<auto_link>
+
+MISSING_DESCRIPTION
+
+=item B<-reuse> I<num> | B<-noreuse>
+
+If false, do not reuse or recycle identical images generated in previous
+runs. If the html subdirectory already exists, start the interactive session.
+If I<num> is nonzero, do recycle them and switch off the interactive session.
+If 1, only recycle images generated from previous runs.
+If 2, recycle images from the current and previous runs (default).
+
+=item B<->(B<no>)B<antialias_text>
+
+Use anti-aliasing in the generation of images of typeset material;
+e.g. mathematics and text, e.g. in tables and {makeimage} environments.
+
+=item B<->(B<no>)B<antialias>
+
+Use anti-aliasing in the generation of images of figures. This usually
+results in "sharper" bitmap images.
+
+=item B<->(B<no>)B<transparent>
+
+If this is set to false then any inlined images generated from "figure" 
+environments will NOT be transparent.
+
+=item B<->(B<no>)B<white>
+
+This sets the background of generated images to white for anti-aliasing.
+
+=item B<->(B<no>)B<discard>
+
+if true, the PostScript file created for each generated image
+is discarded immediately after its image has been rendered and saved in the
+required graphics format. This can lead to significant savings in disk-space,
+when there are a lot of images, since otherwise these files are not discarded 
+until the end of all processing.
+
+=item B<-image_type> I<type>
+
+Specify the type of bitmap images to be generated. Depending on your setup,
+B<LaTeX2HTML> can generate B<gif> or B<png> images. Note: Gif images have
+certain legal restrictions, as their generation involves an algorithm
+patented by Unisys.
+
+=item B<->(B<no>)B<images>
+
+If false, B<LaTeX2HTML> will not attempt to produce any inlined images.
+The missing images can be generated "off-line" by restarting B<LaTeX2HTML>
+with B<-images_only>.
+
+=item B<-accent_images> I<type> | B<-noaccent_images>
+
+MISSING_DESCRIPTION
+
+=item B<-style> I<style>
+
+MISSING_DESCRIPTION
+
+=item B<->(B<no>)B<parbox_images>
+
+MISSING_DESCRIPTION
+
+=item B<->(B<no>)B<math>
+
+By default the special MATH extensions are not used
+since they do not conform with the HTML 3.2 standard.
+
+=item B<->(B<no>)B<math_parsing>
+
+MISSING_DESCRIPTION
+
+=item B<->(B<no>)B<latin>
+
+MISSING_DESCRIPTION
+
+=item B<->(B<no>)B<entities>
+
+MISSING_DESCRIPTION
+
+=item B<->(B<no>)B<local_icons>
+
+Set this if you want to copy the navigation icons to each document directory
+so that the document directory is self-contained and can be dropped into
+another server tree without further actions.
+
+=item B<->(B<no>)B<scalable_fonts>
+
+MISSING_DESCRIPTION
+
+=item B<->(B<no>)B<images_only>
+
+When true, B<LaTeX2HTML> will only try to convert the inlined images in the
+file F<images.tex> which should have been generated automatically during
+previous runs. This is very useful for correcting "bad LaTeX" in this file.
+
+=item B<->(B<no>)B<show_section_numbers>
+
+When this is set true, the section numbers are shown. The section numbers
+should then match those that would have been produced by LaTeX.
+The correct section numbers are obtained from the $FILE.aux file generated 
+by LaTeX.
+Hiding the section numbers encourages use of particular sections 
+as standalone documents. In this case the cross reference to a section 
+is shown using the default symbol rather than the section number.
+
+=item B<->(B<no>)B<show_init>
+
+MISSING_DESCRIPTION
+
+=item B<-init_file> I<Perl_file>
+
+MISSING_DESCRIPTION
+
+=item B<-up_url> I<up_URL>, B<-up_title> I<up_title>
+
+=item B<-down_url> I<down_URL>, B<-down_title> I<down_title>
+
+=item B<-prev_url> I<prev_URL>, B<-prev_title> I<prev_title>
+
+=item B<-index> I<index_URL>,
+
+=item B<-contents> I<toc_URL>
+
+=item B<-biblio> I<biblio_URL>
+
+If both of the listed two options are set then the "Up" ("Previous" etc.)
+button of the navigation panel in the first node/page of a converted
+document will point to I<up_URL> etc. I<up_title> should be set
+to some text which describes this external link.
+Similarly you might use these options to link external documents
+to your navigation panel.
+
+=item B<-external_file> I<external_aux_file>
+
+MISSING_DESCRIPTION
+
+=item B<->(B<no>)B<short_index>
+
+If this is set then B<makeidx.perl> will construct codified names
+for the text of index references.
+
+=item B<->(B<no>)B<unsegment>
+
+Use this to translate a segmented document as if it were not
+segmented.
+
+=item B<->(B<no>)B<debug>
+
+If this is set then intermediate files are left for later inspection and
+a lot of diagnostic output is produced. This output may be useful when
+searching for problems and/or submitting bug reports to the developers.
+Temporary files include F<$$_images.tex> and F<$$_images.log> created during
+image conversion. Caution: Intermediate files can be I<enormous>!
+
+=item B<-tmp> I<path>
+
+Path for temporary files. This should be a local, fast filesystem because it is heavily used during image generation. The default is set in F<l2hconf.pm>.
+
+=item B<->(B<no>)B<ldump>
+
+This will cause LaTeX2HTML to produce a LaTeX dump of images.tex which is read
+in on subsequent runs and speeds up startup time of LaTeX on the images.tex
+translation. This actually consumes additional time on the first run, but pays
+off on subsequent runs. The dump file will need about 1 Meg of disk space.
+
+=item B<->(B<no>)B<timing>
+
+MISSING_DESCRIPTION
+
+=item B<-verbosity> I<num>
+
+The amount of message information printed to the screen during processing
+by B<LaTeX2HTML> is controlled by this setting.
+By increasing this value, more information is displayed.
+Here is the type of extra information that is shown at each level:
+
+  0   no extra information
+  1   section types and titles
+  2   environment
+  3   command names
+  4   links, labels and internal sectioning codes
+
+=item B<-html_version> I<list>
+
+Which HTML version should be generated. Currently available are:
+C<2.0>, C<3.0>, C<3.2>, C<4.0>. Some additional options that may be
+added are: C<math> (parse mathematics), C<i18n> (?), 
+C<table> (generate tables), C<frame> (generate frames),
+C<latin1>...C<latin9> (use ISO-Latin-x encoding),
+C<unicode> (generate unicode characters). Separate the options with ',',
+e.g. C<4.0,math,frame>.
+
+=item B<->(B<no>)B<strict>
+
+MISSING_DESCRIPTION
+
+=back
+
+=head1 FILES
+
+=over 4
+
+=item F<$LATEX2HTMLPLATDIR/l2hconf.pm>
+
+This file holds the global defaults and configuration settings for
+B<LaTeX2HTML>.
+
+=item F<$HOME/.latex2html-init>
+
+=item F<./.latex2html-init>
+
+These files may contain settings that override the global defaults, just
+like specifying command line switches.
+
+=back
+
+=head1 ENVIRONMENT
+
+=over 4
+
+=item LATEX2HTMLDIR
+
+Path where LaTeX2HTML library files are found. On this installation
+LATEX2HTMLDIR is F</usr/share/latex2html>
+
+=item PERL5LIB
+
+Set by the B<latex2html> program to find perl modules.
+
+=item L2HCONFIG
+
+An alternative configuration filename. The standard configuration file
+is F<$LATEX2HTMLPLATDIR/l2hconf.pm>. You may specify a sole filename (searched
+for in F<$LATEX2HTMLPLATDIR> (and F<$PERL5LIB>) or a complete path.
+
+=item L2HINIT_NAME
+
+The standard user-specific configuration filename is F<.latex2html-init>.
+This environment variable will override this name.
+
+=item HOME
+
+Evaluated if the system does not know about "home" directories (like
+DOS, WinXX, OS/2, ...) to determine the path to F<$L2HINIT_NAME>.
+
+=item TEXE_DONT_INCLUDE, TEXE_DO_INCLUDE
+
+Used internally for communication with B<texexpand>.
+
+=item TEXINPUTS
+
+Used to find TeX includes of all sorts.
+
+=back
+
+=head1 PROBLEMS
+
+For information on various problems and remedies see the WWW online
+documentation or the documents available in the distribution.
+An online bug reporting form and various archives are available at
+F<http://www.latex2html.org/>
+
+There is a mailing list for discussing B<LaTeX2HTML>: C<latex2html@tug.org>
+
+=head1 AUTHOR
+
+Nikos Drakos,  Computer Based Learning Unit, University of Leeds
+E<lt>nikos@cbl.leeds.ac.ukE<gt>. Several people have contributed
+suggestions, ideas, solutions, support and encouragement.
+
+The B<pstoimg> script was written by Marek Rouchal 
+E<lt>marek@saftsack.fs.uni-bayreuth.deE<gt>
+as a generalisation of the B<pstogif> utility to allow graphic formats
+other than GIF to be created. Various options and enhancements have
+been added by Ross Moore.
+Some of the code is based upon the pstoppm.ps postscript program 
+originally written by Phillip Conrad (Perfect Byte, Inc.)
+and modified by L. Peter Deutsch (Aladdin Enterprises).
+
+=head1 SEE ALSO
+
+See the WWW online documentation or the F<$LATEX2HTMLDIR/doc/manual.ps>
+file for more detailed information and examples.
+
+L<pstoing>, L<texexpand>
+
+=cut
+
diff --git a/gosa-core/contrib/mysql/README b/gosa-core/contrib/mysql/README
new file mode 100644 (file)
index 0000000..f511910
--- /dev/null
@@ -0,0 +1,6 @@
+
+in those directories you will find the database definitions for the plugins
+gofax gofon glog with mysql.
+
+Benoit Mortier <benoit.mortier@opensides.be>
+
diff --git a/gosa-core/contrib/mysql/glpi/glpi.sql b/gosa-core/contrib/mysql/glpi/glpi.sql
new file mode 100644 (file)
index 0000000..a18e3b7
--- /dev/null
@@ -0,0 +1,1627 @@
+create database glpi;
+use glpi;
+
+CREATE TABLE `glpi_cartridges` (
+  `ID` int(11) NOT NULL auto_increment,
+  `FK_glpi_cartridges_type` int(11) NOT NULL default '0',
+  `FK_glpi_printers` int(11) NOT NULL default '0',
+  `date_in` date default NULL,
+  `date_use` date default NULL,
+  `date_out` date default NULL,
+  `pages` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_cartridges_type` (`FK_glpi_cartridges_type`),
+  KEY `FK_glpi_printers` (`FK_glpi_printers`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
+
+INSERT INTO `glpi_cartridges` (`ID`, `FK_glpi_cartridges_type`, `FK_glpi_printers`, `date_in`, `date_use`, `date_out`, `pages`) VALUES 
+(5, 5, 5, '2006-09-29', '2006-09-29', NULL, 0),
+(4, 5, 5, '2006-09-29', '2006-09-29', NULL, 0);
+
+
+CREATE TABLE `glpi_cartridges_assoc` (
+  `ID` int(11) NOT NULL auto_increment,
+  `FK_glpi_cartridges_type` int(11) NOT NULL default '0',
+  `FK_glpi_type_printer` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `FK_glpi_type_printer` (`FK_glpi_type_printer`,`FK_glpi_cartridges_type`),
+  KEY `FK_glpi_cartridges_type` (`FK_glpi_cartridges_type`),
+  KEY `FK_glpi_type_printer_2` (`FK_glpi_type_printer`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;
+
+
+INSERT INTO `glpi_cartridges_assoc` (`ID`, `FK_glpi_cartridges_type`, `FK_glpi_type_printer`) VALUES 
+(1, 1, 1),
+(2, 2, 5),
+(3, 2, 1),
+(4, 3, 13),
+(5, 4, 13),
+(6, 5, 11),
+(7, 5, 10),
+(8, 5, 5),
+(9, 5, 12),
+(10, 5, 2),
+(11, 5, 14),
+(12, 5, 3);
+
+
+
+CREATE TABLE `glpi_cartridges_type` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `ref` varchar(255) NOT NULL default '',
+  `location` int(11) NOT NULL default '0',
+  `type` tinyint(4) NOT NULL default '0',
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `tech_num` int(11) default '0',
+  `deleted` enum('Y','N') NOT NULL default 'N',
+  `comments` text NOT NULL,
+  `alarm` tinyint(4) NOT NULL default '10',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
+  KEY `tech_num` (`tech_num`),
+  KEY `deleted` (`deleted`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
+
+
+INSERT INTO `glpi_cartridges_type` (`ID`, `name`, `ref`, `location`, `type`, `FK_glpi_enterprise`, `tech_num`, `deleted`, `comments`, `alarm`) VALUES 
+(1, 'TestPatrone', '', 0, 1, 8, 0, '', '', 0),
+(2, 'HP_deskjet_7100C', '', 0, 4, 8, 0, '', 'None', 0),
+(3, 'teseter', '', 0, 3, 12, 0, '', '', 0),
+(4, 'teseter2', '', 0, 3, 12, 0, '', '', 0),
+(5, 'Epson Stylus Nuclear Color', '', 0, 3, 12, 0, '', 'Uranium green.\r\n', 0);
+
+
+
+CREATE TABLE `glpi_computer_device` (
+  `ID` int(11) NOT NULL auto_increment,
+  `specificity` varchar(250) NOT NULL default '',
+  `device_type` tinyint(4) NOT NULL default '0',
+  `FK_device` int(11) NOT NULL default '0',
+  `FK_computers` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  KEY `device_type` (`device_type`),
+  KEY `device_type_2` (`device_type`,`FK_device`),
+  KEY `FK_computers` (`FK_computers`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=136 ;
+
+
+INSERT INTO `glpi_computer_device` (`ID`, `specificity`, `device_type`, `FK_device`, `FK_computers`) VALUES 
+(87, '', 1, 1, 1),
+(92, '', 1, 1, 13),
+(133, '', 1, 1, 17),
+(120, '', 1, 1, 23),
+(122, '', 1, 1, 24),
+(135, '', 1, 1, 19),
+(132, '', 1, 1, 29);
+
+
+
+CREATE TABLE `glpi_computers` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(200) NOT NULL default '',
+  `serial` varchar(200) NOT NULL default '',
+  `otherserial` varchar(200) NOT NULL default '',
+  `contact` varchar(90) NOT NULL default '',
+  `contact_num` varchar(90) NOT NULL default '',
+  `tech_num` int(11) NOT NULL default '0',
+  `comments` text NOT NULL,
+  `date_mod` datetime default NULL,
+  `os` int(11) default NULL,
+  `location` int(11) default NULL,
+  `domain` int(11) NOT NULL default '0',
+  `network` int(11) NOT NULL default '0',
+  `model` int(11) default NULL,
+  `type` int(11) default NULL,
+  `is_template` enum('0','1') NOT NULL default '0',
+  `tplname` varchar(200) default NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `deleted` enum('Y','N') NOT NULL default 'N',
+  PRIMARY KEY  (`ID`),
+  KEY `location` (`location`),
+  KEY `os` (`os`),
+  KEY `type` (`model`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
+  KEY `deleted` (`deleted`),
+  KEY `is_template` (`is_template`),
+  KEY `date_mod` (`date_mod`),
+  KEY `tech_num` (`tech_num`),
+  KEY `type_2` (`type`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=41 ;
+
+
+INSERT INTO `glpi_computers` (`ID`, `name`, `serial`, `otherserial`, `contact`, `contact_num`, `tech_num`, `comments`, `date_mod`, `os`, `location`, `domain`, `network`, `model`, `type`, `is_template`, `tplname`, `FK_glpi_enterprise`, `deleted`) VALUES 
+(1, 'cn=asterisk,ou=servers,ou=systems,dc=gonicus,dc=de', '', '', '', '1', 1, '', '2006-03-08 12:12:04', 5, 0, 0, 0, 0, 27, '0', NULL, 8, 'N'),
+(4, 'cn=pyramid,ou=terminals,ou=systems,dc=gonicus,dc=de', '', '', '', '', 0, '', '2006-03-08 07:05:07', 5, 0, 0, 0, 0, 21, '0', NULL, 8, 'N'),
+(5, 'cn=ctu03,ou=phones,ou=systems,dc=gonicus,dc=de', '', '', '', '', 0, '', '2006-02-10 08:58:15', 6, 0, 0, 0, 0, 21, '0', NULL, 8, 'N'),
+(6, 'cn=fax,ou=servers,ou=systems,dc=gonicus,dc=de', '', '', '', '', 3, '', '2006-03-01 10:04:06', 6, 0, 0, 0, 0, 21, '0', NULL, 12, 'N'),
+(19, 'cn=cl1--6665,ou=workstations,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '18', 0, '', '2007-01-30 08:03:00', 5, 0, 0, 0, 0, 27, '0', NULL, 16, 'N'),
+(11, 'cn=vserver-04f,ou=servers,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '', 0, '', '2006-05-12 07:51:32', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
+(13, 'cn=GetraenkeHalter,ou=netdevices,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '6', 7, 'tester', '2006-06-21 12:34:54', 7, 0, 0, 0, 0, 28, '0', NULL, 16, 'N'),
+(18, 'cn=cl1--151,ou=workstations,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'tester', '2007-01-30 07:55:33', 18, 0, 0, 0, 0, 18, '0', NULL, 16, 'N'),
+(16, 'cn=ctu153,ou=phones,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '8', 9, 'Tester für den Comment \\\\\\n<br>\r\ntester', '2006-06-20 09:24:35', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
+(17, 'cn=cl1--157,ou=workstations,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'asdfasdf \n\r\nasdf', '2007-01-30 07:01:41', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
+(20, 'cn=vserver-01.intranet.gonicus.de,ou=servers,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'sda', '2007-05-21 06:53:29', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
+(21, 'cn=vserver-01.intranet.gonicus.de,ou=servers,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'sda', '2007-05-21 06:53:29', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
+(23, 'cn=kohlenhydrate,ou=servers,ou=systems,ou=keks,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '11', 11, 'eg', '2006-09-29 09:37:30', 7, 0, 0, 0, 0, 26, '0', NULL, 8, 'N'),
+(24, 'cn=Mineralstoffe,ou=workstations,ou=systems,ou=keks,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'dfsaaaaaaaaaaaaaaaaaaaaaaaaaaa', '2006-10-18 11:21:03', 7, 0, 0, 0, 0, 27, '0', NULL, 16, 'N'),
+(25, 'cn=Ammoniumcarbonat,ou=phones,ou=systems,ou=keks,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '11', 11, 'asdf', '2006-09-29 10:34:32', 7, 0, 0, 0, 0, 21, '0', NULL, 16, 'N'),
+(26, 'cn=Kakaomasse,ou=netdevices,ou=systems,ou=keks,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '11', 11, 'ikk', '2006-09-29 10:41:12', 7, 0, 0, 0, 0, 27, '0', NULL, 8, 'N'),
+(27, 'cn=afs-22,ou=servers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '', 0, '-ö', '2006-11-30 13:31:50', 7, 0, 0, 0, 0, 26, '0', NULL, 16, 'N'),
+(28, 'cn=Netzwerkkomponente,ou=netdevices,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '11', 0, '', '2006-11-29 14:43:00', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
+(29, 'cn=vserver-04.intranet.gonicus.de,ou=servers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'asdfasdf', '2006-11-30 12:48:22', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
+(30, 'cn=okulele,ou=servers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '21', 21, 'No comment', '2007-01-23 14:20:48', 11, 0, 0, 0, 0, 21, '0', NULL, 16, 'N'),
+(31, 'cn=keksesindlecker45,ou=workstations,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '', 0, 'sdfsdfaasdf', '2007-01-16 08:26:35', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N'),
+(32, 'cn=phoneTesterAparatz,ou=phones,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '', 0, '', '2007-01-15 08:21:39', 5, 0, 0, 0, 0, 18, '0', NULL, 12, 'N'),
+(39, 'cn=terminal,ou=terminals,ou=systems,o=Landeshauptstadt München,c=de', '', '', '', '', 0, '', '2007-05-21 07:02:42', 6, 0, 0, 0, 0, 28, '0', NULL, 12, 'N');
+
+
+
+CREATE TABLE `glpi_config` (
+  `ID` int(11) NOT NULL auto_increment,
+  `ldap_port` varchar(10) NOT NULL default '389',
+  `num_of_events` varchar(200) NOT NULL default '',
+  `jobs_at_login` varchar(200) NOT NULL default '',
+  `sendexpire` varchar(200) NOT NULL default '',
+  `cut` varchar(200) NOT NULL default '',
+  `expire_events` varchar(200) NOT NULL default '',
+  `list_limit` varchar(200) NOT NULL default '',
+  `version` varchar(200) NOT NULL default '',
+  `logotxt` varchar(200) NOT NULL default '',
+  `root_doc` varchar(200) NOT NULL default '',
+  `event_loglevel` varchar(200) NOT NULL default '',
+  `mailing` varchar(200) NOT NULL default '',
+  `imap_auth_server` varchar(200) NOT NULL default '',
+  `imap_host` varchar(200) NOT NULL default '',
+  `ldap_host` varchar(200) NOT NULL default '',
+  `ldap_basedn` varchar(200) NOT NULL default '',
+  `ldap_rootdn` varchar(200) NOT NULL default '',
+  `ldap_pass` varchar(200) NOT NULL default '',
+  `admin_email` varchar(200) NOT NULL default '',
+  `mailing_resa_all_admin` varchar(200) NOT NULL default '0',
+  `mailing_resa_user` varchar(200) NOT NULL default '1',
+  `mailing_resa_admin` varchar(200) NOT NULL default '1',
+  `mailing_signature` varchar(200) NOT NULL default '',
+  `mailing_new_admin` varchar(200) NOT NULL default '',
+  `mailing_followup_admin` varchar(200) NOT NULL default '',
+  `mailing_finish_admin` varchar(200) NOT NULL default '',
+  `mailing_new_all_admin` varchar(200) NOT NULL default '',
+  `mailing_followup_all_admin` varchar(200) NOT NULL default '',
+  `mailing_finish_all_admin` varchar(200) NOT NULL default '',
+  `mailing_new_all_normal` varchar(200) NOT NULL default '',
+  `mailing_followup_all_normal` varchar(200) NOT NULL default '',
+  `mailing_finish_all_normal` varchar(200) NOT NULL default '',
+  `mailing_new_attrib` varchar(200) NOT NULL default '',
+  `mailing_followup_attrib` varchar(200) NOT NULL default '',
+  `mailing_finish_attrib` varchar(200) NOT NULL default '',
+  `mailing_new_user` varchar(200) NOT NULL default '',
+  `mailing_followup_user` varchar(200) NOT NULL default '',
+  `mailing_finish_user` varchar(200) NOT NULL default '',
+  `ldap_field_name` varchar(200) NOT NULL default '',
+  `ldap_field_email` varchar(200) NOT NULL default '',
+  `ldap_field_location` varchar(200) NOT NULL default '',
+  `ldap_field_realname` varchar(200) NOT NULL default '',
+  `ldap_field_phone` varchar(200) NOT NULL default '',
+  `ldap_condition` varchar(255) NOT NULL default '',
+  `permit_helpdesk` varchar(200) NOT NULL default '',
+  `default_language` varchar(255) NOT NULL default 'french',
+  `priority_1` varchar(200) NOT NULL default '#fff2f2',
+  `priority_2` varchar(200) NOT NULL default '#ffe0e0',
+  `priority_3` varchar(200) NOT NULL default '#ffcece',
+  `priority_4` varchar(200) NOT NULL default '#ffbfbf',
+  `priority_5` varchar(200) NOT NULL default '#ffadad',
+  `date_fiscale` date NOT NULL default '2005-12-31',
+  `cartridges_alarm` int(11) NOT NULL default '10',
+  `cas_host` varchar(255) NOT NULL default '',
+  `cas_port` varchar(255) NOT NULL default '',
+  `cas_uri` varchar(255) NOT NULL default '',
+  `planning_begin` time NOT NULL default '08:00:00',
+  `planning_end` time NOT NULL default '20:00:00',
+  `utf8_conv` int(11) NOT NULL default '0',
+  `auto_assign` enum('0','1') NOT NULL default '0',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
+
+
+INSERT INTO `glpi_config` (`ID`, `ldap_port`, `num_of_events`, `jobs_at_login`, `sendexpire`, `cut`, `expire_events`, `list_limit`, `version`, `logotxt`, `root_doc`, `event_loglevel`, `mailing`, `imap_auth_server`, `imap_host`, `ldap_host`, `ldap_basedn`, `ldap_rootdn`, `ldap_pass`, `admin_email`, `mailing_resa_all_admin`, `mailing_resa_user`, `mailing_resa_admin`, `mailing_signature`, `mailing_new_admin`, `mailing_followup_admin`, `mailing_finish_admin`, `mailing_new_all_admin`, `mailing_followup_all_admin`, `mailing_finish_all_admin`, `mailing_new_all_normal`, `mailing_followup_all_normal`, `mailing_finish_all_normal`, `mailing_new_attrib`, `mailing_followup_attrib`, `mailing_finish_attrib`, `mailing_new_user`, `mailing_followup_user`, `mailing_finish_user`, `ldap_field_name`, `ldap_field_email`, `ldap_field_location`, `ldap_field_realname`, `ldap_field_phone`, `ldap_condition`, `permit_helpdesk`, `default_language`, `priority_1`, `priority_2`, `priority_3`, `priority_4`, `priority_5`, `date_fiscale`, `cartridges_alarm`, `cas_host`, `cas_port`, `cas_uri`, `planning_begin`, `planning_end`, `utf8_conv`, `auto_assign`) VALUES 
+(1, '389', '10', '1', '1', '80', '30', '15', ' 0.6', 'GLPI powered by indepnet', '/glpi', '5', '0', '', '', '', '', '', '', 'admsys@xxxxx.fr', '0', '1', '1', 'SIGNATURE', '1', '1', '1', '1', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', 'uid', 'mail', 'physicaldeliveryofficename', 'cn', 'telephonenumber', '', '', 'english', '#fff2f2', '#ffe0e0', '#ffcece', '#ffbfbf', '#ffadad', '2005-12-31', 10, '', '', '', '08:00:00', '20:00:00', 0, '0');
+
+
+
+CREATE TABLE `glpi_connect_wire` (
+  `ID` int(11) NOT NULL auto_increment,
+  `end1` int(11) NOT NULL default '0',
+  `end2` int(11) NOT NULL default '0',
+  `type` tinyint(4) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `end1_1` (`end1`,`end2`,`type`),
+  KEY `end1` (`end1`),
+  KEY `end2` (`end2`),
+  KEY `type` (`type`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=10 ;
+
+
+INSERT INTO `glpi_connect_wire` (`ID`, `end1`, `end2`, `type`) VALUES 
+(1, 1, 1, 4),
+(5, 2, 17, 4),
+(4, 2, 13, 4),
+(7, 2, 23, 4),
+(8, 2, 24, 4),
+(9, 2, 29, 4);
+
+
+
+CREATE TABLE `glpi_consumables` (
+  `ID` int(11) NOT NULL auto_increment,
+  `FK_glpi_consumables_type` int(11) default NULL,
+  `date_in` date default NULL,
+  `date_out` date default NULL,
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_cartridges_type` (`FK_glpi_consumables_type`),
+  KEY `date_in` (`date_in`),
+  KEY `date_out` (`date_out`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_consumables_type` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `ref` varchar(255) NOT NULL default '',
+  `location` int(11) NOT NULL default '0',
+  `type` tinyint(4) NOT NULL default '0',
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `tech_num` int(11) default '0',
+  `deleted` enum('Y','N') NOT NULL default 'N',
+  `comments` text NOT NULL,
+  `alarm` tinyint(4) NOT NULL default '10',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
+  KEY `tech_num` (`tech_num`),
+  KEY `deleted` (`deleted`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_contact_enterprise` (
+  `ID` int(11) NOT NULL auto_increment,
+  `FK_enterprise` int(11) NOT NULL default '0',
+  `FK_contact` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `FK_enterprise` (`FK_enterprise`,`FK_contact`),
+  KEY `FK_enterprise_2` (`FK_enterprise`),
+  KEY `FK_contact` (`FK_contact`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_contacts` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `phone` varchar(30) NOT NULL default '',
+  `phone2` varchar(30) NOT NULL default '',
+  `fax` varchar(30) NOT NULL default '',
+  `email` varchar(255) NOT NULL default '',
+  `type` tinyint(4) NOT NULL default '1',
+  `comments` text NOT NULL,
+  `deleted` enum('Y','N') NOT NULL default 'N',
+  PRIMARY KEY  (`ID`),
+  KEY `deleted` (`deleted`),
+  KEY `type` (`type`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_contract_device` (
+  `ID` int(11) NOT NULL auto_increment,
+  `FK_contract` int(11) NOT NULL default '0',
+  `FK_device` int(11) NOT NULL default '0',
+  `device_type` tinyint(4) NOT NULL default '0',
+  `is_template` enum('0','1') NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `FK_contract` (`FK_contract`,`FK_device`,`device_type`),
+  KEY `FK_contract_2` (`FK_contract`),
+  KEY `FK_device` (`FK_device`,`device_type`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_contract_enterprise` (
+  `ID` int(11) NOT NULL auto_increment,
+  `FK_enterprise` int(11) NOT NULL default '0',
+  `FK_contract` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `FK_enterprise` (`FK_enterprise`,`FK_contract`),
+  KEY `FK_enterprise_2` (`FK_enterprise`),
+  KEY `FK_contract` (`FK_contract`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_contracts` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `num` varchar(255) NOT NULL default '',
+  `cost` float NOT NULL default '0',
+  `contract_type` int(11) NOT NULL default '0',
+  `begin_date` date default NULL,
+  `duration` tinyint(4) NOT NULL default '0',
+  `notice` tinyint(4) NOT NULL default '0',
+  `periodicity` tinyint(4) NOT NULL default '0',
+  `facturation` tinyint(4) NOT NULL default '0',
+  `bill_type` int(11) NOT NULL default '0',
+  `comments` text NOT NULL,
+  `compta_num` varchar(255) NOT NULL default '',
+  `deleted` enum('Y','N') NOT NULL default 'N',
+  `week_begin_hour` time NOT NULL default '00:00:00',
+  `week_end_hour` time NOT NULL default '00:00:00',
+  `saturday_begin_hour` time NOT NULL default '00:00:00',
+  `saturday_end_hour` time NOT NULL default '00:00:00',
+  `saturday` enum('Y','N') NOT NULL default 'N',
+  `monday_begin_hour` time NOT NULL default '00:00:00',
+  `monday_end_hour` time NOT NULL default '00:00:00',
+  `monday` enum('Y','N') NOT NULL default 'N',
+  `device_countmax` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  KEY `contract_type` (`contract_type`),
+  KEY `begin_date` (`begin_date`),
+  KEY `bill_type` (`bill_type`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_device_case` (
+  `ID` int(11) NOT NULL auto_increment,
+  `designation` varchar(255) NOT NULL default '',
+  `format` enum('Grand','Moyen','Micro') NOT NULL default 'Moyen',
+  `comment` text NOT NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `specif_default` varchar(250) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
+
+
+
+
+
+CREATE TABLE `glpi_device_control` (
+  `ID` int(11) NOT NULL auto_increment,
+  `designation` varchar(255) NOT NULL default '',
+  `interface` enum('IDE','SATA','SCSI','USB') NOT NULL default 'IDE',
+  `raid` enum('Y','N') NOT NULL default 'Y',
+  `comment` text NOT NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `specif_default` varchar(250) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
+
+
+
+
+
+CREATE TABLE `glpi_device_drive` (
+  `ID` int(11) NOT NULL auto_increment,
+  `designation` varchar(255) NOT NULL default '',
+  `is_writer` enum('Y','N') NOT NULL default 'Y',
+  `speed` varchar(30) NOT NULL default '',
+  `interface` enum('IDE','SATA','SCSI') NOT NULL default 'IDE',
+  `comment` text NOT NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `specif_default` varchar(250) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
+
+
+
+
+
+CREATE TABLE `glpi_device_gfxcard` (
+  `ID` int(11) NOT NULL auto_increment,
+  `designation` varchar(120) NOT NULL default '',
+  `ram` varchar(10) NOT NULL default '',
+  `interface` enum('AGP','PCI','PCI-X','Other') NOT NULL default 'AGP',
+  `comment` text NOT NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `specif_default` varchar(250) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
+
+
+
+
+
+CREATE TABLE `glpi_device_hdd` (
+  `ID` int(11) NOT NULL auto_increment,
+  `designation` varchar(100) NOT NULL default '',
+  `rpm` varchar(20) NOT NULL default '',
+  `interface` int(11) NOT NULL default '0',
+  `cache` varchar(20) NOT NULL default '',
+  `comment` text NOT NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `specif_default` varchar(250) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
+
+
+
+
+
+CREATE TABLE `glpi_device_iface` (
+  `ID` int(11) NOT NULL auto_increment,
+  `designation` varchar(120) NOT NULL default '',
+  `bandwidth` varchar(20) NOT NULL default '',
+  `comment` text NOT NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `specif_default` varchar(250) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
+
+
+
+
+
+CREATE TABLE `glpi_device_moboard` (
+  `ID` int(11) NOT NULL auto_increment,
+  `designation` varchar(100) NOT NULL default '',
+  `chipset` varchar(120) NOT NULL default '',
+  `comment` text NOT NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `specif_default` varchar(250) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
+
+
+INSERT INTO `glpi_device_moboard` (`ID`, `designation`, `chipset`, `comment`, `FK_glpi_enterprise`, `specif_default`) VALUES 
+(1, 'NVidia Nforce 9', 'Nforce', 'kein', 2, '');
+
+
+
+CREATE TABLE `glpi_device_pci` (
+  `ID` int(11) NOT NULL auto_increment,
+  `designation` varchar(255) NOT NULL default '',
+  `comment` text NOT NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `specif_default` varchar(250) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
+
+
+
+
+
+CREATE TABLE `glpi_device_power` (
+  `ID` int(11) NOT NULL auto_increment,
+  `designation` varchar(255) NOT NULL default '',
+  `power` varchar(20) NOT NULL default '',
+  `atx` enum('Y','N') NOT NULL default 'Y',
+  `comment` text NOT NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `specif_default` varchar(250) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
+
+
+
+
+
+CREATE TABLE `glpi_device_processor` (
+  `ID` int(11) NOT NULL auto_increment,
+  `designation` varchar(120) NOT NULL default '',
+  `frequence` int(11) NOT NULL default '0',
+  `comment` text NOT NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `specif_default` varchar(250) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
+
+
+
+
+
+CREATE TABLE `glpi_device_ram` (
+  `ID` int(11) NOT NULL auto_increment,
+  `designation` varchar(100) NOT NULL default '',
+  `frequence` varchar(8) NOT NULL default '',
+  `comment` text NOT NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `specif_default` varchar(250) NOT NULL default '',
+  `type` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
+
+
+
+
+
+CREATE TABLE `glpi_device_sndcard` (
+  `ID` int(11) NOT NULL auto_increment,
+  `designation` varchar(120) NOT NULL default '',
+  `type` varchar(100) NOT NULL default '',
+  `comment` text NOT NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `specif_default` varchar(250) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
+
+
+
+
+
+CREATE TABLE `glpi_doc_device` (
+  `ID` int(11) NOT NULL auto_increment,
+  `FK_doc` int(11) NOT NULL default '0',
+  `FK_device` int(11) NOT NULL default '0',
+  `device_type` tinyint(4) NOT NULL default '0',
+  `is_template` enum('0','1') NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `FK_doc` (`FK_doc`,`FK_device`,`device_type`),
+  KEY `FK_doc_2` (`FK_doc`),
+  KEY `FK_device` (`FK_device`,`device_type`),
+  KEY `is_template` (`is_template`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=55 ;
+
+
+INSERT INTO `glpi_doc_device` (`ID`, `FK_doc`, `FK_device`, `device_type`, `is_template`) VALUES 
+(17, 1, 1, 1, '0'),
+(8, 1, 2, 1, '0'),
+(50, 1, 1, 3, '0'),
+(51, 4, 5, 3, '0'),
+(52, 1, 7, 3, '0'),
+(53, 4, 7, 3, '0'),
+(54, 1, 8, 3, '0');
+
+
+
+CREATE TABLE `glpi_docs` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `filename` varchar(255) NOT NULL default '',
+  `rubrique` int(11) NOT NULL default '0',
+  `mime` varchar(30) NOT NULL default '',
+  `date_mod` datetime NOT NULL default '0000-00-00 00:00:00',
+  `comment` text NOT NULL,
+  `deleted` enum('Y','N') NOT NULL default 'N',
+  `link` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `rubrique` (`rubrique`),
+  KEY `deleted` (`deleted`),
+  KEY `date_mod` (`date_mod`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
+
+
+INSERT INTO `glpi_docs` (`ID`, `name`, `filename`, `rubrique`, `mime`, `date_mod`, `comment`, `deleted`, `link`) VALUES 
+(1, 'Anleitung', 'class_mail-methods-kolab.inc', 0, 'application/octet-stream', '2006-01-25 11:23:16', 'leeer', 'N', ''),
+(4, 'Hardware handbuch', 'sieve-php.inc', 0, 'application/octet-stream', '2006-09-29 11:01:52', 'Steht alles drin.\r\n42.342 Seiten', 'N', '');
+
+
+
+CREATE TABLE `glpi_dropdown_cartridge_type` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=14 ;
+
+
+INSERT INTO `glpi_dropdown_cartridge_type` (`ID`, `name`) VALUES 
+(3, 'Color blue'),
+(4, 'Color combination RGB'),
+(6, 'Laser Cartridge Red'),
+(8, 'Laser Cartridge Green'),
+(9, 'Laser Cartridge combination RGB'),
+(10, 'Color Black'),
+(11, 'Color Black /& Rgb');
+
+
+
+CREATE TABLE `glpi_dropdown_consumable_type` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_dropdown_contact_type` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_dropdown_contract_type` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
+
+
+INSERT INTO `glpi_dropdown_contract_type` (`ID`, `name`) VALUES 
+(1, 'Pr&#234;t'),
+(2, 'Location'),
+(3, 'Leasing'),
+(4, 'Assurances'),
+(5, 'Maintenance Hardware'),
+(6, 'Maintenance Software'),
+(7, 'Prestation');
+
+
+
+CREATE TABLE `glpi_dropdown_domain` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_dropdown_enttype` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_dropdown_firmware` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_dropdown_hdd_type` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
+
+
+INSERT INTO `glpi_dropdown_hdd_type` (`ID`, `name`) VALUES 
+(1, 'IDE'),
+(2, 'SATA'),
+(3, 'SCSI');
+
+
+
+CREATE TABLE `glpi_dropdown_iface` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) default NULL,
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_dropdown_kbcategories` (
+  `ID` int(11) NOT NULL auto_increment,
+  `parentID` int(11) NOT NULL default '0',
+  `name` varchar(255) NOT NULL default '',
+  `completename` text NOT NULL,
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `parentID_2` (`parentID`,`name`),
+  KEY `parentID` (`parentID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_dropdown_locations` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `parentID` int(11) NOT NULL default '0',
+  `completename` text NOT NULL,
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `name` (`name`,`parentID`),
+  KEY `parentID` (`parentID`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
+
+
+INSERT INTO `glpi_dropdown_locations` (`ID`, `name`, `parentID`, `completename`) VALUES 
+(1, 'lala', 0, 'chk'),
+(2, 'ldala', 1, 'chacka');
+
+
+
+CREATE TABLE `glpi_dropdown_model` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) default NULL,
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_dropdown_netpoint` (
+  `ID` int(11) NOT NULL auto_increment,
+  `location` int(11) NOT NULL default '0',
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `location` (`location`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_dropdown_network` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_dropdown_os` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) default NULL,
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=21 ;
+
+
+INSERT INTO `glpi_dropdown_os` (`ID`, `name`) VALUES 
+(5, 'Windows 3.1'),
+(6, 'Debian Sarge'),
+(7, 'Debian Woody'),
+(11, 'Windows 98 se'),
+(10, 'Debian SID'),
+(14, 'Windows Server 2003'),
+(18, 'Windows 99');
+
+
+
+CREATE TABLE `glpi_dropdown_ram_type` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
+
+
+INSERT INTO `glpi_dropdown_ram_type` (`ID`, `name`) VALUES 
+(1, 'EDO'),
+(2, 'DDR'),
+(3, 'SDRAM'),
+(4, 'SDRAM-2');
+
+
+
+CREATE TABLE `glpi_dropdown_rubdocs` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) default NULL,
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_dropdown_state` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) default NULL,
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
+
+
+INSERT INTO `glpi_dropdown_state` (`ID`, `name`) VALUES 
+(1, 'asdf'),
+(2, 'asdfasdf');
+
+
+
+CREATE TABLE `glpi_dropdown_tracking_category` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) default NULL,
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_dropdown_vlan` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_enterprises` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(50) NOT NULL default '',
+  `type` int(11) NOT NULL default '0',
+  `address` text NOT NULL,
+  `website` varchar(100) NOT NULL default '',
+  `phonenumber` varchar(20) NOT NULL default '',
+  `comments` text NOT NULL,
+  `deleted` enum('Y','N') NOT NULL default 'N',
+  `fax` varchar(255) NOT NULL default '',
+  `email` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `deleted` (`deleted`),
+  KEY `type` (`type`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=18 ;
+
+
+INSERT INTO `glpi_enterprises` (`ID`, `name`, `type`, `address`, `website`, `phonenumber`, `comments`, `deleted`, `fax`, `email`) VALUES 
+(8, 'Microsoft', 0, 'Neverlandranche', 'www.google.de', '0001', 'No comment', '', '02', '02@01.00'),
+(12, 'Cherry', 0, '3 Tasten höher als ''n''   4 te links.', 'http://cherry_oder_so_aehnlich.com', 'N/A', 'N/A', '', 'N/A', 'N/A@N/A.N/A'),
+(16, 'GONICUS GmbH', 0, '', 'http://www.gonicus.de', '', 'fg', '', '', '');
+
+
+
+CREATE TABLE `glpi_event_log` (
+  `ID` int(11) NOT NULL auto_increment,
+  `item` int(11) NOT NULL default '0',
+  `itemtype` varchar(20) NOT NULL default '',
+  `date` datetime NOT NULL default '0000-00-00 00:00:00',
+  `service` varchar(20) default NULL,
+  `level` tinyint(4) NOT NULL default '0',
+  `message` text NOT NULL,
+  PRIMARY KEY  (`ID`),
+  KEY `comp` (`item`),
+  KEY `date` (`date`),
+  KEY `itemtype` (`itemtype`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=105 ;
+
+
+INSERT INTO `glpi_event_log` (`ID`, `item`, `itemtype`, `date`, `service`, `level`, `message`) VALUES 
+(90, 0, 'dropdowns', '2006-01-18 14:58:40', 'setup', 5, 'glpi added a value to a dropdown.'),
+(89, 0, 'dropdowns', '2006-01-18 14:58:31', 'setup', 5, 'glpi added a value to a dropdown.'),
+(88, 0, 'dropdowns', '2006-01-18 14:58:22', 'setup', 5, 'glpi added a value to a dropdown.'),
+(87, 0, 'dropdowns', '2006-01-18 14:58:07', 'setup', 5, 'glpi added a value to a dropdown.'),
+(86, 0, 'dropdowns', '2006-01-18 14:56:55', 'setup', 5, 'glpi added a value to a dropdown.'),
+(85, 0, 'dropdowns', '2006-01-18 14:56:40', 'setup', 5, 'glpi added a value to a dropdown.'),
+(84, 0, 'dropdowns', '2006-01-18 14:56:28', 'setup', 5, 'glpi added a value to a dropdown.'),
+(83, 0, 'dropdowns', '2006-01-18 14:56:12', 'setup', 5, 'glpi added a value to a dropdown.'),
+(82, 1, 'cartridges', '2006-01-18 14:55:35', 'inventory', 4, 'glpi added item HP Deskjet 80000 Green.'),
+(81, -1, 'system', '2006-01-18 14:49:46', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(80, -1, 'system', '2006-01-18 14:47:02', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(79, -1, 'system', '2006-01-17 12:23:40', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(78, 4, 'documents', '2006-01-17 09:51:47', 'document', 4, 'glpi associate device.'),
+(77, 4, 'documents', '2006-01-17 09:51:38', 'document', 4, 'glpi associate device.'),
+(76, 4, 'printers', '2006-01-17 09:41:51', 'inventory', 4, 'glpi updated item.'),
+(75, 0, 'dropdowns', '2006-01-17 09:41:28', 'setup', 5, 'glpi added a value to a dropdown.'),
+(74, 0, 'dropdowns', '2006-01-17 09:41:14', 'setup', 5, 'glpi added a value to a dropdown.'),
+(73, 0, 'dropdowns', '2006-01-17 09:41:03', 'setup', 5, 'glpi added a value to a dropdown.'),
+(72, 4, 'printers', '2006-01-17 08:56:20', 'inventory', 4, 'glpi added Name.'),
+(71, -1, 'system', '2006-01-17 08:48:04', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(31, -1, 'system', '2005-12-23 09:38:42', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(32, 26, 'computers', '2005-12-23 09:39:05', 'inventory', 4, 'glpi deleted item.'),
+(33, 0, 'Devices', '2005-12-23 14:53:31', 'inventory', 4, 'glpi added gzt.'),
+(34, -1, 'system', '2006-01-03 07:49:38', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(35, -1, 'system', '2006-01-03 08:16:04', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(36, 11, 'networking', '2006-01-03 08:30:08', 'inventory', 4, 'glpi added item name .'),
+(37, 2, 'Devices', '2006-01-03 12:07:52', 'inventory', 4, 'glpi updated item.'),
+(38, 0, 'Devices', '2006-01-03 13:12:53', 'inventory', 4, 'glpi added asdfasdf.'),
+(39, 0, 'Devices', '2006-01-03 13:27:36', 'inventory', 4, 'glpi added amd.'),
+(40, 0, 'Devices', '2006-01-03 13:33:00', 'inventory', 4, 'glpi added Duschaube.'),
+(41, 0, 'Devices', '2006-01-03 13:46:11', 'inventory', 4, 'glpi added name.'),
+(42, 0, 'Devices', '2006-01-03 14:03:42', 'inventory', 4, 'glpi added Hdd.'),
+(43, 0, 'Devices', '2006-01-03 14:42:23', 'inventory', 4, 'glpi added name.'),
+(44, 0, 'Devices', '2006-01-03 14:59:12', 'inventory', 4, 'glpi added Controllers.'),
+(45, 0, 'Devices', '2006-01-03 15:06:59', 'inventory', 4, 'glpi added gfxcard.'),
+(46, 0, 'Devices', '2006-01-03 15:18:33', 'inventory', 4, 'glpi added power.'),
+(47, 0, 'Devices', '2006-01-03 15:22:32', 'inventory', 4, 'glpi added pheripgherals.'),
+(48, -1, 'system', '2006-01-04 08:15:26', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(49, 2, 'Devices', '2006-01-04 08:16:05', 'inventory', 4, 'glpi updated item.'),
+(50, 26, 'computers', '2006-01-04 08:22:28', 'inventory', 4, 'glpi Unlinked a device from computer 26.'),
+(51, -1, 'system', '2006-01-04 11:23:06', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(52, 26, 'documents', '2006-01-04 11:23:47', 'document', 4, 'glpi associate device.'),
+(53, 2, 'documents', '2006-01-04 11:25:40', 'document', 4, 'glpi added item tester.'),
+(54, 3, 'documents', '2006-01-04 11:26:09', 'document', 4, 'glpi added item .'),
+(55, 4, 'documents', '2006-01-04 11:26:29', 'document', 4, 'glpi added item .'),
+(56, -1, 'system', '2006-01-04 15:22:51', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(57, 3, 'documents', '2006-01-04 15:41:50', 'document', 4, 'glpi updated item.'),
+(58, -1, 'system', '2006-01-05 10:17:59', 'login', 3, 'glpi  logged in from 10.3.64.43.'),
+(59, 26, 'documents', '2006-01-05 10:18:52', 'document', 4, 'glpi associate device.'),
+(60, -1, 'system', '2006-01-06 08:24:59', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(61, -1, 'system', '2006-01-06 09:21:47', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(62, -1, 'system', '2006-01-06 10:03:43', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(63, 0, 'dropdowns', '2006-01-06 10:33:17', 'setup', 5, 'glpi added a value to a dropdown.'),
+(64, 0, 'dropdowns', '2006-01-06 10:41:57', 'setup', 5, 'glpi added a value to a dropdown.'),
+(65, 0, 'dropdowns', '2006-01-06 10:42:12', 'setup', 5, 'glpi added a value to a dropdown.'),
+(66, 5, 'monitors', '2006-01-06 14:38:56', 'inventory', 4, 'glpi added asdfasdf.'),
+(67, 27, 'computers', '2006-01-06 14:39:39', 'inventory', 5, 'glpi connected item.'),
+(68, -1, 'system', '2006-01-16 12:08:10', 'login', 1, 'failed login: root'),
+(69, -1, 'system', '2006-01-16 12:08:23', 'login', 1, 'failed login: admin'),
+(70, -1, 'system', '2006-01-16 12:08:35', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(91, 0, 'dropdowns', '2006-01-18 14:58:57', 'setup', 5, 'glpi added a value to a dropdown.'),
+(92, 0, 'dropdowns', '2006-01-18 14:59:08', 'setup', 5, 'glpi added a value to a dropdown.'),
+(93, 0, 'dropdowns', '2006-01-18 14:59:21', 'setup', 5, 'glpi added a value to a dropdown.'),
+(94, 1, 'cartridges', '2006-01-18 15:00:07', 'inventory', 4, 'glpi updated item.'),
+(95, 1, 'cartridges', '2006-01-18 15:02:10', 'inventory', 4, 'glpi added a cartridge.'),
+(96, 1, 'cartridges', '2006-01-18 15:03:19', 'inventory', 4, 'glpi added a cartridge.'),
+(97, 1, 'cartridges', '2006-01-18 15:31:39', 'inventory', 5, 'glpi installed cartridge.'),
+(98, -1, 'system', '2006-01-19 08:33:27', 'login', 3, 'glpi logged in from 10.3.64.43.'),
+(99, 1, 'cartridges', '2006-01-19 08:34:32', 'inventory', 4, 'glpi added 17 cartridge.'),
+(100, 0, 'infocom', '2006-01-19 08:34:54', 'financial', 4, 'glpi added infocoms.'),
+(101, 1, 'cartridges', '2006-01-19 10:21:27', 'inventory', 4, 'glpi updated item.'),
+(102, 1, 'cartridges', '2006-01-19 10:21:33', 'inventory', 4, 'glpi added 1 cartridge.'),
+(103, 2, 'cartridges', '2006-01-19 10:22:45', 'inventory', 4, 'glpi added item Laserjet3.'),
+(104, 2, 'cartridges', '2006-01-19 10:23:16', 'inventory', 4, 'glpi updated item.');
+
+
+
+CREATE TABLE `glpi_followups` (
+  `ID` int(11) NOT NULL auto_increment,
+  `tracking` int(11) default NULL,
+  `date` datetime default NULL,
+  `author` int(11) NOT NULL default '0',
+  `contents` text,
+  PRIMARY KEY  (`ID`),
+  KEY `tracking` (`tracking`),
+  KEY `author` (`author`),
+  KEY `date` (`date`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_infocoms` (
+  `ID` int(11) NOT NULL auto_increment,
+  `FK_device` int(11) NOT NULL default '0',
+  `device_type` tinyint(4) NOT NULL default '0',
+  `buy_date` date NOT NULL default '0000-00-00',
+  `use_date` date NOT NULL default '0000-00-00',
+  `warranty_duration` tinyint(4) NOT NULL default '0',
+  `warranty_info` varchar(255) NOT NULL default '',
+  `FK_enterprise` int(11) default NULL,
+  `num_commande` varchar(50) NOT NULL default '',
+  `bon_livraison` varchar(50) NOT NULL default '',
+  `num_immo` varchar(50) NOT NULL default '',
+  `value` float NOT NULL default '0',
+  `warranty_value` float default NULL,
+  `amort_time` tinyint(4) NOT NULL default '0',
+  `amort_type` varchar(20) NOT NULL default '',
+  `amort_coeff` float NOT NULL default '0',
+  `comments` text NOT NULL,
+  `facture` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `FK_device` (`FK_device`,`device_type`),
+  KEY `FK_enterprise` (`FK_enterprise`),
+  KEY `buy_date` (`buy_date`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
+
+
+INSERT INTO `glpi_infocoms` (`ID`, `FK_device`, `device_type`, `buy_date`, `use_date`, `warranty_duration`, `warranty_info`, `FK_enterprise`, `num_commande`, `bon_livraison`, `num_immo`, `value`, `warranty_value`, `amort_time`, `amort_type`, `amort_coeff`, `comments`, `facture`) VALUES 
+(1, 10, 19, '0000-00-00', '0000-00-00', 0, '', NULL, '', '', '', 0, NULL, 0, '', 0, '', '');
+
+
+
+CREATE TABLE `glpi_inst_software` (
+  `ID` int(11) NOT NULL auto_increment,
+  `cID` int(11) NOT NULL default '0',
+  `license` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  KEY `cID` (`cID`),
+  KEY `sID` (`license`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_kbitems` (
+  `ID` int(11) NOT NULL auto_increment,
+  `categoryID` int(11) NOT NULL default '0',
+  `question` text NOT NULL,
+  `answer` text NOT NULL,
+  `faq` enum('yes','no') NOT NULL default 'no',
+  PRIMARY KEY  (`ID`),
+  KEY `categoryID` (`categoryID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_licenses` (
+  `ID` int(15) NOT NULL auto_increment,
+  `sID` int(15) NOT NULL default '0',
+  `serial` varchar(255) NOT NULL default '',
+  `expire` date default NULL,
+  `oem` enum('N','Y') NOT NULL default 'N',
+  `oem_computer` int(11) NOT NULL default '0',
+  `buy` enum('Y','N') NOT NULL default 'Y',
+  PRIMARY KEY  (`ID`),
+  KEY `sID` (`sID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_links` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_links_device` (
+  `ID` int(11) NOT NULL auto_increment,
+  `FK_links` int(11) NOT NULL default '0',
+  `device_type` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `device_type_2` (`device_type`,`FK_links`),
+  KEY `device_type` (`device_type`),
+  KEY `FK_links` (`FK_links`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_monitors` (
+  `ID` int(10) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `date_mod` datetime NOT NULL default '0000-00-00 00:00:00',
+  `contact` varchar(255) NOT NULL default '',
+  `contact_num` varchar(255) NOT NULL default '',
+  `tech_num` int(11) NOT NULL default '0',
+  `comments` text NOT NULL,
+  `serial` varchar(255) NOT NULL default '',
+  `otherserial` varchar(255) NOT NULL default '',
+  `size` int(3) NOT NULL default '0',
+  `flags_micro` tinyint(4) NOT NULL default '0',
+  `flags_speaker` tinyint(4) NOT NULL default '0',
+  `flags_subd` tinyint(4) NOT NULL default '0',
+  `flags_bnc` tinyint(4) NOT NULL default '0',
+  `location` int(11) default NULL,
+  `type` int(11) default NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `is_global` enum('0','1') NOT NULL default '0',
+  `deleted` enum('Y','N') NOT NULL default 'N',
+  `is_template` enum('0','1') NOT NULL default '0',
+  `tplname` varchar(255) default NULL,
+  PRIMARY KEY  (`ID`),
+  KEY `ID` (`ID`),
+  KEY `type` (`type`),
+  KEY `location` (`location`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
+  KEY `deleted` (`deleted`),
+  KEY `is_template` (`is_template`),
+  KEY `tech_num` (`tech_num`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
+
+
+INSERT INTO `glpi_monitors` (`ID`, `name`, `date_mod`, `contact`, `contact_num`, `tech_num`, `comments`, `serial`, `otherserial`, `size`, `flags_micro`, `flags_speaker`, `flags_subd`, `flags_bnc`, `location`, `type`, `FK_glpi_enterprise`, `is_global`, `deleted`, `is_template`, `tplname`) VALUES 
+(2, 'asdfasdf', '0000-00-00 00:00:00', '', '', 0, '', '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', '', '');
+
+
+
+CREATE TABLE `glpi_networking` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(30) NOT NULL default '',
+  `ram` varchar(10) NOT NULL default '',
+  `serial` varchar(50) NOT NULL default '',
+  `otherserial` varchar(50) NOT NULL default '',
+  `contact` varchar(30) NOT NULL default '',
+  `contact_num` varchar(30) NOT NULL default '',
+  `tech_num` int(11) NOT NULL default '0',
+  `date_mod` datetime NOT NULL default '0000-00-00 00:00:00',
+  `comments` text NOT NULL,
+  `location` int(11) default NULL,
+  `domain` int(11) NOT NULL default '0',
+  `network` int(11) NOT NULL default '0',
+  `type` int(11) default NULL,
+  `firmware` int(11) default NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `deleted` enum('Y','N') NOT NULL default 'N',
+  `is_template` enum('0','1') NOT NULL default '0',
+  `tplname` varchar(255) default NULL,
+  `ifmac` varchar(30) NOT NULL default '',
+  `ifaddr` varchar(30) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `location` (`location`),
+  KEY `type` (`type`),
+  KEY `firmware` (`firmware`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
+  KEY `deleted` (`deleted`),
+  KEY `is_template` (`is_template`),
+  KEY `tech_num` (`tech_num`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=12 ;
+
+
+INSERT INTO `glpi_networking` (`ID`, `name`, `ram`, `serial`, `otherserial`, `contact`, `contact_num`, `tech_num`, `date_mod`, `comments`, `location`, `domain`, `network`, `type`, `firmware`, `FK_glpi_enterprise`, `deleted`, `is_template`, `tplname`, `ifmac`, `ifaddr`) VALUES 
+(10, '', '', '', '', '', '', 0, '0000-00-00 00:00:00', '', NULL, 0, 0, NULL, NULL, 0, 'N', '1', 'Blank Template', '', ''),
+(11, '', '', '', '', '', '', 0, '2006-01-03 08:30:08', '', 0, 0, 0, 0, 0, 0, 'N', '0', NULL, '', '');
+
+
+
+CREATE TABLE `glpi_networking_ports` (
+  `ID` int(11) NOT NULL auto_increment,
+  `on_device` int(11) NOT NULL default '0',
+  `device_type` tinyint(4) NOT NULL default '0',
+  `logical_number` int(11) NOT NULL default '0',
+  `name` char(30) NOT NULL default '',
+  `ifaddr` char(30) NOT NULL default '',
+  `ifmac` char(30) NOT NULL default '',
+  `iface` int(11) default NULL,
+  `netpoint` int(11) default NULL,
+  PRIMARY KEY  (`ID`),
+  KEY `on_device` (`on_device`,`device_type`),
+  KEY `netpoint` (`netpoint`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_networking_vlan` (
+  `ID` int(11) NOT NULL auto_increment,
+  `FK_port` int(11) NOT NULL default '0',
+  `FK_vlan` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `FK_port_2` (`FK_port`,`FK_vlan`),
+  KEY `FK_port` (`FK_port`),
+  KEY `FK_vlan` (`FK_vlan`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_networking_wire` (
+  `ID` int(11) NOT NULL auto_increment,
+  `end1` int(11) NOT NULL default '0',
+  `end2` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `end1_1` (`end1`,`end2`),
+  KEY `end1` (`end1`),
+  KEY `end2` (`end2`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_peripherals` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `date_mod` datetime NOT NULL default '0000-00-00 00:00:00',
+  `contact` varchar(255) NOT NULL default '',
+  `contact_num` varchar(255) NOT NULL default '',
+  `tech_num` int(11) NOT NULL default '0',
+  `comments` text NOT NULL,
+  `serial` varchar(255) NOT NULL default '',
+  `otherserial` varchar(255) NOT NULL default '',
+  `location` int(11) NOT NULL default '0',
+  `type` int(11) NOT NULL default '0',
+  `brand` varchar(255) NOT NULL default '',
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `is_global` enum('0','1') NOT NULL default '0',
+  `deleted` enum('Y','N') NOT NULL default 'N',
+  `is_template` enum('0','1') NOT NULL default '0',
+  `tplname` varchar(255) default NULL,
+  PRIMARY KEY  (`ID`),
+  KEY `type` (`type`),
+  KEY `location` (`location`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
+  KEY `deleted` (`deleted`),
+  KEY `is_template` (`is_template`),
+  KEY `tech_num` (`tech_num`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
+
+
+INSERT INTO `glpi_peripherals` (`ID`, `name`, `date_mod`, `contact`, `contact_num`, `tech_num`, `comments`, `serial`, `otherserial`, `location`, `type`, `brand`, `FK_glpi_enterprise`, `is_global`, `deleted`, `is_template`, `tplname`) VALUES 
+(1, '', '0000-00-00 00:00:00', '', '', 0, '', '', '', 0, 0, '', 0, '0', 'N', '1', 'Blank Template'),
+(2, 'gf5200', '2005-12-13 09:34:32', 'Herr Herr', '0231', 4, 'f', '45875486468', '4554', 0, 0, 'GC', 1, '0', 'N', '0', NULL);
+
+
+
+CREATE TABLE `glpi_printers` (
+  `ID` int(10) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `date_mod` datetime NOT NULL default '0000-00-00 00:00:00',
+  `contact` varchar(255) NOT NULL default '',
+  `contact_num` varchar(255) NOT NULL default '',
+  `tech_num` int(11) NOT NULL default '0',
+  `serial` varchar(255) NOT NULL default '',
+  `otherserial` varchar(255) NOT NULL default '',
+  `flags_serial` tinyint(4) NOT NULL default '0',
+  `flags_par` tinyint(4) NOT NULL default '0',
+  `flags_usb` tinyint(4) NOT NULL default '0',
+  `comments` text NOT NULL,
+  `ramSize` varchar(6) NOT NULL default '',
+  `location` int(11) default NULL,
+  `domain` int(11) NOT NULL default '0',
+  `network` int(11) NOT NULL default '0',
+  `type` int(11) default NULL,
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `deleted` enum('Y','N') NOT NULL default 'N',
+  `is_template` enum('0','1') NOT NULL default '0',
+  `tplname` varchar(255) default NULL,
+  `initial_pages` varchar(30) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  KEY `id` (`ID`),
+  KEY `location` (`location`),
+  KEY `type` (`type`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
+  KEY `deleted` (`deleted`),
+  KEY `is_template` (`is_template`),
+  KEY `tech_num` (`tech_num`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;
+
+
+INSERT INTO `glpi_printers` (`ID`, `name`, `date_mod`, `contact`, `contact_num`, `tech_num`, `serial`, `otherserial`, `flags_serial`, `flags_par`, `flags_usb`, `comments`, `ramSize`, `location`, `domain`, `network`, `type`, `FK_glpi_enterprise`, `deleted`, `is_template`, `tplname`, `initial_pages`) VALUES 
+(1, 'cn=demohost,ou=printers,ou=systems,dc=gonicus,dc=de', '2006-02-01 12:48:33', '', '', 0, '', '', 0, 0, 0, '', '0', 0, 0, 0, 2, 8, 'N', '0', NULL, '0'),
+(2, 'cn=drucker4,ou=printers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '2006-09-19 09:49:33', '', '', 0, '', '', 0, 0, 0, '', '0', 0, 0, 0, 3, 12, 'N', '0', NULL, '0'),
+(3, 'cn=drucker6,ou=printers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '2006-11-29 14:53:41', '', '', 0, '', '', 0, 0, 0, '', '0', 0, 0, 0, 3, 12, 'N', '0', NULL, '0'),
+(4, 'cn=Fettsäuren,ou=printers,ou=systems,ou=keks,ou=DasTestDep,o=Landeshauptstadt München,c=de', '2006-09-28 09:17:45', '', '', 0, '', '', 1, 1, 1, '', '0', 0, 0, 0, 3, 12, 'N', '0', NULL, '0'),
+(5, 'cn=Brennwert,ou=printers,ou=systems,ou=keks,ou=DasTestDep,o=Landeshauptstadt München,c=de', '2006-09-29 11:02:10', '', '', 0, '', '', 1, 1, 1, 'dfsaaaaaaaaaaaaaaaaa', '0', 0, 0, 0, 3, 12, 'N', '0', NULL, '0'),
+(7, 'cn=atz23,ou=printers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '2006-11-29 10:19:48', '', '', 19, '', '', 1, 1, 1, 'ursssszzzzzzzzzzzzzzzzzzzzzzzzzzzzzz', '0', 0, 0, 0, 3, 12, 'N', '0', NULL, '0'),
+(8, 'cn=drucker2,ou=printers,ou=systems,ou=DasTestDep,o=Landeshauptstadt München,c=de', '2006-11-29 10:25:26', '', '', 0, '', '', 1, 1, 1, 'test', '0', 0, 0, 0, 3, 12, 'N', '0', NULL, '0');
+
+
+
+CREATE TABLE `glpi_repair_item` (
+  `ID` int(11) NOT NULL auto_increment,
+  `device_type` tinyint(4) NOT NULL default '0',
+  `id_device` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  KEY `device_type` (`device_type`),
+  KEY `device_type_2` (`device_type`,`id_device`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_reservation_item` (
+  `ID` int(11) NOT NULL auto_increment,
+  `device_type` tinyint(4) NOT NULL default '0',
+  `id_device` int(11) NOT NULL default '0',
+  `comments` text NOT NULL,
+  PRIMARY KEY  (`ID`),
+  KEY `device_type` (`device_type`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
+
+
+INSERT INTO `glpi_reservation_item` (`ID`, `device_type`, `id_device`, `comments`) VALUES 
+(1, 1, 20, '');
+
+
+
+CREATE TABLE `glpi_reservation_resa` (
+  `ID` bigint(20) NOT NULL auto_increment,
+  `id_item` int(11) NOT NULL default '0',
+  `begin` datetime NOT NULL default '0000-00-00 00:00:00',
+  `end` datetime NOT NULL default '0000-00-00 00:00:00',
+  `id_user` int(11) NOT NULL default '0',
+  `comment` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  KEY `id_item` (`id_item`),
+  KEY `id_user` (`id_user`),
+  KEY `begin` (`begin`),
+  KEY `end` (`end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_software` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(200) NOT NULL default '',
+  `version` varchar(20) NOT NULL default '',
+  `comments` text,
+  `location` int(11) default NULL,
+  `tech_num` int(11) NOT NULL default '0',
+  `platform` int(11) default NULL,
+  `is_update` enum('N','Y') NOT NULL default 'N',
+  `update_software` int(11) NOT NULL default '-1',
+  `FK_glpi_enterprise` int(11) NOT NULL default '0',
+  `deleted` enum('Y','N') NOT NULL default 'N',
+  `is_template` enum('0','1') NOT NULL default '0',
+  `tplname` varchar(255) default NULL,
+  `date_mod` datetime default NULL,
+  PRIMARY KEY  (`ID`),
+  KEY `platform` (`platform`),
+  KEY `location` (`location`),
+  KEY `FK_glpi_enterprise` (`FK_glpi_enterprise`),
+  KEY `deleted` (`deleted`),
+  KEY `is_template` (`is_template`),
+  KEY `date_mod` (`date_mod`),
+  KEY `tech_num` (`tech_num`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
+
+
+INSERT INTO `glpi_software` (`ID`, `name`, `version`, `comments`, `location`, `tech_num`, `platform`, `is_update`, `update_software`, `FK_glpi_enterprise`, `deleted`, `is_template`, `tplname`, `date_mod`) VALUES 
+(6, '', '', NULL, NULL, 0, NULL, 'N', -1, 0, 'N', '1', 'Blank Template', NULL);
+
+
+
+CREATE TABLE `glpi_state_item` (
+  `ID` int(11) NOT NULL auto_increment,
+  `device_type` tinyint(4) NOT NULL default '0',
+  `id_device` int(11) NOT NULL default '0',
+  `state` int(11) default '1',
+  `is_template` enum('0','1') NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  KEY `device_type` (`device_type`),
+  KEY `device_type_2` (`device_type`,`id_device`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_tracking` (
+  `ID` int(11) NOT NULL auto_increment,
+  `date` datetime default NULL,
+  `closedate` datetime NOT NULL default '0000-00-00 00:00:00',
+  `status` enum('new','old') default NULL,
+  `author` int(11) NOT NULL default '0',
+  `assign` int(11) NOT NULL default '0',
+  `assign_type` tinyint(4) NOT NULL default '0',
+  `device_type` int(11) NOT NULL default '1',
+  `computer` int(11) default NULL,
+  `contents` text,
+  `priority` tinyint(4) NOT NULL default '1',
+  `is_group` enum('no','yes') NOT NULL default 'no',
+  `uemail` varchar(100) default NULL,
+  `emailupdates` varchar(4) default NULL,
+  `realtime` float NOT NULL default '0',
+  `category` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`ID`),
+  KEY `computer` (`computer`),
+  KEY `author` (`author`),
+  KEY `assign` (`assign`),
+  KEY `date` (`date`),
+  KEY `closedate` (`closedate`),
+  KEY `status` (`status`),
+  KEY `category` (`category`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_tracking_planning` (
+  `ID` bigint(20) NOT NULL auto_increment,
+  `id_tracking` int(11) NOT NULL default '0',
+  `id_assign` int(11) NOT NULL default '0',
+  `begin` datetime NOT NULL default '0000-00-00 00:00:00',
+  `end` datetime NOT NULL default '0000-00-00 00:00:00',
+  PRIMARY KEY  (`ID`),
+  KEY `id_tracking` (`id_tracking`),
+  KEY `begin` (`begin`),
+  KEY `end` (`end`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_type_computers` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=30 ;
+
+
+INSERT INTO `glpi_type_computers` (`ID`, `name`) VALUES 
+(26, 'SuperDupfer'),
+(27, 'Server'),
+(18, 'System tester'),
+(19, 'Windows workstation'),
+(21, 'Network device'),
+(28, 'Microcontroller');
+
+
+
+CREATE TABLE `glpi_type_docs` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `ext` varchar(10) NOT NULL default '',
+  `icon` varchar(255) NOT NULL default '',
+  `mime` varchar(100) NOT NULL default '',
+  `upload` enum('Y','N') NOT NULL default 'Y',
+  `date_mod` datetime default NULL,
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `extension` (`ext`),
+  KEY `upload` (`upload`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=54 ;
+
+
+INSERT INTO `glpi_type_docs` (`ID`, `name`, `ext`, `icon`, `mime`, `upload`, `date_mod`) VALUES 
+(1, 'JPEG', 'jpg', 'jpg-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(2, 'PNG', 'png', 'png-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(3, 'GIF', 'gif', 'gif-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(4, 'BMP', 'bmp', 'bmp-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(5, 'Photoshop', 'psd', 'psd-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(6, 'TIFF', 'tif', 'tif-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(7, 'AIFF', 'aiff', 'aiff-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(8, 'Windows Media', 'asf', 'asf-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(9, 'Windows Media', 'avi', 'avi-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(44, 'C source', 'c', '', '', 'Y', '2004-12-13 19:47:22'),
+(27, 'RealAudio', 'rm', 'rm-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(16, 'Midi', 'mid', 'mid-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(17, 'QuickTime', 'mov', 'mov-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(18, 'MP3', 'mp3', 'mp3-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(19, 'MPEG', 'mpg', 'mpg-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(20, 'Ogg Vorbis', 'ogg', 'ogg-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(24, 'QuickTime', 'qt', 'qt-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(10, 'BZip', 'bz2', 'bz2-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(25, 'RealAudio', 'ra', 'ra-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(26, 'RealAudio', 'ram', 'ram-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(11, 'Word', 'doc', 'doc-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(12, 'DjVu', 'djvu', '', '', 'Y', '2004-12-13 19:47:21'),
+(42, 'MNG', 'mng', '', '', 'Y', '2004-12-13 19:47:22'),
+(13, 'PostScript', 'eps', 'ps-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(14, 'GZ', 'gz', 'gz-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(37, 'WAV', 'wav', 'wav-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(15, 'HTML', 'html', 'html-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(34, 'Flash', 'swf', '', '', 'Y', '2004-12-13 19:47:22'),
+(21, 'PDF', 'pdf', 'pdf-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(22, 'PowerPoint', 'ppt', 'ppt-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(23, 'PostScript', 'ps', 'ps-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(40, 'Windows Media', 'wmv', '', '', 'Y', '2004-12-13 19:47:22'),
+(28, 'RTF', 'rtf', 'rtf-dist.png', '', 'Y', '2004-12-13 19:47:21'),
+(29, 'StarOffice', 'sdd', 'sdd-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(30, 'StarOffice', 'sdw', 'sdw-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(31, 'Stuffit', 'sit', 'sit-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(43, 'Adobe Illustrator', 'ai', 'ai-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(32, 'OpenOffice Impress', 'sxi', 'sxi-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(33, 'OpenOffice', 'sxw', 'sxw-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(46, 'DVI', 'dvi', 'dvi-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(35, 'TGZ', 'tgz', 'tgz-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(36, 'texte', 'txt', 'txt-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(49, 'RedHat/Mandrake/SuSE', 'rpm', 'rpm-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(38, 'Excel', 'xls', 'xls-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(39, 'XML', 'xml', 'xml-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(41, 'Zip', 'zip', 'zip-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(45, 'Debian', 'deb', 'deb-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(47, 'C header', 'h', '', '', 'Y', '2004-12-13 19:47:22'),
+(48, 'Pascal', 'pas', '', '', 'Y', '2004-12-13 19:47:22'),
+(50, 'OpenOffice Calc', 'sxc', 'sxc-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(51, 'LaTeX', 'tex', 'tex-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(52, 'GIMP multi-layer', 'xcf', 'xcf-dist.png', '', 'Y', '2004-12-13 19:47:22'),
+(53, 'JPEG', 'jpeg', 'jpg-dist.png', '', 'Y', '2005-03-07 22:23:17');
+
+
+
+CREATE TABLE `glpi_type_monitors` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) default NULL,
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
+
+
+INSERT INTO `glpi_type_monitors` (`ID`, `name`) VALUES 
+(1, 'testoe');
+
+
+
+CREATE TABLE `glpi_type_networking` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) default NULL,
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_type_peripherals` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) default NULL,
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+
+
+
+
+CREATE TABLE `glpi_type_printers` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(255) default NULL,
+  PRIMARY KEY  (`ID`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=15 ;
+
+
+INSERT INTO `glpi_type_printers` (`ID`, `name`) VALUES 
+(2, 'Tintenstrahl'),
+(3, 'Farb Laser'),
+(5, 'Not known'),
+(6, 'Nadeldrucker Farbe'),
+(10, 'Nadeldrucker'),
+(11, 'Laser'),
+(12, 'Photodrucker A3'),
+(14, 'Tintentrahl');
+
+
+
+CREATE TABLE `glpi_users` (
+  `ID` int(11) NOT NULL auto_increment,
+  `name` varchar(80) NOT NULL default '',
+  `password` varchar(80) NOT NULL default '',
+  `password_md5` varchar(80) NOT NULL default '',
+  `email` varchar(80) NOT NULL default '',
+  `phone` varchar(100) default NULL,
+  `type` enum('normal','admin','post-only','super-admin') NOT NULL default 'normal',
+  `realname` varchar(255) NOT NULL default '',
+  `can_assign_job` enum('yes','no') NOT NULL default 'no',
+  `location` int(11) default NULL,
+  `tracking_order` enum('yes','no') NOT NULL default 'no',
+  `language` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`ID`),
+  UNIQUE KEY `name` (`name`),
+  KEY `type` (`type`),
+  KEY `name_2` (`name`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=22 ;
+
+
+INSERT INTO `glpi_users` (`ID`, `name`, `password`, `password_md5`, `email`, `phone`, `type`, `realname`, `can_assign_job`, `location`, `tracking_order`, `language`) VALUES 
+(1, 'cn=GOsa main administrator admin,ou=people,dc=gonicus,dc=de', '', '', 'asdfasdf@asdfasdf.de', '333333333', 'normal', '', 'no', NULL, 'no', ''),
+(2, 'cn=Getester Hainz,ou=people,dc=gonicus,dc=de', '', '', 'gtest@blafasel.org', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(3, 'cn=adff dendnen,ou=people,dc=gonicus,dc=de', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(4, 'cn=tttttttttttt testttttttttttttttttt,ou=people,ou=Diesisteinelangeabteilung,ou=', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(5, 'cn=asdff33 asdf333,ou=people,ou=tester,ou=Vertrieb,dc=gonicus,dc=de', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(6, 'cn=Florian Schiessl,ou=people,o=Landeshauptstadt München,c=de', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(7, 'cn=blub blab,ou=people,o=Landeshauptstadt München,c=de', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(8, 'cn=Florian test,ou=people,o=Landeshauptstadt München,c=de', '', '', '', '233-92742', 'normal', '', 'no', NULL, 'no', ''),
+(9, 'uid=pppppp,ou=people,o=Landeshauptstadt München,c=de', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(10, 'cn=acltest2 acltest2,ou=people,ou=checkTheFAIStuff,ou=DasTestDep,o=Landeshauptst', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(11, 'cn=acltest acltest,ou=people,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', 'acltest@gonicus.de', '123123', 'normal', '', 'no', NULL, 'no', ''),
+(12, 'cn=Max Mustermann,ou=people,ou=PrinterLosesMember,ou=DasTestDep,o=Landeshauptsta', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(13, 'cn=Susanne Neuhaus,ou=people,ou=PrinterLosesMember,ou=DasTestDep,o=Landeshauptst', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(14, '', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(15, 'cn=Florian Meier,ou=people,ou=PrinterLosesMember,ou=DasTestDep,o=Landeshauptstad', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(16, 'cn=abtielung abtielung,ou=people,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '7890', 'normal', '', 'no', NULL, 'no', ''),
+(17, 'cn=Franz Keller,ou=people,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', 'ableis@gonicus.de', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(18, 'cn=Jan Wenzel,ou=people,o=Landeshauptstadt München,c=de', '', '', '', NULL, 'normal', '', 'no', NULL, 'no', ''),
+(19, 'cn=acl2 acl2,ou=people,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', '', '22222222222222', 'normal', '', 'no', NULL, 'no', ''),
+(20, 'cn=a11 a11,ou=people,ou=DasTestDep,o=Landeshauptstadt München,c=de', '', '', 'a11@gonicus.de', '311112', 'normal', '', 'no', NULL, 'no', ''),
+(21, 'cn=Admin Admin,ou=people,o=Landeshauptstadt München,c=de', '', '', 'ableis@gonicus.de', '1234', 'normal', '', 'no', NULL, 'no', '');
+
diff --git a/gosa-core/contrib/mysql/gofax/gofax.sql b/gosa-core/contrib/mysql/gofax/gofax.sql
new file mode 100644 (file)
index 0000000..744514a
--- /dev/null
@@ -0,0 +1,24 @@
+create database gofax;
+use gofax;
+
+CREATE TABLE faxlog (
+       id                    VARCHAR(20) NOT NULL,
+       status                INTEGER NOT NULL,
+       status_message        TEXT,
+       uid                   VARCHAR(20) NOT NULL,
+       queuing_time          TIMESTAMP NOT NULL,
+       sender_msn            VARCHAR(100),
+       sender_id             VARCHAR(100),
+       receiver_msn          VARCHAR(100),
+       receiver_id           VARCHAR(100),
+       transfer_time         INTEGER,
+       pages                 INTEGER
+       );
+
+CREATE TABLE faxdata (
+       id                    VARCHAR(20) PRIMARY KEY,
+       fax_data              BLOB
+       );
+
+GRANT INSERT,SELECT ON gofax.faxlog TO logger@localhost IDENTIFIED BY 'somemysqlpass';
+GRANT INSERT,SELECT,DELETE ON gofax.faxdata TO logger@localhost IDENTIFIED BY 'somemysqlpass';
diff --git a/gosa-core/contrib/mysql/gofon/gofon.sql b/gosa-core/contrib/mysql/gofon/gofon.sql
new file mode 100644 (file)
index 0000000..584bcc9
--- /dev/null
@@ -0,0 +1,24 @@
+create database gophone;
+use gophone;
+
+create table cdr (
+  calldate datetime NOT NULL default '0000-00-00 00:00:00',
+  clid varchar(80) NOT NULL default '',
+  src varchar(80) NOT NULL default '',
+  dst varchar(80) NOT NULL default '',
+  dcontext varchar(80) NOT NULL default '',
+  channel varchar(80) NOT NULL default '',
+  dstchannel varchar(80) NOT NULL default '',
+  lastapp varchar(80) NOT NULL default '',
+  lastdata varchar(80) NOT NULL default '',
+  duration integer NOT NULL default '0',
+  billsec integer NOT NULL default '0',
+  disposition varchar(45) NOT NULL default '',
+  amaflags integer NOT NULL default '0',
+  accountcode varchar(20) NOT NULL default '',
+  uniqueid varchar(32) NOT NULL default '',
+  userfield varchar(255) NOT NULL default ''
+);
+
+GRANT INSERT,SELECT ON gophone.cdr TO asterisk@localhost IDENTIFIED BY 'somemysqlpass';
+
diff --git a/gosa-core/contrib/mysql/golog/golog.sql b/gosa-core/contrib/mysql/golog/golog.sql
new file mode 100644 (file)
index 0000000..0461fdc
--- /dev/null
@@ -0,0 +1,14 @@
+
+create database golog;
+use golog;
+
+create table golog (
+       time_stamp DATETIME,
+       host VARCHAR(50),
+       message VARCHAR(255),
+       log_level VARCHAR(15),
+       matched_dn VARCHAR(255),
+       matched_ts DATETIME
+       );
+
+GRANT INSERT,SELECT,DELETE ON golog.golog TO gomon@localhost IDENTIFIED BY 'somemysqlpass';
diff --git a/gosa-core/contrib/mysql/logging/logging.sql b/gosa-core/contrib/mysql/logging/logging.sql
new file mode 100644 (file)
index 0000000..e61472d
--- /dev/null
@@ -0,0 +1,17 @@
+create database gosa_log;
+use gosa_log;
+
+CREATE TABLE `gosa_log` (
+  `id` int(10) unsigned NOT NULL auto_increment,
+  `timestamp` int(10) NOT NULL,
+  `user` longtext NOT NULL,
+  `action` varchar(255) NOT NULL,
+  `objecttype` varchar(255) NOT NULL,
+  `object` varchar(255) NOT NULL,
+  `changes` blob NOT NULL,
+  `result` varchar(255) NOT NULL,
+  PRIMARY KEY  (`id`)
+  KEY `timestamp` (`timestamp`)
+  KEY `action` (`action`),
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
diff --git a/gosa-core/contrib/openldap/apple.schema.README b/gosa-core/contrib/openldap/apple.schema.README
new file mode 100644 (file)
index 0000000..e0e3f9a
--- /dev/null
@@ -0,0 +1,50 @@
+
+Heya,
+
+as we don't want to run into licensing issues the apple.schema is not included
+here. In case you want to manage your apple users' homedirectories with GOsa
+please copy the apple.schema file from your MacOSX installation into the
+schema-directory of your openldap installation and include it in the slapd-
+configuration. Usually you'll have to change a few objectclasses as some
+attribute-types are missing.
+
+For example to use the apple.schema from osx 10.4 you'll have to
+- remove the objectclass authAuthorityObject
+- remove the objectclass apple-acl
+- remove the following attributes from all ObjectClasses:
+    - acctFlags
+    - pwdLastSet
+    - logonTime
+    - logoffTime
+    - kickoffTime
+    - homeDrive
+    - scriptPath
+    - profilePath
+    - userWorkstations
+    - smbHome
+    - rid
+    - primaryGroupID
+- uncomment the apple-user-homeDirectory attribute
+- add the apple-user-homeDirectory attribute to the apple-user objectclass
+
+YMMV depending on the version of the apple.schema. As far as I can remember the
+apple.schema from 10.2 does not include all neccessary attributes and object-
+classes, so you probably want to use a more recent one.
+
+
+As I actually don't have the time to provide a complete howto I've googled for
+a howto - probably http://www.spack.org/wiki/AppleOsxIntegrationWithOpenLdap
+will give you some hints how to setup your apple.
+
+The netatalk plugin was developed by Gina Haeussge <osd@foosel.net> and Bernd
+Zeimetz <osd@bzed.de> for use at the Darmstadt University of Technology,
+Department of Architecture.
+
+In case you have any questions or find any bugs feel free to contact me at
+<osd@bzed.de>.
+
+
+Best regards,
+
+
+Bernd Zeimetz
diff --git a/gosa-core/contrib/openldap/dhcp.schema b/gosa-core/contrib/openldap/dhcp.schema
new file mode 100644 (file)
index 0000000..a0a68e9
--- /dev/null
@@ -0,0 +1,462 @@
+attributetype ( 2.16.840.1.113719.1.203.4.1 
+       NAME 'dhcpPrimaryDN' 
+       EQUALITY distinguishedNameMatch
+       DESC 'The DN of the dhcpServer which is the primary server for the configuration.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.2 
+       NAME 'dhcpSecondaryDN' 
+       EQUALITY distinguishedNameMatch
+       DESC 'The DN of dhcpServer(s) which provide backup service for the configuration.'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.3 
+       NAME 'dhcpStatements' 
+       EQUALITY caseIgnoreIA5Match
+       DESC 'Flexible storage for specific data depending on what object this exists in. Like conditional statements, server parameters, etc. This allows the standard to evolve without needing to adjust the schema.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.4 
+       NAME 'dhcpRange' 
+       EQUALITY caseIgnoreIA5Match
+       DESC 'The starting & ending IP Addresses in the range (inclusive), separated by a hyphen; if the range only contains one address, then just the address can be specified with no hyphen.  Each range is defined as a separate value.'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.5 
+       NAME 'dhcpPermitList' 
+       EQUALITY caseIgnoreIA5Match
+       DESC 'This attribute contains the permit lists associated with a pool. Each permit list is defined as a separate value.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.6 
+       NAME 'dhcpNetMask' 
+       EQUALITY integerMatch
+       DESC 'The subnet mask length for the subnet.  The mask can be easily computed from this length.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.7 
+       NAME 'dhcpOption' 
+       EQUALITY caseIgnoreIA5Match
+       DESC 'Encoded option values to be sent to clients.  Each value represents a single option and contains (OptionTag, Length, OptionValue) encoded in the format used by DHCP.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.8 
+       NAME 'dhcpClassData' 
+       EQUALITY caseIgnoreIA5Match
+       DESC 'Encoded text string or list of bytes expressed in hexadecimal, separated by colons.  Clients match subclasses based on matching the class data with the results of match or spawn with statements in the class name declarations.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.9 
+       NAME 'dhcpOptionsDN' 
+       EQUALITY distinguishedNameMatch
+       DESC 'The distinguished name(s) of the dhcpOption objects containing the configuration options provided by the server.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.10 
+       NAME 'dhcpHostDN' 
+       EQUALITY distinguishedNameMatch
+       DESC 'the distinguished name(s) of the dhcpHost objects.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) 
+
+attributetype ( 2.16.840.1.113719.1.203.4.11 
+       NAME 'dhcpPoolDN' 
+       EQUALITY distinguishedNameMatch
+       DESC 'The distinguished name(s) of pools.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.12 
+       NAME 'dhcpGroupDN' 
+       EQUALITY distinguishedNameMatch
+       DESC 'The distinguished name(s)   of the groups.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.13 
+       NAME 'dhcpSubnetDN' 
+       EQUALITY distinguishedNameMatch
+       DESC 'The distinguished name(s) of the subnets.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.14 
+       NAME 'dhcpLeaseDN' 
+       EQUALITY distinguishedNameMatch
+       DESC 'The distinguished name of a client address.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE)
+
+attributetype ( 2.16.840.1.113719.1.203.4.15 
+       NAME 'dhcpLeasesDN' 
+       DESC 'The distinguished name(s) client addresses.' 
+       EQUALITY distinguishedNameMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.16 
+       NAME 'dhcpClassesDN' 
+       EQUALITY distinguishedNameMatch
+       DESC 'The distinguished name(s) of a class(es) in a subclass.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.17 
+       NAME 'dhcpSubclassesDN' 
+       EQUALITY distinguishedNameMatch
+       DESC 'The distinguished name(s) of subclass(es).' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.18 
+       NAME 'dhcpSharedNetworkDN' 
+       EQUALITY distinguishedNameMatch
+       DESC 'The distinguished name(s) of sharedNetworks.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.19 
+       NAME 'dhcpServiceDN' 
+       EQUALITY distinguishedNameMatch
+       DESC 'The DN of dhcpService object(s)which contain the configuration information. Each dhcpServer object has this attribute identifying the DHCP configuration(s) that the server is associated with.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.20 
+       NAME 'dhcpVersion'
+       DESC 'The version attribute of this object.'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.21 
+       NAME 'dhcpImplementation' 
+       EQUALITY caseIgnoreIA5Match
+       DESC 'Description of the DHCP Server implementation e.g. DHCP Servers vendor.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.22 
+       NAME 'dhcpAddressState' 
+       EQUALITY caseIgnoreIA5Match
+       DESC 'This stores information about the current binding-status of an address.  For dynamic addresses managed by DHCP, the values should be restricted to the following: "FREE", "ACTIVE", "EXPIRED", "RELEASED", "RESET", "ABANDONED", "BACKUP".  For other addresses, it SHOULD be one of the following: "UNKNOWN", "RESERVED" (an address that is managed by DHCP that is reserved for a specific client), "RESERVED-ACTIVE" (same as reserved, but address is currently in use), "ASSIGNED" (assigned manually or by some other mechanism), "UNASSIGNED", "NOTASSIGNABLE".'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.23 
+       NAME 'dhcpExpirationTime' 
+       EQUALITY generalizedTimeMatch 
+       DESC 'This is the time the current lease for an address expires.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.24 
+       NAME 'dhcpStartTimeOfState' 
+       EQUALITY generalizedTimeMatch 
+       DESC 'This is the time of the last state change for a leased address.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.25 
+       NAME 'dhcpLastTransactionTime' 
+       EQUALITY generalizedTimeMatch 
+       DESC 'This is the last time a valid DHCP packet was received from the client.'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.26 
+       NAME 'dhcpBootpFlag' 
+       EQUALITY booleanMatch 
+       DESC 'This indicates whether the address was assigned via BOOTP.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.27 
+       NAME 'dhcpDomainName' 
+       EQUALITY caseIgnoreIA5Match
+       DESC 'This is the name of the domain sent to the client by the server.  It is essentially the same as the value for DHCP option 15 sent to the client, and represents only the domain - not the full FQDN.  To obtain the full FQDN assigned to the client you must prepend the "dhcpAssignedHostName" to this value with a ".".' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.28 
+       NAME 'dhcpDnsStatus' 
+       EQUALITY integerMatch
+       DESC 'This indicates the status of updating DNS resource records on behalf of the client by the DHCP server for this address.  The value is a 16-bit bitmask.'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.29 
+       NAME 'dhcpRequestedHostName' 
+       EQUALITY caseIgnoreIA5Match
+       DESC 'This is the hostname that was requested by the client.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.30 
+       NAME 'dhcpAssignedHostName' 
+       EQUALITY caseIgnoreIA5Match
+       DESC 'This is the actual hostname that was assigned to a client. It may not be the name that was requested by the client.  The fully qualified domain name can be determined by appending the value of "dhcpDomainName" (with a dot separator) to this name.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.31 
+       NAME 'dhcpReservedForClient' 
+       EQUALITY distinguishedNameMatch
+       DESC 'The distinguished name of a "dhcpClient" that an address is reserved for.  This may not be the same as the "dhcpAssignedToClient" attribute if the address is being reassigned but the current lease has not yet expired.'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.32 
+       NAME 'dhcpAssignedToClient' 
+       EQUALITY distinguishedNameMatch
+       DESC 'This is the distinguished name of a "dhcpClient" that an address is currently assigned to.  This attribute is only present in the class when the address is leased.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.33 
+       NAME 'dhcpRelayAgentInfo' 
+       EQUALITY octetStringMatch
+       DESC 'If the client request was received via a relay agent, this contains information about the relay agent that was available from the DHCP request.  This is a hex-encoded option value.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.34 
+       NAME 'dhcpHWAddress' 
+       EQUALITY caseIgnoreIA5Match
+       DESC 'The clients hardware address that requested this IP address.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.35 
+       NAME 'dhcpHashBucketAssignment' 
+       EQUALITY octetStringMatch
+       DESC 'HashBucketAssignment bit map for the DHCP Server, as defined in DHC Load Balancing Algorithm [RFC 3074].' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.36 
+       NAME 'dhcpDelayedServiceParameter' 
+       EQUALITY integerMatch
+       DESC 'Delay in seconds corresponding to Delayed Service Parameter configuration, as defined in  DHC Load Balancing Algorithm [RFC 3074]. '
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.37 
+       NAME 'dhcpMaxClientLeadTime' 
+       EQUALITY integerMatch
+       DESC 'Maximum Client Lead Time configuration in seconds, as defined in DHCP Failover Protocol [FAILOVR]' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.38 
+       NAME 'dhcpFailOverEndpointState' 
+       EQUALITY caseIgnoreIA5Match
+       DESC 'Server (Failover Endpoint) state, as defined in DHCP Failover Protocol [FAILOVR]' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.39 
+       NAME 'dhcpErrorLog' 
+       EQUALITY caseIgnoreIA5Match
+       DESC 'Generic error log attribute that allows logging error conditions within a dhcpService or a dhcpSubnet, like no IP addresses available for lease.'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.40 
+       NAME 'dhcpLocatorDN' 
+       EQUALITY distinguishedNameMatch 
+       DESC 'The DN of dhcpLocator object which contain the DNs of all DHCP configuration objects. There will be a single dhcpLocator object in the tree with links to all the DHCP objects in the tree' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+attributetype  ( 2.16.840.1.113719.1.203.4.41 
+       NAME 'dhcpKeyAlgorithm' 
+       EQUALITY caseIgnoreIA5Match 
+       DESC 'Algorithm to generate TSIG Key' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype  ( 2.16.840.1.113719.1.203.4.42 
+       NAME 'dhcpKeySecret' 
+       EQUALITY octetStringMatch 
+       DESC 'Secret to generate TSIG Key' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.43 
+       NAME 'dhcpDnsZoneServer' 
+       EQUALITY caseIgnoreIA5Match 
+       DESC 'Master server of the DNS Zone' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 2.16.840.1.113719.1.203.4.44 
+       NAME 'dhcpKeyDN' 
+       EQUALITY distinguishedNameMatch 
+       DESC 'The DNs of TSIG Key to use in secure dynamic updates. In case of locator object, this will be list of TSIG keys.  In case of DHCP Service, Shared Network, Subnet and DNS Zone, it will be a single key.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12)
+
+attributetype ( 2.16.840.1.113719.1.203.4.45 
+       NAME 'dhcpZoneDN' 
+       EQUALITY distinguishedNameMatch 
+       DESC 'The DNs of DNS Zone. In case of locator object, this will be list of DNS Zones in the tree. In case of DHCP Service, Shared Network and Subnet, it will be a single DNS Zone.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12)
+
+attributetype ( 2.16.840.1.113719.1.203.4.46 
+       NAME 'dhcpFailOverPrimaryServer' 
+       EQUALITY caseIgnoreIA5Match 
+       DESC 'IP address or DNS name of the server playing primary role in DHC Load Balancing and Fail over.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26  )
+
+attributetype ( 2.16.840.1.113719.1.203.4.47 
+       NAME 'dhcpFailOverSecondaryServer' 
+       EQUALITY caseIgnoreIA5Match 
+       DESC 'IP address or DNS name of the server playing secondary role in DHC Load Balancing and Fail over.' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26  )
+
+attributetype ( 2.16.840.1.113719.1.203.4.48
+       NAME 'dhcpFailOverPrimaryPort' 
+       EQUALITY integerMatch 
+       DESC 'Port on which primary server listens for connections from its fail over peer (secondary server)' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27  )
+       
+attributetype ( 2.16.840.1.113719.1.203.4.49
+       NAME 'dhcpFailOverSecondaryPort' 
+       EQUALITY integerMatch 
+       DESC 'Port on which secondary server listens for connections from its fail over peer (primary server)' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27  )
+
+attributetype ( 2.16.840.1.113719.1.203.4.50
+       NAME 'dhcpFailOverResponseDelay' 
+       EQUALITY integerMatch 
+       DESC 'Maximum response time in seconds, before Server assumes that connection to fail over peer has failed' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27  )
+
+attributetype ( 2.16.840.1.113719.1.203.4.51
+       NAME 'dhcpFailOverUnackedUpdates' 
+       EQUALITY integerMatch 
+       DESC 'Number of BNDUPD messages that server can send before it receives BNDACK from its fail over peer' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27  )
+
+attributetype ( 2.16.840.1.113719.1.203.4.52
+       NAME 'dhcpFailOverSplit' 
+       EQUALITY integerMatch 
+       DESC 'Split between the primary and secondary servers for fail over purpose' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27  )
+
+attributetype ( 2.16.840.1.113719.1.203.4.53
+       NAME 'dhcpFailOverLoadBalanceTime' 
+       EQUALITY integerMatch 
+       DESC 'Cutoff time in seconds, after which load balance is disabled' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27  )
+
+attributetype ( 2.16.840.1.113719.1.203.4.54
+       NAME 'dhcpFailOverPeerDN' 
+       EQUALITY distinguishedNameMatch 
+       DESC 'The DNs of Fail over peers. In case of locator object, this will be list of fail over peers in the tree. In case of Subnet and pool, it will be a single Fail Over Peer' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) 
+
+#List of all servers in the tree
+attributetype ( 2.16.840.1.113719.1.203.4.55
+       NAME 'dhcpServerDN' 
+       EQUALITY distinguishedNameMatch 
+       DESC 'List of all  DHCP Servers in the tree. Used by dhcpLocatorObject' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+
+attributetype ( 2.16.840.1.113719.1.203.4.56
+       NAME 'dhcpComments' 
+       EQUALITY caseIgnoreIA5Match 
+       DESC 'Generic attribute that allows coments  within any DHCP object' 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+# Classes
+
+objectclass ( 2.16.840.1.113719.1.203.6.1 
+       NAME 'dhcpService' 
+       DESC 'Service object that represents the actual DHCP Service configuration. This is a container object.' 
+       SUP top 
+       MUST (cn) 
+       MAY ( dhcpPrimaryDN $ dhcpSecondaryDN $ dhcpServerDN $ dhcpSharedNetworkDN $ dhcpSubnetDN $ dhcpGroupDN $ dhcpHostDN $  dhcpClassesDN $ dhcpOptionsDN $ dhcpZoneDN $ dhcpKeyDN $ dhcpFailOverPeerDN $ dhcpStatements $dhcpComments $ dhcpOption) )
+
+objectclass ( 2.16.840.1.113719.1.203.6.2 
+       NAME 'dhcpSharedNetwork' 
+       DESC 'This stores configuration information for a shared network.' 
+       SUP top 
+       MUST cn 
+       MAY ( dhcpSubnetDN $ dhcpPoolDN $ dhcpOptionsDN $ dhcpZoneDN $ dhcpStatements $dhcpComments $ dhcpOption) X-NDS_CONTAINMENT ('dhcpService' ) )
+
+objectclass ( 2.16.840.1.113719.1.203.6.3 
+       NAME 'dhcpSubnet' 
+       DESC 'This class defines a subnet. This is a container object.' 
+       SUP top 
+       MUST ( cn $ dhcpNetMask ) 
+       MAY ( dhcpRange $ dhcpPoolDN $ dhcpGroupDN $ dhcpHostDN $ dhcpClassesDN $ dhcpLeasesDN $ dhcpOptionsDN $ dhcpZoneDN $ dhcpKeyDN $ dhcpFailOverPeerDN $ dhcpStatements $ dhcpComments $ dhcpOption ) X-NDS_CONTAINMENT ('dhcpService' 'dhcpSharedNetwork') )
+
+objectclass ( 2.16.840.1.113719.1.203.6.4 
+       NAME 'dhcpPool' 
+       DESC 'This stores configuration information about a pool.' 
+       SUP top 
+       MUST ( cn $ dhcpRange ) 
+       MAY ( dhcpClassesDN $ dhcpPermitList $ dhcpLeasesDN $ dhcpOptionsDN $ dhcpZoneDN $dhcpKeyDN $ dhcpStatements $ dhcpComments $ dhcpOption ) 
+       X-NDS_CONTAINMENT ('dhcpSubnet' 'dhcpSharedNetwork') )
+
+objectclass ( 2.16.840.1.113719.1.203.6.5 
+       NAME 'dhcpGroup' 
+       DESC 'Group object that lists host DNs and parameters. This is a container object.' 
+       SUP top 
+       MUST cn 
+       MAY ( dhcpHostDN $ dhcpOptionsDN $ dhcpStatements $ dhcpComments $ dhcpOption )
+       X-NDS_CONTAINMENT ('dhcpSubnet' 'dhcpService' ) )
+
+objectclass ( 2.16.840.1.113719.1.203.6.6 
+       NAME 'dhcpHost' 
+       DESC 'This represents information about a particular client' 
+       SUP top 
+       MUST cn 
+       MAY  (dhcpLeaseDN $ dhcpHWAddress $ dhcpOptionsDN $ dhcpStatements $ dhcpComments $ dhcpOption) 
+       X-NDS_CONTAINMENT ('dhcpService' 'dhcpSubnet' 'dhcpGroup') )
+
+objectclass ( 2.16.840.1.113719.1.203.6.7 
+       NAME 'dhcpClass' 
+       DESC 'Represents information about a collection of related clients.' 
+       SUP top 
+       MUST cn 
+       MAY (dhcpSubClassesDN $ dhcpOptionsDN $ dhcpStatements $ dhcpComments $ dhcpOption) 
+       X-NDS_CONTAINMENT ('dhcpService' 'dhcpSubnet' ) )
+
+objectclass ( 2.16.840.1.113719.1.203.6.8 
+       NAME 'dhcpSubClass' 
+       DESC 'Represents information about a collection of related classes.' 
+       SUP top 
+       MUST cn 
+       MAY (dhcpClassData $ dhcpOptionsDN $ dhcpStatements $ dhcpComments $ dhcpOption) X-NDS_CONTAINMENT 'dhcpClass' )
+
+objectclass ( 2.16.840.1.113719.1.203.6.9 
+       NAME 'dhcpOptions' 
+       DESC 'Represents information about a collection of options defined.' 
+       SUP top AUXILIARY
+       MUST cn 
+       MAY ( dhcpOption $ dhcpComments ) 
+       X-NDS_CONTAINMENT  ('dhcpService' 'dhcpSharedNetwork' 'dhcpSubnet' 'dhcpPool' 'dhcpGroup' 'dhcpHost' 'dhcpClass' ) )
+
+objectclass ( 2.16.840.1.113719.1.203.6.10 
+       NAME 'dhcpLeases' 
+       DESC 'This class represents an IP Address, which may or may not have been leased.' 
+       SUP top 
+       MUST ( cn $ dhcpAddressState ) 
+       MAY ( dhcpExpirationTime $ dhcpStartTimeOfState $ dhcpLastTransactionTime $ dhcpBootpFlag $ dhcpDomainName $ dhcpDnsStatus $ dhcpRequestedHostName $ dhcpAssignedHostName $ dhcpReservedForClient $ dhcpAssignedToClient $ dhcpRelayAgentInfo $ dhcpHWAddress ) 
+       X-NDS_CONTAINMENT ( 'dhcpService' 'dhcpSubnet' 'dhcpPool') )
+
+objectclass ( 2.16.840.1.113719.1.203.6.11 
+       NAME 'dhcpLog' 
+       DESC 'This is the object that holds past information about the IP address. The cn is the time/date stamp when the address was assigned or released, the address state at the time, if the address was assigned or released.' 
+       SUP top 
+       MUST ( cn ) 
+       MAY ( dhcpAddressState $ dhcpExpirationTime $ dhcpStartTimeOfState $ dhcpLastTransactionTime $ dhcpBootpFlag $ dhcpDomainName $ dhcpDnsStatus $ dhcpRequestedHostName $ dhcpAssignedHostName $ dhcpReservedForClient $ dhcpAssignedToClient $ dhcpRelayAgentInfo $ dhcpHWAddress $ dhcpErrorLog) 
+       X-NDS_CONTAINMENT ('dhcpLeases' 'dhcpPool' 'dhcpSubnet' 'dhcpSharedNetwork' 'dhcpService' ) )
+
+objectclass ( 2.16.840.1.113719.1.203.6.12 
+       NAME 'dhcpServer' 
+       DESC 'DHCP Server Object' 
+       SUP top AUXILIARY 
+       MUST ( cn ) 
+       MAY (dhcpServiceDN  $ dhcpLocatorDN $ dhcpVersion $ dhcpImplementation $ dhcpHashBucketAssignment $ dhcpDelayedServiceParameter $ dhcpMaxClientLeadTime $ dhcpFailOverEndpointState $ dhcpStatements $ dhcpComments $ dhcpOption) 
+       X-NDS_CONTAINMENT ('organization' 'organizationalunit' 'domain') )
+
+objectclass ( 2.16.840.1.113719.1.203.6.13 
+       NAME 'dhcpTSigKey' 
+       DESC 'TSIG key for secure dynamic updates' 
+       SUP top 
+       MUST (cn $ dhcpKeyAlgorithm $ dhcpKeySecret ) 
+       MAY ( dhcpComments ) 
+       X-NDS_CONTAINMENT ('dhcpService' 'dhcpSharedNetwork' 'dhcpSubnet') )
+
+objectclass ( 2.16.840.1.113719.1.203.6.14 
+       NAME 'dhcpDnsZone' 
+       DESC 'DNS Zone for updating leases' 
+       SUP top 
+       MUST (cn $ dhcpDnsZoneServer ) 
+       MAY (dhcpKeyDN $ dhcpComments) 
+       X-NDS_CONTAINMENT ('dhcpService' 'dhcpSharedNetwork' 'dhcpSubnet') )
+
+objectclass ( 2.16.840.1.113719.1.203.6.15 
+       NAME 'dhcpFailOverPeer' 
+       DESC 'This class defines the Fail over peer' 
+       SUP top 
+  MUST ( cn $ dhcpFailOverPrimaryServer $ dhcpFailOverSecondaryServer $ dhcpFailoverPrimaryPort $ dhcpFailOverSecondaryPort) MAY (dhcpFailOverResponseDelay  $ dhcpFailOverUnackedUpdates $ dhcpMaxClientLeadTime $ dhcpFailOverSplit $ dhcpHashBucketAssignment $ dhcpFailOverLoadBalanceTime $ dhcpComments ) 
+       X-NDS_CONTAINMENT ('dhcpService' 'dhcpSharedNetwork' 'dhcpSubnet') )
+
+objectclass ( 2.16.840.1.113719.1.203.6.16 
+       NAME 'dhcpLocator' 
+       DESC 'Locator object for DHCP configuration in the tree. There will be a single dhcpLocator object in the tree with links to all the DHCP objects in the tree' 
+       SUP top 
+       MUST ( cn ) 
+       MAY ( dhcpServiceDN $dhcpServerDN $ dhcpSharedNetworkDN $ dhcpSubnetDN $ dhcpPoolDN $ dhcpGroupDN $ dhcpHostDN $  dhcpClassesDN $ dhcpKeyDN $ dhcpZoneDN $ dhcpFailOverPeerDN $ dhcpOption $ dhcpComments) 
+       X-NDS_CONTAINMENT ('organization' 'organizationalunit' 'domain') )
+
+
diff --git a/gosa-core/contrib/openldap/dnszone.schema b/gosa-core/contrib/openldap/dnszone.schema
new file mode 100644 (file)
index 0000000..0714b0b
--- /dev/null
@@ -0,0 +1,155 @@
+# A schema for storing DNS zones in LDAP
+#
+attributetype ( 1.3.6.1.4.1.2428.20.0.0  NAME 'dNSTTL'
+       DESC 'An integer denoting time to live'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.0.1 NAME 'dNSClass'
+       DESC 'The class of a resource record'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.0.2 NAME 'zoneName'
+       DESC 'The name of a zone, i.e. the name of the highest node in the zone'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.0.3 NAME 'relativeDomainName'
+       DESC 'The starting labels of a domain name'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.12 NAME 'pTRRecord'
+       DESC 'domain name pointer, RFC 1035'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.13 NAME 'hInfoRecord'
+       DESC 'host information, RFC 1035'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.14 NAME 'mInfoRecord'
+       DESC 'mailbox or mail list information, RFC 1035'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.16 NAME 'tXTRecord'
+       DESC 'text string, RFC 1035'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.18 NAME 'aFSDBRecord'
+       DESC 'for AFS Data Base location, RFC 1183'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.24 NAME 'SigRecord'
+       DESC 'Signature, RFC 2535'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.25 NAME 'KeyRecord'
+       DESC 'Key, RFC 2535'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.28 NAME 'aAAARecord'
+       DESC 'IPv6 address, RFC 1886'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.29 NAME 'LocRecord'
+       DESC 'Location, RFC 1876'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.30 NAME 'nXTRecord'
+       DESC 'non-existant, RFC 2535'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.33 NAME 'sRVRecord'
+       DESC 'service location, RFC 2782'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.35 NAME 'nAPTRRecord'
+       DESC 'Naming Authority Pointer, RFC 2915'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.36 NAME 'kXRecord'
+       DESC 'Key Exchange Delegation, RFC 2230'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.37 NAME 'certRecord'
+       DESC 'certificate, RFC 2538'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.38 NAME 'a6Record'
+       DESC 'A6 Record Type, RFC 2874'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.39 NAME 'dNameRecord'
+       DESC 'Non-Terminal DNS Name Redirection, RFC 2672'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.43 NAME 'dSRecord'
+       DESC 'Delegation Signer, RFC 3658'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.44 NAME 'sSHFPRecord'
+       DESC 'SSH Key Fingerprint, draft-ietf-secsh-dns-05.txt'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.46 NAME 'rRSIGRecord'
+       DESC 'RRSIG, RFC 3755'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.2428.20.1.47 NAME 'nSECRecord'
+       DESC 'NSEC, RFC 3755'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+objectclass ( 1.3.6.1.4.1.2428.20.3 NAME 'dNSZone'
+        SUP top STRUCTURAL
+       MUST ( zoneName $ relativeDomainName )
+        MAY ( DNSTTL $ DNSClass $
+              ARecord $ MDRecord $ MXRecord $ NSRecord $
+             SOARecord $ CNAMERecord $ PTRRecord $ HINFORecord $
+              MINFORecord $ TXTRecord $ AFSDBRecord $ SIGRecord $
+              KEYRecord $ AAAARecord $ LOCRecord $ NXTRecord $
+              SRVRecord $ NAPTRRecord $ KXRecord $ CERTRecord $
+              A6Record $ DNAMERecord $ DSRecord $ SSHFPRecord $
+              RRSIGRecord $ NSECRecord ) )
diff --git a/gosa-core/contrib/openldap/fai.schema b/gosa-core/contrib/openldap/fai.schema
new file mode 100644 (file)
index 0000000..5bfbcd8
--- /dev/null
@@ -0,0 +1,474 @@
+###############################################################################
+#                                                                             #
+#            F A I - Fully automatic installation LDAP schema file            #
+#                                                                             #
+#-----------------------------------------------------------------------------#
+# Last modified: Cajus Pollmeier / 20050902                                   #
+#-----------------------------------------------------------------------------#
+#             Copyright 2005, Cajus Pollmeier <cajus@debian.org>              #
+#                             Thomas Lange <lange@debian.org>                 #
+#-----------------------------------------------------------------------------#
+# This program is free software; you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation; either version 2 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program; if not, write to the Free Software                 #
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   #
+###############################################################################
+
+
+# This schema file has dependencies to the nis.schema. Please make sure that
+# the inclusion order in your slapd.conf is correct.
+
+
+# Here's a short list of object class / attribute relationship. For a more
+# detailed description take a look at the definitions below.
+#
+# Objectclasses        | Attributes
+# -----------------------------------------------------------------------------
+# FAIclass             | cn,description,FAIclassType
+# FAIprofile           | FAIclass
+# FAIhook              | (inherit from FAIclass)
+# FAIhookEntry         | FAIscript, FAItask
+# FAIscript            | (inherit from FAIclass)
+# FAIscriptEntry       | FAIscript, FAIpriority
+# FAIvariable          | (inherit from FAIclass)
+# FAIvariableEntry     | FAIvariableContent
+# FAItemplate          | (inherit from FAIclass)
+# FAItemplateEntry     | FAItemplateFile, FAItemplatePath, FAIowner, FAImode
+# FAIpartitionTable    | (inherit from FAIclass)
+# FAIpartitionDisk     | (inherit from FAIclass)
+# FAIpartitionEntry    | FAIpartitionType, FAIpartitionNr, FAImountOptions,
+#                      | FAIfsOptions, FAIfsType, FAImountPoint,FAIpartitionSize,
+#                      | FAIpartitionFlag
+# FAIpackageList       | FAIinstallMethod, FAIpackage
+# FAIdebconfInfo       | FAIvariable, FAIvariableContent, FAIvariableType
+# FAIobject            | FAIclass, FAIstatus, macAddress
+# FAIrepository        | FAIdebianMirror, FAIdebianRelease, FAIdebianSection
+# FAIrepositoryServer  | FAIrepository
+#
+# Rem.: Except of FAIdebconfInfo and FAIobject, all object classes are inherited
+#       from FAIclass, so ALL cn's MUST be unique in your tree.
+
+
+##
+## Attribute definitions (allocated from the GONICUS oid space)
+##
+
+# Name       : FAIclass
+# Description: Notes which FAI class name(s) are used in an FAI object
+#              or in profile definitions. No unicode here, maximum
+#              length is set to 64 characters.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.1 NAME 'FAIclass'
+               DESC 'Storage for FAI class names'
+               EQUALITY caseExactMatch
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64})
+
+# Name       : FAIpriority
+# Description: Notes which priority scripts or profiles entries get. It is used
+#              by FAI to generate a propper class list during the bootstrap
+#              process. This is an unsigned integer value. 
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.2 NAME 'FAIpriority'
+               DESC 'Storage for FAI priorities'
+               EQUALITY integerMatch
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
+
+# Name       : FAIpartitionType
+# Description: As the name says, we store the type of a (hard-disk) partition
+#              here. Type can be one of "primary" or "secondary". We did not
+#              make this bool because there may be changes to the FAI partitioner
+#              which we can't handle then. The maximum length is set to 16
+#              characters.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.3 NAME 'FAIpartitionType'
+               DESC 'Storage for FAI partition types'
+               EQUALITY caseExactMatch
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{16} SINGLE-VALUE)
+
+# Name       : FAIpartitionNr
+# Description: We use this value to store the device entries like "disk1" or
+#              "sda8" with this attribute. Currently the storage is without the
+#              leading "/dev/".
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.4 NAME 'FAIpartitionNr'
+               DESC 'Storage for FAI partition devices'
+               EQUALITY caseExactIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAImountOptions
+# Description: We use this value to store special mount options for partitions.
+#              For example some people tend to have /usr mounted as read-only.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.5 NAME 'FAImountOptions'
+               DESC 'Storage for FAI partition mount options'
+               EQUALITY caseExactIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAImountPoint
+# Description: Simply the mountpoint like found in the fstab. Examples are
+#              '/usr', '/' and '/home'.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.6 NAME 'FAImountPoint'
+               DESC 'Storage for FAI partition mount points'
+               EQUALITY caseExactIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIfsOptions
+# Description: In some cases you might want to influence the filesystem
+#              generation commands by adding flags for larger inode tables, etc.
+#              FAIfsOptions keeps the flags that are used by the mkfs workers.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.7 NAME 'FAIfsOptions'
+               DESC 'Storage for FAI partition generation options'
+               EQUALITY caseExactIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIfsType
+# Description: Keeps the type of the filessytem a partition gets formatted with.
+#              Examples are 'ext3', 'xfs', etc. Please refer to the FAI manual
+#              for valid types.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.8 NAME 'FAIfsType'
+               DESC 'Storage for FAI partition types'
+               EQUALITY caseExactMatch
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{16} SINGLE-VALUE)
+
+# Name       : FAIscript
+# Description: Store multiline text, mostly used for scripts and hooks. 
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.9 NAME 'FAIscript'
+               DESC 'General storage field for multiline text aka scripts'
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE)
+
+# Name       : FAItask
+# Description: Assign a hook to a special task. You can use it i.e. to alter
+#              partition tables, etc. The FAI manual hold a list of valid
+#              tasks for you.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.10 NAME 'FAItask'
+               DESC 'Note for which FAI tasks a hook is made for'
+               EQUALITY caseIgnoreIA5Match
+               SUBSTR caseIgnoreIA5SubstringsMatch
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIvariable
+# Description: Keeps the name of a debconf template variable. The value is
+#              stored inside of FAIvariableContent, the type inside
+#              FAIvariableType.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.11 NAME 'FAIvariable'
+               DESC 'Store debconf template variable names'
+               EQUALITY caseIgnoreIA5Match
+               SUBSTR caseIgnoreIA5SubstringsMatch
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIvariableContent
+# Description: Keeps the content of a debconf template variable. See
+#              FAIvariable for more informations.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.12 NAME 'FAIvariableContent'
+               DESC 'Store debconf template variable contents'
+               EQUALITY caseIgnoreIA5Match
+               SUBSTR caseIgnoreIA5SubstringsMatch
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIvariableType
+# Description: Keeps the type of a debconf template variable. See
+#              FAIvariable for more informations.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.13 NAME 'FAIvariableType'
+               DESC 'Store debconf template variable type'
+               EQUALITY caseIgnoreIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIinstallMethod
+# Description: Keeps a per package setting on how packages should be
+#              installed. This is the normal line you'd specify in
+#              our ordinary package lists.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.14 NAME 'FAIinstallMethod'
+               DESC 'Store debian package installation flag'
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIpackage
+# Description: Keeps an entry of a package list. Each FAIpackage object
+#              may be a parent for FAIdebconfInfo objects.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.15 NAME 'FAIpackage'
+               DESC 'Store debian package name'
+               EQUALITY caseIgnoreIA5Match
+               SUBSTR caseIgnoreIA5SubstringsMatch
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+# Name       : FAItemplateFile
+# Description: Keeps complete template files that are copied to the
+#              freshly installed system later on. The tasks path is
+#              stored in FAItemplatePath. Use ;binary for this attribute.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.16 NAME 'FAItemplateFile'
+               DESC 'Store complete template files'
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE)
+
+# Name       : FAItemplatePath
+# Description: Keeps the path used for template files. See FAItemplateFile
+#              for more informations.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.17 NAME 'FAItemplatePath'
+               DESC 'Store template file storage path'
+               EQUALITY caseIgnoreIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIowner
+# Description: Keeps the owner used for template files. Put in the unix
+#              way like user.group.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.18 NAME 'FAIowner'
+               DESC 'Store template file storage path'
+               EQUALITY caseIgnoreIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAImode
+# Description: Keeps the file mode used for template files. Put in the unix
+#              way like 775.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.19 NAME 'FAImode'
+               DESC 'Store template file storage path'
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE)
+               
+# Name       : FAIstatus
+# Desrciption: Normally the fai daemon should set the status flag to the
+#             current status. Possible states are:
+#             * update-needed
+#             * update-running
+#             * update-failed
+#             * update-ok
+#             * install-running
+#             * install-failed
+#             * install-ok
+#             Additional informations can be taken from the log files if
+#             some machine is set to -failed.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.20 NAME 'FAIstatus'
+               DESC 'Store FAI progress status'
+               EQUALITY caseIgnoreIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIpackagelistDependency
+# Description: This field stores dependency informations for package lists.
+#              It is used to install i.e. ati specific packages when the
+#              hardware detection detects ATI gfx cards.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.21 NAME 'FAIpackagelistDependency'
+               DESC 'Store package lists where we depend from'
+               EQUALITY caseIgnoreIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIpartitionSize
+# Description: Store a size or a size range for partitions. I.e. 50,
+#              50-200.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.22 NAME 'FAIpartitionSize'
+               DESC 'Store size range for partition size'
+               EQUALITY caseIgnoreIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIpartitionFlags
+# Description: Optionally this flag contains the "preserve" keyword, in
+#              order to influence partitioning.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.23 NAME 'FAIpartitionFlags'
+               DESC 'Optional flags like "preserve"'
+               EQUALITY caseIgnoreIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIdebianMirror
+# Description: Used for bootstrap sources.list settings. It contains
+#              the mirror server url.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.24 NAME 'FAIdebianMirror'
+               DESC 'TODO'
+               EQUALITY caseIgnoreIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIdebianRelease
+# Description: Used for bootstrap sources.list settings. It contains
+#              the release.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.25 NAME 'FAIdebianRelease'
+               DESC 'TODO'
+               EQUALITY caseIgnoreIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Name       : FAIdebianSection
+# Description: Used for bootstrap sources.list settings. It contains
+#              the section. Multiple Sections get appended.
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.26 NAME 'FAIdebianSection'
+               DESC 'TODO'
+               EQUALITY caseIgnoreIA5Match
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+# Name       : FAIrepository
+# Description: Used to store repository settings 
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.27 NAME 'FAIrepository'
+               DESC 'TODO'
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+               
+# Name       : FAIstate
+# Description: Used to store repository state (branched/freezed)
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.28 NAME 'FAIstate'
+               DESC 'TODO'
+                EQUALITY caseIgnoreIA5Match
+                SUBSTR caseIgnoreIA5SubstringsMatch
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+# Name       : FAIrelease
+# Description: Used to store the release
+attributetype ( 1.3.6.1.4.1.10098.1.1.5.29 NAME 'FAIrelease'
+               DESC 'TODO'
+               SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+##
+## Object class definitions (allocated from the GONICUS oid space)
+##
+
+# Name       : FAIclass
+# Description: FAIclass is the basic container wich includes a
+#              common name and a description.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.1 NAME 'FAIclass'
+       SUP top STRUCTURAL
+       DESC 'Generic class parent for FAI objects'
+       MUST ( cn ) MAY  ( FAIstate $ description ) )
+
+# Name       : FAIprofile
+# Description: FAIprofile which bundles a set of FAIclass entries
+#              like FAIpartition and FAIpackageList. It is used
+#              to simplify administration tasks for so called junior
+#              administrators.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.2 NAME 'FAIprofile'
+       SUP top AUXILIARY
+       DESC 'FAI profile container for multiple class objects' 
+       MUST ( cn $ FAIclass ) MAY  ( FAIstate $ description ) )
+
+# Name       : FAIpartitionTable
+# Description: Each installation profile should contain a partition
+#              table in order to perform well. FAIpartitionTable is
+#              a container for partition entries.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.3 NAME 'FAIpartitionTable'
+       SUP top AUXILIARY
+       DESC 'Stores FAI partition tables'
+       MUST ( cn ) MAY  ( FAIstate $ description ) )
+
+# Name       : FAIpartitionDisk
+# Description: Each installation profile should contain a partition
+#              table in order to perform well. FAIpartitionTable is
+#              a container for partition entries.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.4 NAME 'FAIpartitionDisk'
+       SUP top AUXILIARY
+       DESC 'Stores FAI partition tables' 
+       MUST ( cn ) MAY  ( FAIstate $ description ) )
+
+# Name       : FAIpartitionEntry
+# Description: This object defines a single partition entry for the
+#              FAI partitioner.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.5 NAME 'FAIpartitionEntry'
+       SUP top AUXILIARY
+       DESC 'One partition table entry'
+       MUST ( FAIpartitionType $ FAIpartitionNr $ FAIfsType $
+              FAImountPoint $ FAIpartitionSize $ cn )
+       MAY  ( FAImountOptions $ FAIfsOptions $ FAIpartitionFlags $
+              description $ FAIstate ) )
+
+# Name       : FAIhook
+# Description: Container for hooks
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.6 NAME 'FAIhook'
+       SUP top AUXILIARY
+       DESC 'Stores FAI partition tables'
+       MUST ( cn ) MAY  ( FAIstate $ description ) )
+
+# Name       : FAIhookEntry
+# Description: Hooks are stored with their FAI task inside the
+#              FAIhook object.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.7 NAME 'FAIhookEntry'
+       SUP top AUXILIARY
+       DESC 'FAI hook storage'
+       MUST ( cn $ FAIscript $ FAItask ) MAY ( FAIstate $ description ) )
+
+# Name       : FAIscriptEntry
+# Description: Container for scripts
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.8 NAME 'FAIscriptEntry'
+       SUP top AUXILIARY
+       DESC 'FAI script storage'
+       MUST ( cn $ FAIscript $ FAIpriority ) MAY ( FAIstate $ description ) )
+
+# Name       : FAIscript
+# Description: Hooks and scripts are somewhat similar.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.9 NAME 'FAIscript'
+       SUP top AUXILIARY
+       DESC 'FAI script storage'
+       MUST ( cn ) MAY  ( FAIstate $ description ) )
+
+# Name       : FAIvariable
+# Description: Store a set of variables in this container.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.10 NAME 'FAIvariable'
+       SUP top AUXILIARY
+       DESC 'Stores FAI variables sub entries'
+       MUST ( cn ) MAY  ( FAIstate $ description ) )
+
+# Name       : FAIvariableEntry
+# Description: Stores a single variable.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.11 NAME 'FAIvariableEntry'
+       SUP top AUXILIARY
+       DESC 'Stores single variable entries'
+       MUST ( cn $ FAIvariableContent ) MAY ( FAIstate $ description ) )
+
+# Name       : FAIpackagelist
+# Description: Stores a complete package list and is container
+#              for several FAIdebconfInfo scripts
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.12 NAME 'FAIpackageList'
+       SUP top AUXILIARY
+       DESC 'Stores complete package lists'
+       MUST ( cn $ FAIpackage ) MAY ( FAIpackagelistDependency $ FAIinstallMethod $ description $ FAIstate ) )
+
+# Name       : FAItemplate
+# Description: Container for template objects.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.13 NAME 'FAItemplate'
+       SUP top AUXILIARY
+       DESC 'Container for template objects' 
+       MUST ( cn ) MAY  ( FAIstate $ description ) )
+
+# Name       : FAItemplateEntry
+# Description: Stores FAI templates and the corresponding path.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.14 NAME 'FAItemplateEntry'
+       SUP top AUXILIARY
+       DESC 'Stores real file templates'
+       MUST ( cn $ FAItemplateFile $ FAItemplatePath $ FAIowner $ FAImode ) 
+       MAY ( FAIstate $ description ) )
+       
+# Name       : FAIdebconfInfo
+# Description: Stores debconf information like shown in
+#              debconf-getselections.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.15 NAME 'FAIdebconfInfo'
+       SUP top STRUCTURAL
+       DESC 'Stores debconf informations for single packages'
+       MUST ( FAIpackage $ FAIvariable $ FAIvariableType ) MAY ( FAIvariableContent $ FAIstate ) )
+
+# Name       : FAIobject
+# Description: Marks objects to have a set of FAI classes.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.16 NAME 'FAIobject'
+       SUP top AUXILIARY
+       DESC 'Marks an object as an FAI object.'
+       MAY ( FAIstate $ FAIstatus $ FAIclass $ FAIdebianMirror $ macAddress) )
+
+# Name       : FAIrepository
+# Description: Marks objects to have a set of FAI classes.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.17 NAME 'FAIrepository'
+       SUP top AUXILIARY
+       DESC 'Provides per object repository informations.'
+       MUST ( FAIdebianRelease $ FAIdebianSection ) MAY ( FAIdebianMirror ) )
+
+# Name       : FAIrepositoryServer
+# Description: FAIrepositoryServer stores information about repository settings.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.18 NAME 'FAIrepositoryServer'
+       SUP top AUXILIARY
+       DESC 'Provides repository informations.'
+       MAY ( FAIrepository ) )
+
+# Name       : FAIbranch
+# Description: FAIbranch stores information about the state of a set of FAI classes.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.19 NAME 'FAIbranch'
+       SUP top AUXILIARY
+       DESC 'Provides information for versioning.'
+       MAY ( FAIstate ) )
+
+# Name       : FAIreleaseTag
+# Description: FAIreleaseTag stores information about the fai release of an object.
+objectclass (1.3.6.1.4.1.10098.1.2.1.40.20 NAME 'FAIreleaseTag'
+       SUP top AUXILIARY
+       DESC 'Provides information for versioning.'
+       MAY ( FAIrelease ) )
+
+### END of FAI schema file
diff --git a/gosa-core/contrib/openldap/glpi.schema b/gosa-core/contrib/openldap/glpi.schema
new file mode 100644 (file)
index 0000000..6028bfd
--- /dev/null
@@ -0,0 +1,21 @@
+#
+## schema file for OpenLDAP 2.x
+## Schema for storing glpi User Configuration in LDAP
+## OIDs are owned by OpenSides
+##
+#
+# $Id: glpi.schema,v 1.1 2005/11/02 16:48:16 benoit Exp $
+#
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.4.1 NAME 'glpiAccountLogin'
+        DESC 'glpi Account Login'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+#
+# all objectclass 
+#
+
+objectclass ( 1.3.6.1.4.1.22262.1.1.2.4.1 NAME 'glpiAccount' SUP top AUXILIARY
+ DESC 'glpi Account'
+ MAY ( glpiAccountLogin  ))
\ No newline at end of file
diff --git a/gosa-core/contrib/openldap/goconfig.schema b/gosa-core/contrib/openldap/goconfig.schema
new file mode 100644 (file)
index 0000000..64fbf84
--- /dev/null
@@ -0,0 +1,43 @@
+## 
+##
+## goconfig.schema - Needed by the GONICUS System Administator
+##
+## Version 030719
+##
+##
+## Maintainer:         Lars Scheiter   (scheiter@GONICUS.de)
+##                     Cajus Pollmeier (pollmeier@GONICUS.de)
+##
+##
+
+
+# Attributes for the GONICUS server extensions
+
+# Syntax: regex
+attributetype ( 1.3.6.1.4.1.10098.1.1.10.8 NAME 'goLogcheckIgnoreMatch'
+       DESC 'Contains a regular expression to ignore'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+# Syntax: regex
+attributetype ( 1.3.6.1.4.1.10098.1.1.10.9 NAME 'goLogcheckMatch'
+       DESC 'Contains a regular expression to ignore'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+# Syntax: value
+attributetype ( 1.3.6.1.4.1.10098.1.1.10.10 NAME 'goLogcheckCategory'
+       DESC 'Contains a regular expression to ignore'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+##
+##             Objectclasses
+##
+
+# Logging object
+objectclass (1.3.6.1.4.1.10098.1.2.2.2 NAME 'goLogcheckObject' SUP top STRUCTURAL
+       DESC 'Logcheck rule container (v2.4)'
+       MUST ( cn $ goLogcheckCategory )
+       MAY  ( goLogcheckMatch $ goLogcheckIgnoreMatch ))
+
diff --git a/gosa-core/contrib/openldap/gofax.schema b/gosa-core/contrib/openldap/gofax.schema
new file mode 100644 (file)
index 0000000..b949016
--- /dev/null
@@ -0,0 +1,95 @@
+## 
+## Gonicus Attribute and Objectclass Definitions for GOfax
+##
+## Version: 030403
+##
+##     Maintained by:  Lars Scheiter (scheiter@GONICUS.de)
+##
+
+# Attributes 
+attributetype ( 1.3.6.1.4.1.10098.1.1.7.1 NAME 'goFaxDeliveryMode'
+       DESC 'goFax delivery mode is defined here'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.7.2 NAME 'goFaxPrinter'
+       DESC 'defines which printer is used to print a fax'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.7.3 NAME 'goFaxDivertNumber'
+       DESC 'for fax diversion services'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.22
+       SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.7.4 NAME 'goFaxLanguage'
+       DESC 'preferred language for the users goFax entry'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.7.5 NAME 'goFaxFormat'
+       DESC 'defines the fileformat for mailattachments'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.7.6 NAME 'goFaxRBlocklist'
+       DESC 'defines faxnumbers the user is not allowed to get fax from'
+       EQUALITY caseExactIA5Match 
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.7.8 NAME 'goFaxSBlocklist'
+       DESC 'defines faxnumbers the user is not allowed to fax to'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.7.7 NAME 'goFaxRBlockgroups'
+       DESC 'defines groups of receive blocklists the user belongs to'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.7.9 NAME 'goFaxSBlockgroups'
+       DESC 'defines groups of sender blocklists the user belongs to'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.7.10 NAME 'goFaxIsEnabled'
+       DESC 'This account is enabled or not'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.7.11 NAME 'facsimileAlternateTelephoneNumber'
+       EQUALITY telephoneNumberMatch
+    SUBSTR telephoneNumberSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32} )
+
+# objectclass 
+objectclass (1.3.6.1.4.1.10098.1.2.1.11 NAME 'goFaxAccount' SUP top AUXILIARY
+       DESC 'goFax Account objectclass (v1.0.4)'
+       MUST ( goFaxDeliveryMode $ facsimileTelephoneNumber $ uid $ goFaxIsEnabled )
+       MAY ( goFaxPrinter $ goFaxDivertNumber $ goFaxLanguage $ goFaxFormat $ goFaxRBlocklist $ 
+             goFaxRBlockgroups $ goFaxSBlocklist $ goFaxSBlockgroups $ mail $
+             facsimileAlternateTelephoneNumber ))
+
+objectclass (1.3.6.1.4.1.10098.1.2.1.12 NAME 'goFaxSBlock'
+       DESC 'goFax send blocklist groups (v1.0.4)'
+       MUST ( cn )
+       MAY ( goFaxSBlocklist $ description ))
+
+objectclass (1.3.6.1.4.1.10098.1.2.1.13 NAME 'goFaxRBlock'
+       DESC 'goFax receive blocklist groups (v1.0.4)'
+       MUST ( cn )
+       MAY ( goFaxRBlocklist $ description ))
+
diff --git a/gosa-core/contrib/openldap/gofirewall.schema b/gosa-core/contrib/openldap/gofirewall.schema
new file mode 100644 (file)
index 0000000..3405b9d
--- /dev/null
@@ -0,0 +1,128 @@
+##
+##
+## gofirewall.schema - Used to store some firewalling data
+##
+##
+## Version 030403
+##
+##
+## Maintainer: Cajus Pollmeier (pollmeier@GONICUS.de)
+##             Lars Scheiter   (scheiter@GONICUS.de)
+##
+##
+
+
+# Attributes for FireWall Configs
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.1 NAME 'FWdevice'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.2 NAME 'FWtype'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.3 NAME 'FWaction'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.4 NAME 'FWtable'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.5 NAME 'FWsource'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.6 NAME 'FWdest'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.7 NAME 'FWservice'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.8 NAME 'FWprotocol'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.10 NAME 'FWlog'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.11 NAME 'FWnetwork'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.12 NAME 'FWhost'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.14 NAME 'FWproto'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.15 NAME 'FWlist'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.16 NAME 'FWdisabled'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.4.17 NAME 'FWid'
+       DESC 'Firewall definitions'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+##
+##     Objectclasses
+##
+
+# ObjectClasses for Firewall Setups
+objectclass (1.3.6.1.4.1.10098.1.2.1.6 NAME 'FWRule'
+       DESC 'Firewall rule definition' SUP top AUXILIARY
+       MUST ( cn $ FWtype )
+       MAY ( FWdevice $ FWaction $ FWtable $ FWsource $ FWdest $ FWservice $ FWprotocol $
+               FWtable $ FWlog $ FWid )) 
+
+objectclass (1.3.6.1.4.1.10098.1.2.1.7 NAME 'FWGroup'
+       DESC 'Firewall group definition' SUP top AUXILIARY
+       MUST ( cn )
+       MAY ( FWnetwork $ FWhost $ FWservice $ FWproto $ FWid))
+
+objectclass (1.3.6.1.4.1.10098.1.2.1.8 NAME 'FWRuleSet'
+       DESC 'Firewall ruleset definition' SUP top AUXILIARY
+       MUST ( cn )
+       MAY ( FWlist $ FWdisabled $ FWid))
+
diff --git a/gosa-core/contrib/openldap/gofon.schema b/gosa-core/contrib/openldap/gofon.schema
new file mode 100644 (file)
index 0000000..b16a7fe
--- /dev/null
@@ -0,0 +1,324 @@
+## 
+## Gonicus Attribute and Objectclass Definitions for GOfon
+##
+##     Maintained by:  Cajus Pollmeier <pollmeier@gonicus.de>
+##
+
+# Attributes 
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.1 NAME 'goFonDeliveryMode'
+       DESC 'GOFon delivery mode is defined here'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.2 NAME 'goFonForwarding'
+       DESC 'defines which phone numbers get the next call'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.3 NAME 'goFonFormat'
+       DESC 'defines voicemail delivery format'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.4 NAME 'goFonHardware'
+       DESC 'defines voicemail delivery format'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.5 NAME 'goFonPIN'
+       DESC 'defines voicemail delivery format'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.6 NAME 'goFonType'
+       DESC 'sets the sip.conf type parameter'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.7 NAME 'goFonDmtfMode'
+       DESC 'sets the sip.conf dmtfmode parameter'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.8 NAME 'goFonHost'
+       DESC 'sets the sip.conf host parameter'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.9 NAME 'goFonDefaultIP'
+       DESC 'sets the sip.conf defaultip parameter'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.10 NAME 'goFonQualify'
+       DESC 'sets the sip.conf qualify parameter'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.11 NAME 'goFonAuth'
+       DESC 'sets the sip.conf auth parameter'
+       EQUALITY caseExactMatch
+       SUBSTR caseExactSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.12 NAME 'goFonSecret'
+       DESC 'sets the sip.conf secret parameter'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.13 NAME 'goFonInkeys'
+       DESC 'sets the sip.conf inkeys parameter'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.14 NAME 'goFonOutkey'
+       DESC 'sets the sip.conf outkey parameter'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.15 NAME 'goFonTrunk'
+       DESC 'sets the sip.conf trunk parameter'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.16 NAME 'goFonAccountCode'
+       DESC 'sets the sip.conf accountcode parameter'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.17 NAME 'goFonMSN'
+       DESC 'sets the sip.conf msn parameter'
+       EQUALITY telephoneNumberMatch
+       SUBSTR telephoneNumberSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32} SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.18 NAME 'goFonPermit'
+       DESC 'sets the sip.conf permit parameter'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.19 NAME 'goFonDeny'
+       DESC 'sets the sip.conf deny parameter'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.20 NAME 'goFonMacroVisible'
+       DESC 'Triggers if the macro is visible for users'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.21 NAME 'goFonMacroContent'
+       DESC 'Holds the macro'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.22 NAME 'goFonMacroParameter'
+       DESC 'Holds the macro parameter definitions'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.23 NAME 'goFonMacro'
+    DESC 'Holds the macro parameter definitions'
+    EQUALITY caseExactMatch
+    SUBSTR caseExactSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.24 NAME 'goFonTimeOut'
+    DESC 'Holds the queue goFonTimeOut definitions'
+    EQUALITY integerMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.25 NAME 'goFonMaxLen'
+    DESC 'Holds the queue goFonMaxLen definitions'
+    EQUALITY integerMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.26 NAME 'goFonAnnounceFrequency'
+    DESC 'Holds the queue goFonAnnounceFrequency definitions'
+    EQUALITY integerMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.27 NAME 'goFonDialOption'
+    DESC 'Holds the queue goFonDialOption definitions'
+    EQUALITY caseExactMatch
+    SUBSTR caseExactSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{16} SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.28 NAME 'goFonMusiconHold'
+    DESC 'Holds the queue goFonMusiconHold definitions'
+    EQUALITY caseExactIA5Match
+    SUBSTR caseExactIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.29 NAME 'goFonWelcomeMusic'
+    DESC 'Holds the queue goFonWelcomeMusic definitions'
+    EQUALITY caseExactIA5Match
+    SUBSTR caseExactIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.30 NAME 'goFonQueueReportHold'
+    DESC 'Holds the queue goFonQueueReportHold definitions'
+    EQUALITY caseExactIA5Match
+    SUBSTR caseExactIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.31 NAME 'goFonQueueYouAreNext'
+    DESC 'Holds the queue goFonQueueYouAreNext definitions'
+    EQUALITY caseExactIA5Match
+    SUBSTR caseExactIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.32 NAME 'goFonQueueThereAre'
+    DESC 'Holds the queue goFonQueueThereAre definitions'
+    EQUALITY caseExactIA5Match
+    SUBSTR caseExactIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.33 NAME 'goFonQueueCallsWaiting'
+    DESC 'Holds the queue goFonQueueCallsWaiting definitions'
+    EQUALITY caseExactIA5Match
+    SUBSTR caseExactIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.34 NAME 'goFonQueueThankYou'
+    DESC 'Holds the queue goFonQueueThankYou definitions'
+    EQUALITY caseExactIA5Match
+    SUBSTR caseExactIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.35 NAME 'goFonQueueMinutes'
+    DESC 'Holds the queue goFonQueueMinutes definitions'
+    EQUALITY caseExactIA5Match
+    SUBSTR caseExactIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.36 NAME 'goFonQueueSeconds'
+    DESC 'Holds the queue goFonQueueSeconds definitions'
+    EQUALITY caseExactIA5Match
+    SUBSTR caseExactIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.37 NAME 'goFonQueueLanguage'
+    DESC 'Holds the queue goFonLanguage definitions'
+    EQUALITY caseExactIA5Match
+    SUBSTR caseExactIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.38 NAME 'goFonQueueStrategy'
+    DESC 'Holds the queue goFonStrategy definitions'
+    EQUALITY caseExactIA5Match
+    SUBSTR caseExactIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.39 NAME 'goFonQueueAnnounceHoldtime'
+    DESC 'Holds the queue goFonAnnounceHoldtime definitions'
+    EQUALITY caseExactMatch
+    SUBSTR caseExactSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4} SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.40 NAME 'goFonQueueAnnounce'
+    DESC 'Holds the queue goFonAnnounce definitions'
+    EQUALITY caseExactIA5Match
+    SUBSTR caseExactIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.41 NAME 'goFonQueueRetry'
+    DESC 'Holds the queue goFonRetry definitions'
+       EQUALITY integerMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.42 NAME 'goFonQueueLessThan'
+    DESC 'Holds the queue goFonQueueLessThan definitions'
+    EQUALITY caseExactIA5Match
+    SUBSTR caseExactIA5SubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.43 NAME 'goFonConferenceOption'
+    DESC 'Holds the queue goFonConferenceOptions definitions'
+    EQUALITY caseExactMatch
+    SUBSTR caseExactSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{16} SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.44 NAME 'goFonConferenceTimeOut'
+    DESC 'Holds the queue goFonConferenceTimeOut definitions'
+    EQUALITY integerMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.45 NAME 'goFonConferenceOwner'
+    DESC 'Holds the queue goFonConferenceOwner definitions'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.46 NAME 'goFonVoicemailPIN'
+       DESC 'defines voicemail delivery format'
+       EQUALITY caseExactIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.13.47 NAME 'goFonHomeServer'
+       DESC 'defines voicemail delivery format'
+       EQUALITY caseExactMatch
+       SUBSTR caseExactSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
+
+# objectclass 
+objectclass (1.3.6.1.4.1.10098.1.2.3.11 NAME 'goFonAccount' SUP top AUXILIARY
+       DESC 'GOFon Account objectclass (v1.0)'
+       MUST ( goFonDeliveryMode $ telephoneNumber $ uid )
+       MAY ( goFonFormat $ goFonForwarding $ goFonHardware $ goFonPIN $ goFonVoicemailPIN $ goFonMacro $ goFonHomeServer ))
+
+objectclass (1.3.6.1.4.1.10098.1.2.3.12 NAME 'goFonHardware' SUP top STRUCTURAL
+       DESC 'defines a telephone (v1.0)'
+       MUST ( cn $ macAddress $ ipHostNumber )
+       MAY (description $ goFonType $ goFonDmtfMode $ goFonHost $ goFonDefaultIP $
+                goFonQualify $ goFonAuth $ goFonSecret $ goFonInkeys $ goFonOutkey $
+                goFonTrunk $ goFonAccountCode $ goFonMSN $ goFonPermit $ goFonDeny ) )
+
+objectclass (1.3.6.1.4.1.10098.1.2.3.13 NAME 'goFonPickupGroup' SUP top AUXILIARY
+       DESC 'Additive for posixGroups (v1.0)'
+       MUST ( cn $ gidNumber ) )
+
+objectclass (1.3.6.1.4.1.10098.1.2.3.14 NAME 'goFonMacro' SUP top STRUCTURAL
+       DESC 'Macro definitions for asterisk machines (v1.0)'
+       MUST ( cn ) 
+       MAY ( goFonMacroVisible $ displayName $ goFonMacroContent $ description $
+                 goFonMacroParameter ))
+
+objectclass (1.3.6.1.4.1.10098.1.2.3.15 NAME 'goFonQueue' SUP top AUXILIARY
+       DESC 'Queue definitions for asterisk machines (v1.0)'
+       MUST ( cn ) 
+       MAY ( goFonTimeOut $ goFonMaxLen $ goFonAnnounceFrequency $ goFonDialOption $
+                 goFonMusiconHold $ goFonWelcomeMusic $ goFonQueueReportHold $
+                 goFonQueueYouAreNext $ goFonQueueThereAre $ goFonQueueCallsWaiting $
+                 goFonQueueThankYou $ goFonQueueMinutes $ goFonQueueSeconds $ telephoneNumber $
+                 goFonQueueLanguage $ goFonQueueStrategy $ goFonQueueAnnounceHoldtime $ goFonQueueAnnounce $
+                 goFonQueueRetry $ goFonQueueLessThan $ goFonHomeServer ))
+
+objectclass (1.3.6.1.4.1.10098.1.2.3.16 NAME 'goFonConference' SUP top STRUCTURAL
+       DESC 'Conference definitions for asterisk machines (v1.0)'
+       MUST ( cn ) 
+       MAY ( description $ goFonConferenceOption $ goFonConferenceTimeout $ goFonPIN $
+                 goFonConferenceOwner $ telephoneNumber $ goFonHomeServer))
+
diff --git a/gosa-core/contrib/openldap/gosa+samba3.schema b/gosa-core/contrib/openldap/gosa+samba3.schema
new file mode 100644 (file)
index 0000000..2016066
--- /dev/null
@@ -0,0 +1,379 @@
+##
+## Needed attributes for GOsa (GONICUS System Administrator)
+##
+## Version 030303
+##
+## Maintainer: Cajus Pollmeier (pollmeier@GONICUS.de)
+##
+
+
+# Attributes
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.1 NAME 'gosaSubtreeACL'
+        DESC 'GOsa acl entry'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.2 NAME 'gosaUser'
+        DESC 'GOsa user'
+        EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.3 NAME 'gosaObject'
+        DESC 'GOsa object'
+        EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.4 NAME 'gosaMailServer'
+        DESC 'Specify users main mail server'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.5 NAME 'gosaMailQuota'
+        DESC 'GOsa quota definitions'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.6 NAME 'gosaMailAlternateAddress'
+        DESC 'Additional mail addresses where the user is reachable'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.7 NAME 'gosaMailForwardingAddress'
+        DESC 'Addresses where to forward mail to'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.8 NAME 'gosaMailMaxSize'
+        DESC 'Block mails bigger than this value'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.9 NAME 'gosaSpamSortLevel'
+        DESC 'Spamassassins hits'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.10 NAME 'gosaSpamMailbox'
+        DESC 'Where to put spam'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.11 NAME 'gosaVacationMessage'
+        DESC 'Text to display in case of vacation'
+        EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.12 NAME 'gosaMailDeliveryMode'
+        DESC 'What to do with mails'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.13 NAME 'gosaDefaultPrinter'
+        DESC 'Defines a default printer a user owns'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.14 NAME 'gosaDefaultLanguage'
+        DESC 'Defines the default language for a user'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.15 NAME 'gosaHostACL'
+        DESC 'Defines the places where users can login'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.16 NAME 'gosaService'
+        DESC 'Defines services a certain host can provide'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.17 NAME 'gosaProxyID'
+        DESC 'Defines the proxy user id used, needed for some filters'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.18 NAME 'gosaProxyAcctFlags'
+        DESC 'Proxy Account Flags'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.19 NAME 'gosaProxyWorkingStart'
+        DESC 'Specifies the beginning of work in minutes, relative to 00:00'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.20 NAME 'gosaProxyWorkingStop'
+        DESC 'Specifies the end of work in minutes, relative to 00:00'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.21 NAME 'gosaApplicationName'
+        DESC 'Specifies the name of an application to be shown up on users desktop'
+        EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.22 NAME 'gosaApplicationExecute'
+        DESC 'Specifies the executable path of an application'
+        EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.23 NAME 'gosaApplicationFlags'
+        DESC 'Specifies the application flags G(roup only), D(esktop), M(enu)'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.31 NAME 'gosaApplicationCategory'
+       DESC 'Store application parameters'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.24 NAME 'gosaApplicationIcon'
+        DESC 'Keeps the application icon in png format'
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.28)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.25 NAME 'gosaSharedFolderTarget'
+        DESC 'Keeps the target of cyrus shared folders'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.26 NAME 'gosaMemberApplication'
+        DESC 'Like memberUid, just for applications'
+        EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.27 NAME 'gosaApplicationParameter'
+        DESC 'Store application parameters'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.28 NAME 'gosaProxyQuota'
+        DESC 'Specifies the amount of data a user may surf in a defined period of time'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.29 NAME 'gosaProxyQuotaPeriod'
+        DESC 'Specifies period of time where the counter is been reseted'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.30 NAME 'gosaGroupObjects'
+        DESC 'Takes a list of all object types that are in a gosaGroupOfNames'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.32 NAME 'gosaApplicationMimeType'
+       DESC 'Takes a list of relevant mime-type|priority settings'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.33 NAME 'gosaUnitTag'
+        DESC 'Takes a list of relevant mime-type|priority settings'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.34 NAME 'gosaAclTemplate'
+        DESC 'Takes ACL entries for gosaRoles'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.35 NAME 'gosaAclEntry'
+        DESC 'Takes ACL entries for gosaRoles'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.36 NAME 'gosaSnapshotType'
+        DESC 'Takes either undo or snapshot'
+        EQUALITY caseIgnoreMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.37 NAME 'gosaSnapshotTimestamp'
+        DESC 'Unix timestamp of snapshot'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.38 NAME 'gosaSnapshotDN'
+        DESC 'Original DN of saved object'
+        EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.39 NAME 'gosaSnapshotData'
+        DESC 'Original DN of saved object'
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.40 NAME 'gosaSetting'
+        DESC 'Original DN of saved object'
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.41 NAME 'gosaVacationStart'
+        DESC 'Timestamp for enabling current vacation message'
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.42 NAME 'gosaVacationStop'
+        DESC 'Timestamp for switching off current vacation message'
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.6.2 NAME 'academicTitle'
+        DESC 'Field to represent the academic title'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.15305.2.1 NAME ( 'gender' 'sex' )
+        DESC    'Gender: M for male, F for female'
+        EQUALITY caseIgnoreIA5Match
+        SYNTAX  1.3.6.1.4.1.1466.115.121.1.26{1}
+        SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.15305.2.2 NAME ( 'dateOfBirth' 'dob' )
+        DESC    'Date of birth in ISO 8601 format'
+        EQUALITY caseIgnoreMatch
+        SYNTAX  1.3.6.1.4.1.1466.115.121.1.15{10}
+        SINGLE-VALUE )
+
+# cyrus imapd access control list
+# acls work with users and groups
+attributetype ( 1.3.6.1.4.1.19414.2.1.651
+               NAME 'acl'
+               EQUALITY caseIgnoreIA5Match
+               SUBSTR caseIgnoreIA5SubstringsMatch
+           SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# Objectclasses
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.1 NAME 'gosaObject' SUP top AUXILIARY
+        DESC 'Objectclass for GOsa settings (v2.4)'
+        MUST ( gosaSubtreeACL ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.2 NAME 'gosaLockEntry' SUP top STRUCTURAL
+        DESC 'Objectclass for GOsa locking (v2.4)'
+        MUST ( gosaUser $ gosaObject $ cn ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.3 NAME 'gosaCacheEntry' SUP top STRUCTURAL
+        DESC 'Objectclass for GOsa caching (v2.4)'
+       MAY  ( gosaUser )
+       MUST ( cn ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.4 NAME 'gosaDepartment' SUP top AUXILIARY
+        DESC 'Objectclass to mark Departments for GOsa (v2.4)'
+       MUST  ( ou $ description ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.5 NAME 'gosaMailAccount' SUP top AUXILIARY
+        DESC 'Objectclass to mark MailAccounts for GOsa (v2.4)'
+       MUST ( mail $ gosaMailServer $ gosaMailDeliveryMode)
+       MAY  ( gosaMailQuota $ gosaMailAlternateAddress $ gosaMailForwardingAddress $
+              gosaMailMaxSize $ gosaSpamSortLevel $ gosaSpamMailbox $
+              gosaVacationMessage $ gosaVacationStart $ gosaVacationStop $ gosaSharedFolderTarget $ acl))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.6 NAME 'gosaAccount' SUP top AUXILIARY
+        DESC 'Objectclass for GOsa Accounts (v2.4)'
+       MUST ( uid )
+        MAY ( sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ gosaDefaultPrinter $
+             gosaDefaultLanguage $ academicTitle $ personalTitle $ gosaHostACL $ dateOfBirth $
+                 sambaBadPasswordCount $ sambaBadPasswordTime $ gender ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.7 NAME 'gosaHost' SUP top AUXILIARY
+        DESC 'Objectclass for GOsa Hosts (v2.4)'
+        MUST ( cn )
+        MAY ( description $ gosaService ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.8 NAME 'gosaProxyAccount' SUP top AUXILIARY
+        DESC 'Objectclass for GOsa Proxy settings (v2.4)'
+        MUST ( gosaProxyAcctFlags )
+        MAY ( gosaProxyID $ gosaProxyWorkingStart $ gosaProxyWorkingStop $ gosaProxyQuota $
+              gosaProxyQuotaPeriod ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.9 NAME 'gosaApplication' SUP top STRUCTURAL
+        DESC 'Objectclass for GOsa applications (v2.4)'
+        MUST ( cn $ gosaApplicationExecute )
+        MAY ( gosaApplicationName $ gosaApplicationIcon $ gosaApplicationFlags $ gosaApplicationMimeType $
+              gosaApplicationParameter $ gotoLogonScript $ description $ gosaApplicationCategory ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.10 NAME 'gosaApplicationGroup' SUP top AUXILIARY
+        DESC 'Objectclass for GOsa application groups (v2.4)'
+        MUST ( cn )
+        MAY ( gosaMemberApplication $ gosaApplicationParameter ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.11 NAME 'gosaUserTemplate' SUP top AUXILIARY
+        DESC 'Objectclass for GOsa User Templates (v2.4)'
+        MUST ( cn ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.12 NAME 'gosaGroupOfNames'
+        DESC 'GOsa object grouping (v2.4)'
+               SUP top STRUCTURAL
+               MUST ( cn $ gosaGroupObjects ) MAY ( member $ description ) )
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.13 NAME 'gosaWebdavAccount'
+        DESC 'GOsa webdav enabling account (v2.4)'
+        SUP top AUXILIARY
+        MUST ( cn $ uid ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.14 NAME 'gosaIntranetAccount'
+               DESC 'GOsa Inatrent enabling account (v2.4)'
+               SUP top AUXILIARY
+               MUST ( cn $ uid )
+               MAY ( gosaDefaultLanguage ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.15 NAME 'gosaAdministrativeUnit'
+       DESC 'Marker for administrational units (v2.5)'
+           SUP top AUXILIARY
+       MUST ( gosaUnitTag ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.16 NAME 'gosaAdministrativeUnitTag'
+       DESC 'Marker for objects below administrational units (v2.5)'
+           SUP top AUXILIARY
+       MUST ( gosaUnitTag ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.17 NAME 'gosaRole'
+       DESC 'ACL container to define roles (v2.5)' SUP top STRUCTURAL
+       MUST ( gosaAclTemplate $ cn )
+       MAY  ( description ) )
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.18 NAME 'gosaAcl'
+       DESC 'ACL container to define single ACLs (v2.5)' SUP top AUXILIARY
+       MUST ( gosaAclEntry  ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.19 NAME 'gosaSnapshotObject'
+       DESC 'Container object for undo and snapshot data (v2.5)' SUP top STRUCTURAL
+       MUST ( gosaSnapshotType $ gosaSnapshotTimestamp $ gosaSnapshotDN $ gosaSnapshotData )
+       MAY  ( description ) )
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.20 NAME 'gosaConfig'
+       DESC 'Settings for gosa. Replaces parts of the gosa.conf. (v2.6)' SUP top STRUCTURAL
+       MAY  ( gosaSetting ) )
+
diff --git a/gosa-core/contrib/openldap/gosa.schema b/gosa-core/contrib/openldap/gosa.schema
new file mode 100644 (file)
index 0000000..a11a4c5
--- /dev/null
@@ -0,0 +1,376 @@
+##
+## Needed attributes for GOsa (GONICUS System Administrator)
+##
+## Maintainer: Cajus Pollmeier (pollmeier@GONICUS.de)
+##
+
+
+# Attributes
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.1 NAME 'gosaSubtreeACL'
+        DESC 'GOsa acl entry'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.2 NAME 'gosaUser'
+        DESC 'GOsa user'
+        EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.3 NAME 'gosaObject'
+        DESC 'GOsa object'
+        EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.4 NAME 'gosaMailServer'
+        DESC 'Specify users main mail server'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.5 NAME 'gosaMailQuota'
+        DESC 'GOsa quota definitions'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.6 NAME 'gosaMailAlternateAddress'
+        DESC 'Additional mail addresses where the user is reachable'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.7 NAME 'gosaMailForwardingAddress'
+        DESC 'Addresses where to forward mail to'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.8 NAME 'gosaMailMaxSize'
+        DESC 'Block mails bigger than this value'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.9 NAME 'gosaSpamSortLevel'
+        DESC 'Spamassassins hits'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.10 NAME 'gosaSpamMailbox'
+        DESC 'Where to put spam'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.11 NAME 'gosaVacationMessage'
+        DESC 'Text to display in case of vacation'
+        EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.12 NAME 'gosaMailDeliveryMode'
+        DESC 'What to do with mails'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.13 NAME 'gosaDefaultPrinter'
+        DESC 'Defines a default printer a user owns'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.14 NAME 'gosaDefaultLanguage'
+        DESC 'Defines the default language for a user'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.15 NAME 'gosaHostACL'
+        DESC 'Defines the places where users can login'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.16 NAME 'gosaService'
+        DESC 'Defines services a certain host can provide'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.17 NAME 'gosaProxyID'
+        DESC 'Defines the proxy user id used, needed for some filters'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.18 NAME 'gosaProxyAcctFlags'
+        DESC 'Proxy Account Flags'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.19 NAME 'gosaProxyWorkingStart'
+        DESC 'Specifies the beginning of work in minutes, relative to 00:00'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.20 NAME 'gosaProxyWorkingStop'
+        DESC 'Specifies the end of work in minutes, relative to 00:00'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.21 NAME 'gosaApplicationName'
+        DESC 'Specifies the name of an application to be shown up on users desktop'
+        EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.22 NAME 'gosaApplicationExecute'
+        DESC 'Specifies the executable path of an application'
+        EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.23 NAME 'gosaApplicationFlags'
+        DESC 'Specifies the application flags G(roup only), D(esktop), M(enu)'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.24 NAME 'gosaApplicationIcon'
+        DESC 'Keeps the application icon in png format'
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.28)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.25 NAME 'gosaSharedFolderTarget'
+        DESC 'Keeps the target of cyrus shared folders'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.26 NAME 'gosaMemberApplication'
+        DESC 'Like memberUid, just for applications'
+        EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.27 NAME 'gosaApplicationParameter'
+        DESC 'Store application parameters'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.31 NAME 'gosaApplicationCategory'
+        DESC 'Store application parameters'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.28 NAME 'gosaProxyQuota'
+        DESC 'Specifies the amount of data a user may surf in a defined period of time'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.29 NAME 'gosaProxyQuotaPeriod'
+        DESC 'Specifies period of time where the counter is been reseted'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.30 NAME 'gosaGroupObjects'
+        DESC 'Takes a list of all object types that are in a gosaGroupOfNames'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.32 NAME 'gosaApplicationMimeType'
+        DESC 'Takes a list of relevant mime-type|priority settings'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.33 NAME 'gosaUnitTag'
+        DESC 'Takes a list of relevant mime-type|priority settings'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.34 NAME 'gosaAclTemplate'
+        DESC 'Takes ACL entries for gosaRoles'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.35 NAME 'gosaAclEntry'
+        DESC 'Takes ACL entries for gosaRoles'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.36 NAME 'gosaSnapshotType'
+        DESC 'Takes either undo or snapshot'
+        EQUALITY caseIgnoreMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.37 NAME 'gosaSnapshotTimestamp'
+        DESC 'Unix timestamp of snapshot'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.38 NAME 'gosaSnapshotDN'
+        DESC 'Original DN of saved object'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.39 NAME 'gosaSnapshotData'
+        DESC 'Original DN of saved object'
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.40 NAME 'gosaSetting'
+        DESC 'Original DN of saved object'
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.41 NAME 'gosaVacationStart'
+        DESC 'Timestamp for enabling current vacation message'
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.12.42 NAME 'gosaVacationStop'
+        DESC 'Timestamp for switching off current vacation message'
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.6.2 NAME 'academicTitle'
+        DESC 'Field to represent the academic title'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+attributetype ( 1.3.6.1.4.1.15305.2.1 NAME ( 'gender' 'sex' )
+       DESC    'Gender: M for male, F for female'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX  1.3.6.1.4.1.1466.115.121.1.26{1}
+       SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.15305.2.2 NAME ( 'dateOfBirth' 'dob' )
+       DESC    'Date of birth in ISO 8601 format'
+       EQUALITY caseIgnoreMatch
+       SYNTAX  1.3.6.1.4.1.1466.115.121.1.15{10}
+       SINGLE-VALUE )
+
+# cyrus imapd access control list
+# acls work with users and groups
+attributetype ( 1.3.6.1.4.1.19414.2.1.651
+       NAME 'acl'
+    EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# Objectclasses
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.1 NAME 'gosaObject' SUP top AUXILIARY
+        DESC 'Objectclass for GOsa settings (v2.4)'
+        MUST ( gosaSubtreeACL ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.2 NAME 'gosaLockEntry' SUP top STRUCTURAL
+        DESC 'Objectclass for GOsa locking (v2.4)'
+        MUST ( gosaUser $ gosaObject $ cn ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.3 NAME 'gosaCacheEntry' SUP top STRUCTURAL
+        DESC 'Objectclass for GOsa caching (v2.4)'
+       MAY  ( gosaUser )
+       MUST ( cn ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.4 NAME 'gosaDepartment' SUP top AUXILIARY
+        DESC 'Objectclass to mark Departments for GOsa (v2.4)'
+       MUST  ( ou $ description ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.5 NAME 'gosaMailAccount' SUP top AUXILIARY
+        DESC 'Objectclass to mark MailAccounts for GOsa (v2.4)'
+       MUST ( mail $ gosaMailServer $ gosaMailDeliveryMode)
+       MAY  ( gosaMailQuota $ gosaMailAlternateAddress $ gosaMailForwardingAddress $
+              gosaMailMaxSize $ gosaSpamSortLevel $ gosaSpamMailbox $
+              gosaVacationMessage $ gosaVacationStart $ gosaVacationStop $ gosaSharedFolderTarget $ acl))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.6 NAME 'gosaAccount' SUP top AUXILIARY
+        DESC 'Objectclass for GOsa Accounts (v2.4)'
+       MUST ( uid )
+        MAY ( lmPassword $ ntPassword $ pwdLastSet $ gosaDefaultPrinter $ gosaDefaultLanguage $
+              academicTitle $ personalTitle $ gosaHostACL $ dateOfBirth $ gender ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.7 NAME 'gosaHost' SUP top AUXILIARY
+        DESC 'Objectclass for GOsa Hosts (v2.4)'
+        MUST ( cn )
+        MAY ( description $ gosaService ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.8 NAME 'gosaProxyAccount' SUP top AUXILIARY
+        DESC 'Objectclass for GOsa Proxy settings (v2.4)'
+        MUST ( gosaProxyAcctFlags )
+        MAY ( gosaProxyID $ gosaProxyWorkingStart $ gosaProxyWorkingStop $ gosaProxyQuota $
+              gosaProxyQuotaPeriod ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.9 NAME 'gosaApplication' SUP top STRUCTURAL
+        DESC 'Objectclass for GOsa applications (v2.4)'
+        MUST ( cn $ gosaApplicationExecute )
+        MAY ( gosaApplicationName $ gosaApplicationIcon $ gosaApplicationFlags $ gosaApplicationMimeType $
+              gosaApplicationParameter $ gotoLogonScript $ description $ gosaApplicationCategory ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.10 NAME 'gosaApplicationGroup' SUP top AUXILIARY
+        DESC 'Objectclass for GOsa application groups (v2.4)'
+        MUST ( cn )
+        MAY ( gosaMemberApplication $ gosaApplicationParameter ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.11 NAME 'gosaUserTemplate' SUP top AUXILIARY
+        DESC 'Objectclass for GOsa User Templates (v2.4)'
+        MUST ( cn ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.12 NAME 'gosaGroupOfNames'
+        DESC 'GOsa object grouping (v2.4)'
+        SUP top STRUCTURAL
+               MUST ( cn $ gosaGroupObjects ) MAY ( description $ member ) )
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.13 NAME 'gosaWebdavAccount'
+        DESC 'GOsa webdav enabling account (v2.4)'
+        SUP top AUXILIARY
+        MUST ( cn $ uid ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.14 NAME 'gosaIntranetAccount'
+       DESC 'GOsa Intarent enabling account (v2.4)'
+          SUP top AUXILIARY
+       MUST ( cn $ uid )
+       MAY ( gosaDefaultLanguage ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.15 NAME 'gosaAdministrativeUnit'
+       DESC 'Marker for administrational units (v2.5)'
+          SUP top AUXILIARY
+       MUST ( gosaUnitTag ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.16 NAME 'gosaAdministrativeUnitTag'
+       DESC 'Marker for objects below administrational units (v2.5)'
+          SUP top AUXILIARY
+       MUST ( gosaUnitTag ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.17 NAME 'gosaRole'
+       DESC 'ACL container to define roles (v2.5)' SUP top STRUCTURAL
+       MUST ( gosaAclTemplate $ cn )
+       MAY  ( description ) )
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.18 NAME 'gosaAcl'
+       DESC 'ACL container to define single ACLs (v2.5)' SUP top AUXILIARY
+       MUST ( gosaAclEntry  ))
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.19 NAME 'gosaSnapshotObject'
+       DESC 'Container object for undo and snapshot data (v2.5)' SUP top STRUCTURAL
+       MUST ( gosaSnapshotType $ gosaSnapshotTimestamp $ gosaSnapshotDN $ gosaSnapshotData )
+       MAY  ( description ) )
+
+objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.20 NAME 'gosaConfig'
+       DESC 'Settings for gosa. Replaces parts of the gosa.conf. (v2.6)' SUP top STRUCTURAL
+       MAY  ( gosaSetting ) )
+
diff --git a/gosa-core/contrib/openldap/goserver.schema b/gosa-core/contrib/openldap/goserver.schema
new file mode 100644 (file)
index 0000000..97edc9d
--- /dev/null
@@ -0,0 +1,583 @@
+## 
+##
+## goserver.schema - Needed by the GONICUS System Administator
+##
+## Version 030403
+##
+##
+## Maintainer:         Lars Scheiter   (scheiter@GONICUS.de)
+##                     Cajus Pollmeier (pollmeier@GONICUS.de)
+##
+##
+
+
+# Attributes for the Gonicus Terminal Server Class
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.1 NAME 'goXdmcpIsEnabled'
+       DESC 'Indicates if the server is enabled for XDMCP queries'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.2 NAME 'goFontPath'
+       DESC 'Fontserver Entry'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+# Attributes for common Gonicus Server Class
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.4 NAME 'goExportEntry'
+       DESC 'Provides an export entry'
+       EQUALITY caseExactMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.9 NAME 'goSyslogSection'
+       DESC 'What sections wants the server for its syslog service? i.e. *.*'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.10 NAME 'goTimeSource'
+       DESC 'List of time sources'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.11 NAME 'goSpoolPath'
+       DESC 'Provides a spool path for printing services'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.12 NAME 'goLdapBase'
+       DESC 'Base to use for this LDAP server'
+       EQUALITY caseExactMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.13 NAME 'goImapName'
+       DESC 'Name of IMAP server appearing in GOsa'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.14 NAME 'goImapConnect'
+       DESC 'PHP connect string for IMAP server'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.15 NAME 'goImapAdmin'
+       DESC 'IMAP admin account'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.16 NAME 'goImapPassword'
+       DESC 'IMAP admin password'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.17 NAME 'goImapSieveServer'
+       DESC 'Cyrus sieve server address or name'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.18 NAME 'goImapSievePort'
+       DESC 'Cyrus sieve server port'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.19 NAME 'goKrbRealm'
+       DESC 'Default Kerberos realm to use for this server'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.20 NAME 'goKrbAdmin'
+       DESC 'Admin principal for kerberos server'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.21 NAME 'goKrbPassword'
+       DESC 'Admin password for kerberos server'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.22 NAME 'goFaxAdmin'
+       DESC 'Admin principal for fax server'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.23 NAME 'goFaxPassword'
+       DESC 'Admin password for fax server'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.24 NAME 'goLogAdmin'
+       DESC 'Admin principal for log server'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.25 NAME 'goLogPassword'
+       DESC 'Admin password for log server'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.26 NAME 'goFonAdmin'
+        DESC 'Admin principal for fon server'
+        EQUALITY caseExactIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.27 NAME 'goFonPassword'
+        DESC 'Admin password for fon server'
+        EQUALITY caseExactIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.28 NAME 'goFonAreaCode'
+        DESC 'Store area code'
+        EQUALITY caseExactIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.29 NAME 'goFonCountryCode'
+        DESC 'Store country code'
+        EQUALITY caseExactIA5Match
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.30 NAME 'goGlpiAdmin'
+       DESC 'Admin principal for glpi database server'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.31 NAME 'goGlpiPassword'
+       DESC 'Admin password for glpi database server'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.32 NAME 'goGlpiDatabase'
+       DESC 'Database name for glpi extension'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.33 NAME 'goTerminalServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.34 NAME 'goNfsServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.35 NAME 'goNtpServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.36 NAME 'goSyslogServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.37 NAME 'goLdapServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.38 NAME 'goImapServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.39 NAME 'goKrbServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.40 NAME 'goFaxServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.41 NAME 'goLogDBServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.42 NAME 'goFonServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.43 NAME 'goShareServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.44 NAME 'goMailServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.45 NAME 'goGlpiServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.46 NAME 'postfixHeaderSizeLimit'
+       DESC 'Keep postfix header-size-limit variable'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.47 NAME 'postfixMailboxSizeLimit'
+       DESC 'Keep postfix mailbox-size-limit variable'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.48 NAME 'postfixMessageSizeLimit'
+       DESC 'Keep postfix message-size-limit variable'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.49 NAME 'postfixMyDestinations'
+       DESC 'Keep postfix mydestinations variable'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.50 NAME 'postfixMyDomain'
+       DESC 'Keep postfix mydomain variable'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.51 NAME 'postfixMyHostname'
+       DESC 'Keep postfix myhostname variable'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.52 NAME 'postfixMyNetworks'
+       DESC 'Keep postfix mynetworks variable'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.53 NAME 'postfixRelayhost'
+       DESC 'Keep postfix relayhost variable'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.54 NAME 'postfixTransportTable'
+       DESC 'Keep postfix transport tables'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.55 NAME 'postfixSenderRestrictions'
+       DESC 'Keep postfix sender restrictions'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.56 NAME 'postfixRecipientRestrictions'
+       DESC 'Keep postfix transport tables'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.57 NAME 'cyrusImap'
+       DESC 'Start IMAP service? true/false'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.58 NAME 'cyrusImapSSL'
+       DESC 'Start IMAP SSL service? true/false'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.59 NAME 'cyrusPop3'
+       DESC 'Start POP3 service? true/false'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.60 NAME 'cyrusPop3SSL'
+       DESC 'Start POP3 SSL service? true/false'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.61 NAME 'goCupsServerStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.62 NAME 'saRewriteHeader'
+       DESC 'Text to place in front of mail subjects'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.63 NAME 'saTrustedNetworks'
+       DESC 'List of trusted networks'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.64 NAME 'saRequiredScore'
+       DESC 'Required score to tag a mail as SPAM'
+       EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
+
+#saFlags   B:    Enable use of bayes filtering
+#          b:    Enable bayes auto learning
+#          C:    Enable RBL checks
+#          R:    Enable use of Razor
+#          D:    Enable use of DDC
+#          P:    Enable use of Pyzor
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.65 NAME 'saFlags'
+       DESC 'Flags for spamassassin'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.66 NAME 'saRule'
+       DESC 'Base64 encoded rule text for spamassassin'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.67 NAME 'saStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.68 NAME 'avMaxThreads'
+       DESC 'Number of AV scanning threads'
+       EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.69 NAME 'avMaxDirectoryRecursions'
+       DESC 'Number of recursions done with directories'
+       EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.70 NAME 'avUser'
+       DESC 'Username to run with'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# avFlags         D       Debug
+#                 S       Scan Mail
+#                 A       Scan Archive
+#                 E       Archive block encrypted
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.71 NAME 'avFlags'
+       DESC 'Special flags for the scan engine'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.72 NAME 'avArchiveMaxFileSize'
+       DESC 'Maximum archive file size'
+       EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.73 NAME 'avArchiveMaxRecursion'
+       DESC 'Maximum number of archive nestings'
+       EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.74 NAME 'avArchiveMaxCompressionRatio'
+       DESC 'Maximum compression ratio'
+       EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.75 NAME 'avDatabaseMirror'
+       DESC 'Where to find updates'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.76 NAME 'avHttpProxyURL'
+       DESC 'How to get the updates'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.77 NAME 'avStatus'
+       DESC 'Server status container - on / off / fail'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.78 NAME 'avChecksPerDay'
+        DESC 'Update checks per day'
+        EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.79 NAME 'goLogDB'
+       DESC 'Name of logging DB'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.80 NAME 'goLogDBUser'
+       DESC 'Auth user for logging DB'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.9.81 NAME 'goLogDBPassword'
+       DESC 'Password for logging DB user'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+
+##
+##             Objectclasses
+##
+
+# Terminal Server description 
+objectclass (1.3.6.1.4.1.10098.1.2.1.16 NAME 'goTerminalServer' SUP top AUXILIARY
+       DESC 'Terminal server description (v2.4)'
+       MUST ( cn $ goXdmcpIsEnabled $ goFontPath )
+       MAY  ( description $ goTerminalServerStatus ))
+
+# NFS Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.19 NAME 'goNfsServer' SUP top AUXILIARY
+       DESC 'NFS server description (v2.4)'
+       MUST ( cn )
+       MAY  ( goExportEntry $ description $ goNfsServerStatus ))
+
+# Time Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.20 NAME 'goNtpServer' SUP top AUXILIARY
+       DESC 'Time server description (v2.4)'
+       MUST ( cn )
+        MAY  ( goTimeSource $ description $ goNtpServerStatus ))
+
+# Syslog Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.21 NAME 'goSyslogServer' SUP top AUXILIARY
+       DESC 'Syslog server description (v2.4)'
+       MUST ( cn )
+       MAY  ( goSyslogSection $ description $ goSyslogServerStatus ))
+
+# LDAP Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.22 NAME 'goLdapServer' SUP top AUXILIARY
+       DESC 'LDAP server description (v2.4)'
+       MUST ( cn )
+       MAY  ( goLdapBase $ description $ goLdapServerStatus ))
+
+# CUPS Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.23 NAME 'goCupsServer' SUP top AUXILIARY
+       DESC 'CUPS server description (v2.4)'
+       MUST ( cn )
+       MAY  ( description $ goCupsServerStatus ))
+
+# IMAP Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.24 NAME 'goImapServer' SUP top AUXILIARY
+       DESC 'IMAP server description (v2.4)'
+       MUST ( cn $ goImapName $ goImapConnect $ goImapAdmin $ goImapPassword )
+       MAY  ( goImapSieveServer $ goImapSievePort $ description $ goImapServerStatus $
+              cyrusImap $ cyrusImapSSL $ cyrusPop3 $ cyrusPop3SSL ))
+
+# Kerberos Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.25 NAME 'goKrbServer' SUP top AUXILIARY
+       DESC 'Kerberos server description (v2.4)'
+       MUST ( cn $ goKrbRealm $ goKrbAdmin $ goKrbPassword )
+       MAY  ( description $ goKrbServerStatus ))
+
+# Fax Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.26 NAME 'goFaxServer' SUP top AUXILIARY
+       DESC 'Fax server description (v2.4)'
+       MUST ( cn $ goFaxAdmin $ goFaxPassword )
+       MAY  ( description $ goFaxServerStatus ))
+
+# Common server class
+objectclass (1.3.6.1.4.1.10098.1.2.1.27 NAME 'goServer' SUP top AUXILIARY
+       DESC 'Server description (v2.4)'
+       MUST ( cn )
+       MAY  ( description $ macAddress $ ipHostNumber ))
+
+# LogDB Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.28 NAME 'goLogDBServer' SUP top AUXILIARY
+       DESC 'Log DB server description (v2.4)'
+       MUST ( cn $ goLogAdmin $ goLogPassword )
+       MAY  ( goLogDBServerStatus ))
+
+# Fon Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.29 NAME 'goFonServer' SUP top AUXILIARY
+        DESC 'Fon server description (v2.4)'
+        MUST ( cn $ goFonAdmin $ goFonPassword $ goFonAreaCode $ goFonCountryCode )
+        MAY  ( description $ goFonServerStatus ))
+
+# Share Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.33 NAME 'goShareServer' SUP top AUXILIARY
+       DESC 'Share server description (v2.4)'
+       MUST ( cn )
+       MAY  ( description $ goExportEntry $ goShareServerStatus ))
+
+# Mail Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.36 NAME 'goMailServer' SUP top AUXILIARY
+       DESC 'Mail server definition (v2.4)'
+       MUST ( cn )
+       MAY  ( description $ goMailServerStatus $ postfixHeaderSizeLimit $
+              postfixMailboxSizeLimit $ postfixMessageSizeLimit $
+              postfixMydestinations $ postfixMydomain $ postfixMyhostname $
+              postfixMynetworks $ postfixRelayhost $ postfixTransportTable $
+              postfixSenderRestrictions $ postfixRecipientRestrictions ) )
+
+# Glpi Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.37 NAME 'goGlpiServer' SUP top AUXILIARY
+       DESC 'Glpi server definition (v2.4)'
+       MUST ( cn $ goGlpiAdmin $ goGlpiDatabase)
+       MAY  ( description $ goGlpiPassword $ goGlpiServerStatus ) )
+
+# Spamassassin definitions
+objectclass (1.3.6.1.4.1.10098.1.2.1.38 NAME 'goSpamServer' SUP top AUXILIARY
+       DESC 'Spam server definition (v2.5)'
+       MUST ( cn )
+       MAY  ( saRewriteHeader $ saTrustedNetworks $ saRequiredScore $ saFlags $
+              saRule $ saStatus ) )
+
+# Clamav definitions
+objectclass (1.3.6.1.4.1.10098.1.2.1.39 NAME 'goVirusServer' SUP top AUXILIARY
+       DESC 'Virus server definition (v2.5)'
+       MUST ( cn )
+       MAY  ( avMaxThreads $ avMaxDirectoryRecursions $ avUser $ avFlags $
+               avArchiveMaxFileSize $ avArchiveMaxRecursion $ avArchiveMaxCompressionRatio $
+               avDatabaseMirror $ avChecksPerDay $ avHttpProxyURL ) )
+
+# LogDB Server description
+objectclass (1.3.6.1.4.1.10098.1.2.1.40 NAME 'gosaLogServer' SUP top AUXILIARY
+       DESC 'GOsa log server (v2.6)'
+       MUST ( cn $ goLogDB $ goLogDBUser $ goLogDBPassword ))
+
+# Environment Server
+objectclass (1.3.6.1.4.1.10098.1.2.1.41 NAME 'goEnvironmentServer' SUP top AUXILIARY
+       DESC 'Environment server definition (v2.6)'
+       MUST ( cn )
+       MAY  ( gotoKioskProfile ) )
+
diff --git a/gosa-core/contrib/openldap/gosystem.schema b/gosa-core/contrib/openldap/gosystem.schema
new file mode 100644 (file)
index 0000000..b25e61d
--- /dev/null
@@ -0,0 +1,340 @@
+##
+## gosystem.schema - Needed by the GONICUS Terminal concept
+##
+
+# Attributes
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.1 NAME 'gotoSyslogServer'
+       DESC 'GOto - Gonicus Terminal Concept, value syslogServer.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.2 NAME 'gotoNtpServer'
+       DESC 'GOto - Gonicus Terminal Concept, value ntpServer.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.3 NAME 'gotoSwapServer'
+       DESC 'GOto - Gonicus Terminal Concept, value swapServer.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.4 NAME 'gotoLpdServer'
+       DESC 'GOto - Gonicus Terminal Concept, value lpdServer.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.5 NAME 'gotoFontPath'
+       DESC 'GOto - Gonicus Terminal Concept, value fontPath.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.6 NAME 'gotoFilesystem'
+       DESC 'GOto - Gonicus Terminal Concept, value filesystem.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.7 NAME 'gotoFloppyEnable'
+       DESC 'GOto - Gonicus Terminal Concept, value floppyEnable.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.8 NAME 'gotoCdromEnable'
+       DESC 'GOto - Gonicus Terminal Concept, value cdromEnable.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.9 NAME 'gotoLpdEnable'
+       DESC 'GOto - Gonicus Terminal Concept, value lpdEnable.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.10 NAME 'gotoScannerEnable'
+       DESC 'GOto - Gonicus Terminal Concept, value scannerEnable.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.11 NAME 'gotoScannerClients'
+       DESC 'GOto - Gonicus Terminal Concept, value scannerClients.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.14 NAME 'gotoRootPasswd'
+       DESC 'GOto - Gonicus Terminal Concept, value rootPasswd.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.15 NAME 'gotoXdmcpServer'
+       DESC 'GOto - Gonicus Terminal Concept, value xdmcpServer.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.16 NAME 'gotoXMethod'
+       DESC 'GOto - Gonicus Terminal Concept, value xMethod.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.17 NAME 'gotoXMonitor'
+       DESC 'GOto - Gonicus Terminal Concept, value xMonitor.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.18 NAME 'gotoXHsync'
+       DESC 'GOto - Gonicus Terminal Concept, value xHsync.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.19 NAME 'gotoXVsync'
+       DESC 'GOto - Gonicus Terminal Concept, value xVsync.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.20 NAME 'gotoXResolution'
+       DESC 'GOto - Gonicus Terminal Concept, value xResolution.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.21 NAME 'gotoXColordepth'
+       DESC 'GOto - Gonicus Terminal Concept, value xColordepth.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.22 NAME 'gotoXMouseport'
+       DESC 'GOto - Gonicus Terminal Concept, value xMouseport.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.23 NAME 'gotoXMouseButtons'
+       DESC 'GOto - Gonicus Terminal Concept, value xMouseButtons.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.24 NAME 'gotoMode'
+       DESC 'GOto - Gonicus Terminal Concept, Terminal is active.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.25 NAME 'gotoXKbModel'
+       DESC 'GOto - Gonicus Terminal Concept, value xKbmodel.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.26 NAME 'gotoXKbLayout'
+       DESC 'GOto - Gonicus Terminal Concept, value xKblayout.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.27 NAME 'gotoXKbVariant'
+       DESC 'GOto - Gonicus Terminal Concept, value xKbvariant.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.28 NAME 'gotoXDriver'
+       DESC 'GOto - Gonicus Terminal Concept, value xDriver.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.29 NAME 'gotoSndModule'
+       DESC 'GOto - Gonicus Terminal Concept, value sndModules.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.30 NAME 'gotoLastUser'
+       DESC 'GOto - Gonicus Terminal Concept, value lastUser.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.31 NAME 'gotoAutoFs'
+       DESC 'GOto - Gonicus Terminal Concept, value autofs.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+       
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.32 NAME 'gotoModules'
+       DESC 'GOto - Gonicus Terminal Concept, value modules.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.33 NAME 'gotoAdaptPath'
+       DESC 'GOto - Gonicus Terminal Concept, value adaptpath.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.34 NAME 'gotoXMouseType'
+        DESC 'Hardware definitions, value Maustyp'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.35 NAME 'gotoKernelParameters'
+        DESC 'Kernel boot parameters'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.36 NAME 'gotoBootKernel'
+        DESC 'Kernel boot parameters'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.37 NAME 'gotoTerminalPath'
+        DESC 'Kernel boot parameters'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+        SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.38 NAME 'gotoLdapServer'
+        DESC 'Kernel boot parameters'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.39 NAME 'gotoScannerBackend'
+       DESC 'GOto - Gonicus Terminal Concept, value scannerBackend.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.1.40 NAME 'gotoScannerModel'
+       DESC 'GOto - Gonicus Terminal Concept, value scannerModel.'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.2.1 NAME 'ghCpuType'
+       DESC 'Hardware definitions, value cpuType'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.2.2 NAME 'ghMemSize'
+       DESC 'Hardware definitions, value memSize'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.2.3 NAME 'ghUsbSupport'
+       DESC 'Hardware definitions, value usbSupport'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.2.4 NAME 'ghIdeDev'
+       DESC 'Hardware definitions, value ideDev'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.2.5 NAME 'ghScsiDev'
+       DESC 'Hardware definitions, value scsiDev'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.2.7 NAME 'ghSoundAdapter'
+       DESC 'Hardware definitions, value soundAdapter'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.2.8 NAME 'ghNetNic'
+       DESC 'Hardware definitions, value Network Device'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.2.9 NAME 'ghGfxAdapter'
+       DESC 'Hardware definitions, value Grafikkarte'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.2.10 NAME 'ghInventoryNumber'
+       DESC 'Unique number for inclusion in an inventory'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE)
+
+
+# objectclass for Hardware definitions
+objectclass (1.3.6.1.4.1.10098.1.2.1.3 NAME 'GOhard'
+        DESC 'Gonicus Hardware definitions, objectclass (v2.5)' SUP top STRUCTURAL
+        MUST ( cn )
+        MAY ( ghGfxAdapter $ ghNetNic $ ghSoundAdapter $ ghIdeDev $ ghScsiDev $
+              macAddress $ ghUsbSupport $ ghMemSize $ ghCpuType $ ghInventoryNumber $
+              gotoSyslogServer $ gotoNtpServer $ gotoSwapServer $ gotoLpdServer $
+              gotoFontPath $ gotoFilesystem $ gotoFloppyEnable $ gotoCdromEnable $
+              gotoLpdEnable $ gotoScannerEnable $ gotoScannerClients $
+              gotoRootPasswd $ gotoXdmcpServer $ gotoXMethod $ gotoSndModule $
+              gotoLastUser $ gotoXMonitor $ gotoXHsync $ gotoXVsync $ gotoXResolution $
+              gotoXColordepth $ gotoXMouseport $ gotoXMouseButtons $ gotoMode $ gotoXKbModel $
+              gotoXKbLayout $ gotoXKbVariant $ gotoXDriver $ gotoXMouseType $ macAddress $
+              gotoAutoFs $ gotoModules $ gotoAdaptPath $ gotoKernelParameters $ gotoBootKernel $
+              gotoTerminalPath $ gotoLdapServer $ gotoScannerModel $ ipHostNumber $ l $ description ) )
+
diff --git a/gosa-core/contrib/openldap/goto-mime.schema b/gosa-core/contrib/openldap/goto-mime.schema
new file mode 100644 (file)
index 0000000..eef9dbf
--- /dev/null
@@ -0,0 +1,61 @@
+##
+## goto-mime.schema - Needed by the GONICUS Terminal concept
+##
+## Maintainer: Cajus Pollmeier (pollmeier@GONICUS.de)
+##
+
+# Basic list of mime groups:
+#   application audio chemical image inode message model multipart
+#   text video x-conference x-world
+attributetype ( 1.3.6.1.4.1.10098.1.1.14.1 NAME 'gotoMimeGroup'
+        DESC 'IANA defined mime group'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# File extensions without search patterns. i.e. png, jpg, xcf
+attributetype ( 1.3.6.1.4.1.10098.1.1.14.2 NAME 'gotoMimeFilePattern'
+        DESC 'File extensions for mime types'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+# Coded application and priority seperated by |. i.e. /usr/bin/gimp|1
+attributetype ( 1.3.6.1.4.1.10098.1.1.14.3 NAME 'gotoMimeApplication'
+        DESC 'Assigned application and priority'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+# Coded application and priority seperated by |.
+# i.e. cn=gimp,ou=apps,dc=gonicus,dc=de|1
+attributetype ( 1.3.6.1.4.1.10098.1.1.14.4 NAME 'gotoMimeEmbeddedApplication'
+        DESC 'Assigned application and priority for embedded applications'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+# Encoded left click action for filebrowsers, etc. This can be either:
+#  I: show in embedded viewer
+#  E: show in external viewer
+#  O: take settings from global mime group
+#  These fields are taken as OR. Additionally you can add a
+#  Q: to ask wether a question should pop up - to save it to
+#     the local disc or not.
+attributetype ( 1.3.6.1.4.1.10098.1.1.14.5 NAME 'gotoMimeLeftClickAction'
+        DESC 'GOto - Gonicus Terminal Concept, PPD data'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+# Save binary png icon here
+attributetype ( 1.3.6.1.4.1.10098.1.1.14.6 NAME 'gotoMimeIcon'
+        DESC 'Specify the mime icon'
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.28 SINGLE-VALUE)
+
+objectclass (1.3.6.1.4.1.10098.1.2.4.1 NAME 'gotoMimeType'
+        DESC 'Class to represent global mime types (v2.5)' SUP top STRUCTURAL
+        MUST ( cn $ gotoMimeFilePattern $ gotoMimeGroup )
+        MAY  ( description $ gotoMimeIcon $ gotoMimeApplication $
+              gotoMimeEmbeddedApplication $ gotoMimeLeftClickAction ))
+
diff --git a/gosa-core/contrib/openldap/goto.schema b/gosa-core/contrib/openldap/goto.schema
new file mode 100644 (file)
index 0000000..2840c4e
--- /dev/null
@@ -0,0 +1,154 @@
+## 
+##
+## goto.schema - Needed by the GONICUS Terminal concept
+##
+## Version 030403
+##
+##
+## Maintainer:         Lars Scheiter   (scheiter@GONICUS.de)
+##                     Cajus Pollmeier (pollmeier@GONICUS.de)
+##
+##
+## Requires: gohard.schema
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.11.6 NAME 'gotoPrinterPPD'
+        DESC 'GOto - Gonicus Terminal Concept, PPD data'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.11.7 NAME 'gotoProfileFlags'
+        DESC 'GOto - Flags for Profile handling - C is for caching'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.11.8 NAME 'gotoProfileServer'
+        DESC 'GOto - specifies the profile server'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.11.9 NAME 'gotoShare'
+        DESC 'GOto - specifies a share'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.11.10 NAME 'gotoLogonScript'
+        DESC 'GOto - specifies a LogonScript'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.11.11 NAME 'gotoKioskProfile'
+        DESC 'GOto - specifies a kiosk profile'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.11.12 NAME 'gotoUserPrinter'
+        DESC 'GOto - keeps printers shown for this user'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.11.13 NAME 'gotoUserAdminPrinter'
+        DESC 'GOto - keeps printers we are admin for'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.11.16 NAME 'gotoGroupPrinter'
+        DESC 'GOto - keeps printers shown for this user'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.11.17 NAME 'gotoGroupAdminPrinter'
+        DESC 'GOto - keeps printers we are admin for'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.11.14 NAME 'gotoHotplugDevice'
+        DESC 'GOto - keeps hotplug devices'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.11.15 NAME 'gotoProfileQuota'
+        DESC 'GOto - save quota for home'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
+
+attributetype ( 1.3.6.1.4.1.10098.1.1.11.18 NAME 'gotoHotplugDeviceDN'
+        DESC 'GOto - points to hotplug devices'
+       EQUALITY distinguishedNameMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12)
+
+objectclass (1.3.6.1.4.1.10098.1.2.1.1 NAME 'gotoTerminal'
+        DESC 'GOto - Gonicus Terminal Concept, objectclass (v2.5)' SUP top AUXILIARY
+        MUST ( cn )
+        MAY  ( description $ macAddress $ ipHostNumber $ gotoShare $ goFonHardware ))
+
+# objectclass for the Terminal Conecept
+objectclass (1.3.6.1.4.1.10098.1.2.1.30 NAME 'gotoWorkstation'
+        DESC 'GOto - Gonicus Terminal Concept, objectclass (v2.5)' SUP top AUXILIARY
+        MUST ( cn )
+        MAY  ( description $ macAddress $ ipHostNumber $ gotoShare $ goFonHardware ))
+
+# objectclass for the Terminal Conecept
+objectclass (1.3.6.1.4.1.10098.1.2.1.31 NAME 'gotoPrinter'
+       DESC 'GOto - Gonicus Terminal Concept, objectclass (v2.2)' SUP top STRUCTURAL
+       MUST ( cn )
+       MAY ( labeledURI $ description $ l $ gotoPrinterPPD $ macAddress $ ipHostNumber $ gotoUserPrinter $
+                 gotoUserAdminPrinter $ gotoGroupPrinter $ gotoGroupAdminPrinter ) )
+
+# objectclass for the Terminal Conecept
+objectclass (1.3.6.1.4.1.10098.1.2.1.32 NAME 'gotoEnvironment'
+       DESC 'GOto - contains environment settings (v2.2)' SUP top AUXILIARY
+       MAY ( gotoProfileServer $ gotoProfileFlags $ gotoXResolution $ gotoShare $ gotoLogonScript $
+                 gotoKioskProfile $ gotoHotplugDevice $ gotoProfileQuota $ gotoHotplugDeviceDN ) )
+
+# objectclass for the Terminal Conecept
+objectclass (1.3.6.1.4.1.10098.1.2.1.34 NAME 'gotoWorkstationTemplate'
+        DESC 'GOto - Gonicus Terminal Concept, objectclass (v2.5)' SUP top AUXILIARY
+        MUST ( cn )
+        MAY  ( description $ gotoShare $ goFonHardware $
+              ghGfxAdapter $ ghNetNic $ ghSoundAdapter $ ghIdeDev $ ghScsiDev $
+              ghUsbSupport $ ghMemSize $ ghCpuType $ ghInventoryNumber $
+              gotoSyslogServer $ gotoNtpServer $ gotoSwapServer $ gotoLpdServer $
+              gotoFontPath $ gotoFilesystem $ gotoFloppyEnable $ gotoCdromEnable $
+              gotoLpdEnable $ gotoScannerEnable $ gotoScannerClients $
+              gotoRootPasswd $ gotoXdmcpServer $ gotoXMethod $ gotoSndModule $
+              gotoLastUser $ gotoXMonitor $ gotoXHsync $ gotoXVsync $ gotoXResolution $
+              gotoXColordepth $ gotoXMouseport $ gotoXMouseButtons $ gotoMode $ gotoXKbModel $
+              gotoXKbLayout $ gotoXKbVariant $ gotoXDriver $ gotoXMouseType $ macAddress $
+              gotoAutoFs $ gotoModules $ gotoAdaptPath $ gotoKernelParameters $ gotoBootKernel $
+              gotoTerminalPath $ gotoLdapServer $ gotoScannerModel ))
+
+# objectclass for the Terminal Conecept
+objectclass (1.3.6.1.4.1.10098.1.2.1.35 NAME 'gotoTerminalTemplate'
+        DESC 'GOto - Gonicus Terminal Concept, objectclass (v2.5)' SUP top AUXILIARY
+        MUST ( cn )
+        MAY  ( description $ gotoShare $ goFonHardware $
+              ghGfxAdapter $ ghNetNic $ ghSoundAdapter $ ghIdeDev $ ghScsiDev $
+              ghUsbSupport $ ghMemSize $ ghCpuType $ ghInventoryNumber $
+              gotoSyslogServer $ gotoNtpServer $ gotoSwapServer $ gotoLpdServer $
+              gotoFontPath $ gotoFilesystem $ gotoFloppyEnable $ gotoCdromEnable $
+              gotoLpdEnable $ gotoScannerEnable $ gotoScannerClients $
+              gotoRootPasswd $ gotoXdmcpServer $ gotoXMethod $ gotoSndModule $
+              gotoLastUser $ gotoXMonitor $ gotoXHsync $ gotoXVsync $ gotoXResolution $
+              gotoXColordepth $ gotoXMouseport $ gotoXMouseButtons $ gotoMode $ gotoXKbModel $
+              gotoXKbLayout $ gotoXKbVariant $ gotoXDriver $ gotoXMouseType $ macAddress $
+              gotoAutoFs $ gotoModules $ gotoAdaptPath $ gotoKernelParameters $ gotoBootKernel $
+              gotoTerminalPath $ gotoLdapServer $ gotoScannerModel ))
+
+# objectclass for the Terminal Conecept
+objectclass (1.3.6.1.4.1.10098.1.2.1.42 NAME 'gotoDevice'
+       DESC 'GOto - contains environment settings (v2.2)' SUP top STRUCTURAL
+  MUST ( cn )
+       MAY ( gotoHotplugDevice ) )
+
diff --git a/gosa-core/contrib/openldap/hdb.schema b/gosa-core/contrib/openldap/hdb.schema
new file mode 100644 (file)
index 0000000..6e5c0f7
--- /dev/null
@@ -0,0 +1,139 @@
+# Definitions for a Kerberos V KDC schema
+#
+# $Id: hdb.schema 14958 2005-04-25 17:33:40Z lha $
+#
+# This version is compatible with OpenLDAP 1.8
+#
+# OID Base is iso(1) org(3) dod(6) internet(1) private(4) enterprise(1) padl(5322) kdcSchema(10)
+#
+# Syntaxes are under 1.3.6.1.4.1.5322.10.0
+# Attributes types are under 1.3.6.1.4.1.5322.10.1
+# Object classes are under 1.3.6.1.4.1.5322.10.2
+
+# Syntax definitions
+
+#krb5KDCFlagsSyntax SYNTAX ::= {
+#   WITH SYNTAX            INTEGER
+#--        initial(0),             -- require as-req
+#--        forwardable(1),         -- may issue forwardable
+#--        proxiable(2),           -- may issue proxiable
+#--        renewable(3),           -- may issue renewable
+#--        postdate(4),            -- may issue postdatable
+#--        server(5),              -- may be server
+#--        client(6),              -- may be client
+#--        invalid(7),             -- entry is invalid
+#--        require-preauth(8),     -- must use preauth
+#--        change-pw(9),           -- change password service
+#--        require-hwauth(10),     -- must use hwauth
+#--        ok-as-delegate(11),     -- as in TicketFlags
+#--        user-to-user(12),       -- may use user-to-user auth
+#--        immutable(13)           -- may not be deleted         
+#   ID                     { 1.3.6.1.4.1.5322.10.0.1 }
+#}
+
+#krb5PrincipalNameSyntax SYNTAX ::= {
+#   WITH SYNTAX            OCTET STRING
+#-- String representations of distinguished names as per RFC1510
+#   ID                     { 1.3.6.1.4.1.5322.10.0.2 }
+#}
+
+# Attribute type definitions
+attributetype ( 1.3.6.1.4.1.5322.10.1.1
+       NAME 'krb5PrincipalName'
+       DESC 'The unparsed Kerberos principal name'
+       EQUALITY caseExactIA5Match
+       SINGLE-VALUE
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.5322.10.1.2
+       NAME 'krb5KeyVersionNumber'
+       EQUALITY integerMatch
+       SINGLE-VALUE
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+attributetype ( 1.3.6.1.4.1.5322.10.1.3
+       NAME 'krb5MaxLife'
+       EQUALITY integerMatch
+       SINGLE-VALUE
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+attributetype ( 1.3.6.1.4.1.5322.10.1.4
+       NAME 'krb5MaxRenew'
+       EQUALITY integerMatch
+       SINGLE-VALUE
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+attributetype ( 1.3.6.1.4.1.5322.10.1.5
+       NAME 'krb5KDCFlags'
+       EQUALITY integerMatch
+       SINGLE-VALUE
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+attributetype ( 1.3.6.1.4.1.5322.10.1.6
+       NAME 'krb5EncryptionType'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+attributetype ( 1.3.6.1.4.1.5322.10.1.7
+       NAME 'krb5ValidStart'
+       EQUALITY generalizedTimeMatch
+       ORDERING generalizedTimeOrderingMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
+       SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.5322.10.1.8
+       NAME 'krb5ValidEnd'
+       EQUALITY generalizedTimeMatch
+       ORDERING generalizedTimeOrderingMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
+       SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.5322.10.1.9
+       NAME 'krb5PasswordEnd'
+       EQUALITY generalizedTimeMatch
+       ORDERING generalizedTimeOrderingMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
+       SINGLE-VALUE )
+
+# this is temporary; keys will eventually
+# be child entries or compound attributes.
+attributetype ( 1.3.6.1.4.1.5322.10.1.10
+       NAME 'krb5Key'
+       DESC 'Encoded ASN1 Key as an octet string'
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
+
+attributetype ( 1.3.6.1.4.1.5322.10.1.11
+       NAME 'krb5PrincipalRealm'
+       DESC 'Distinguished name of krb5Realm entry'
+       SUP distinguishedName )
+
+attributetype ( 1.3.6.1.4.1.5322.10.1.12
+       NAME 'krb5RealmName'
+       EQUALITY octetStringMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )
+
+# Object class definitions
+
+objectclass ( 1.3.6.1.4.1.5322.10.2.1
+       NAME 'krb5Principal'
+       SUP top
+       AUXILIARY
+       MUST ( krb5PrincipalName )
+       MAY ( cn $ krb5PrincipalRealm ) )
+
+objectclass ( 1.3.6.1.4.1.5322.10.2.2
+       NAME 'krb5KDCEntry'
+       SUP krb5Principal
+       AUXILIARY
+       MUST ( krb5KeyVersionNumber )
+       MAY ( krb5ValidStart $ krb5ValidEnd $ krb5PasswordEnd $
+              krb5MaxLife $ krb5MaxRenew $ krb5KDCFlags $
+              krb5EncryptionType $ krb5Key ) )
+
+objectclass ( 1.3.6.1.4.1.5322.10.2.3
+       NAME 'krb5Realm'
+       SUP top
+       AUXILIARY
+       MUST ( krb5RealmName ) )
+
diff --git a/gosa-core/contrib/openldap/kolab2.schema b/gosa-core/contrib/openldap/kolab2.schema
new file mode 100644 (file)
index 0000000..85b22d7
--- /dev/null
@@ -0,0 +1,641 @@
+# $Id: kolab2.schema,v 1.22 2007/02/02 15:16:45 thomas Exp $
+# (c) 2003, 2004 Tassilo Erlewein <tassilo.erlewein@erfrakon.de>
+# (c) 2003-2006  Martin Konold <martin.konold@erfrakon.de>
+# (c) 2003 Achim Frank <achim.frank@erfrakon.de>
+#
+# Redistribution and use in source and binary forms, with or without 
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this 
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice, 
+# this list of conditions and the following disclaimer in the documentation 
+# and/or other materials provided with the distribution.
+#
+# The name of the author may not be used to endorse or promote products derived 
+# from this software without specific prior written permission.
+#
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This schema highly depends on the core.schema, cosine.schema and the inetorgperson.schema
+# as provided by 3rd parties like OpenLDAP.
+#
+# slapd.conf then looks like
+# include /kolab/etc/openldap/schema/core.schema
+# include /kolab/etc/openldap/schema/cosine.schema
+# include /kolab/etc/openldap/schema/inetorgperson.schema
+# include /kolab/etc/openldap/schema/rfc2739.schema
+# include /kolab/etc/openldap/schema/kolab2.schema
+
+#
+####################
+# kolab attributes #
+####################
+
+# helper attribute to make the kolab root easily findable in 
+# a big ldap directory
+attributetype ( 1.3.6.1.4.1.19414.2.1.1
+  NAME ( 'k' 'kolab' )
+  DESC 'Kolab attribute'
+  SUP name )
+
+# kolabDeleteflag used to be a boolean but describes with Kolab 2 
+# the fqdn of the server which is requested to delete this objects
+# in its local store
+attributetype ( 1.3.6.1.4.1.19414.2.1.2
+  NAME 'kolabDeleteflag'
+  DESC 'Per host deletion status'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# alias used to provide alternative rfc822 email addresses for kolab users
+attributetype ( 1.3.6.1.4.1.19414.2.1.3
+  NAME 'alias'
+  DESC 'RFC1274: RFC822 Mailbox'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# kolabEncryptedPassword is an asymmetrically (RSA) encrypted copy of the
+# cleartext password. This is required in order to pass the password from
+# the maintainance/administration application to the kolabHomeServer running the
+# resource handler application in a secure manner.
+# Actually this attribute is deprecated as of Kolab 2.1. Instead we grant the 
+# calendar user dn: cn=calendar,cn=internal,dc=yourcompany,dc=com access to 
+# the respective calendar folder using IMAP ACLs.
+attributetype ( 1.3.6.1.4.1.19419.2.1.4
+  NAME 'kolabEncryptedPassword'
+  DESC 'base64 encoded public key encrypted Password'
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+# hostname including the domain name like kolab-master.yourcompany.com
+attributetype ( 1.3.6.1.4.1.19414.2.1.5
+  NAME ( 'fqhostname' 'fqdnhostname' )
+  DESC 'Fully qualified Hostname including full domain component'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# fqdn of all hosts in a multi-location or cluster setup
+attributetype ( 1.3.6.1.4.1.19414.2.1.6
+  NAME 'kolabHost'
+  DESC 'Multivalued -- list of hostnames in a Kolab setup'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# fqdn of the server containg the actual user mailbox
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.1
+  NAME 'kolabHomeServer'
+  DESC 'server which keeps the users mailbox'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# flag for allowing unrestriced length of mails
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.2
+  NAME 'unrestrictedMailSize'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
+
+# Specifies the email delegates.
+# An email delegate can send email on behalf of the account  
+# which means using the "from" of the account.
+# Delegates are specified by the syntax of rfc822 email addresses.
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.3
+  NAME 'kolabDelegate'
+  DESC 'Kolab user allowed to act as delegates - RFC822 Mailbox/Alias'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# For user, group and resource Kolab accounts
+# Describes how to respond to invitations
+# We keep the attribute as a string, but actually it can only have one 
+# of the following values:
+#
+#  ACT_ALWAYS_ACCEPT
+#  ACT_ALWAYS_REJECT
+#  ACT_REJECT_IF_CONFLICTS
+#  ACT_MANUAL_IF_CONFLICTS
+#  ACT_MANUAL
+# In addition one of these values may be prefixed with a primary email 
+# address followed by a colon like
+# user@domain.tld: ACT_ALWAYS_ACCEPT
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.4
+  NAME ( 'kolabInvitationPolicy' 'kolabResourceAction' )
+  DESC 'defines how to respond to invitations'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# time span from now to the future used for the free busy data
+# measured in days
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.5
+  NAME 'kolabFreeBusyFuture' 
+  DESC 'time in days for fb data towards the future'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 
+  SINGLE-VALUE )
+
+# time span from now to the past used for the free busy data
+# measured in days
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.6
+  NAME 'kolabFreeBusyPast'
+  DESC 'time in days for fb data towards the past'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+# fqdn of the server as the default SMTP MTA
+# not used in Kolab 2 currently as in Kolab 2 the
+# default MTA is equivalent to the kolabHomeServer
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.7
+  NAME 'kolabHomeMTA'
+  DESC 'fqdn of default MTA'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
+  SINGLE-VALUE )
+
+# Begin date of Kolab vacation period. Sender will
+# be notified every kolabVacationResendIntervall days 
+# that recipient is absent until kolabVacationEnd.
+# Values in this syntax are encoded as printable strings,
+# represented as specified in X.208. 
+# Note that the time zone must be specified. 
+# For Kolab we limit ourself to  GMT
+# YYYYMMDDHHMMZ e.g. 200512311458Z.
+# see also: rfc 2252.
+# Currently this attribute is not used in Kolab.
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.8
+  NAME 'kolabVacationBeginDateTime'
+  DESC 'Begin date of vacation'
+  EQUALITY generalizedTimeMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
+  SINGLE-VALUE )
+
+# End date of Kolab vacation period. Sender will
+# be notified every kolabVacationResendIntervall days
+# that recipient is absent starting from kolabVacationBeginDateTime.
+# Values in this syntax are encoded as printable strings,
+# represented as specified in X.208.
+# Note that the time zone must be specified.
+# For Kolab we limit ourself to  GMT
+# YYYYMMDDHHMMZ e.g. 200601012258Z.
+# see also: rfc 2252.
+# Currently this attribute is not used in Kolab.
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.9
+  NAME 'kolabVacationEndDateTime'
+  DESC 'End date of vacation'
+  EQUALITY generalizedTimeMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
+  SINGLE-VALUE )
+
+# Intervall in days after which senders get 
+# another vacation message.
+# Currently this attribute is not used in Kolab.
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.10
+  NAME 'kolabVacationResendInterval'
+  DESC 'Vacation notice interval in days'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+# Email recipient addresses which are handled by the
+# vacation script. There can be multiple kolabVacationAddress
+# entries for each kolabInetOrgPerson.
+# Default is the primary email address and all
+# email aliases of the kolabInetOrgPerson.
+# Currently this attribute is not used in Kolab.
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.11
+  NAME 'kolabVacationAddress'
+  DESC 'Email address for vacation to response upon'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# Enable sending vacation notices in reaction
+# unsolicited commercial email.
+# Default is no.
+# Currently this attribute is not used in Kolab.
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.12
+  NAME 'kolabVacationReplyToUCE'
+  DESC 'Enable vacation notices to UCE'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
+  SINGLE-VALUE )
+
+# Email recipient domains which are handled by the
+# vacation script. There can be multiple kolabVacationReactDomain
+# entries for each kolabInetOrgPerson
+# Default is to handle all domains.
+# Currently this attribute is not used in Kolab.
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.13
+  NAME 'kolabVacationReactDomain'
+  DESC 'Multivalued -- Email domain for vacation to response upon'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )  
+
+# Forward all incoming emails except UCE if kolabForwardUCE
+# is not set to this email address.
+# There can be multiple kolabForwardAddress entries for 
+# each kolabInetOrgPerson.
+# Currently this attribute is not used in Kolab.
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.14
+  NAME 'kolabForwardAddress'
+  DESC 'Forward email to this address'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# Keep local copy when forwarding emails to list of
+# kolabForwardAddress. 
+# Default is no.
+# Currently this attribute is not used in Kolab.
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.15
+  NAME 'kolabForwardKeepCopy'
+  DESC 'Keep copy when forwarding'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 
+  SINGLE-VALUE )
+
+# Enable forwarding of UCE. 
+# Default is yes.
+# Currently this attribute is not used in Kolab.
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.16
+  NAME 'kolabForwardUCE'
+  DESC 'Enable forwarding of mails known as UCE'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 
+  SINGLE-VALUE )
+
+# comment when creating or deleting a kolab object
+# a comment might be appropriate. This is most useful
+# for tracability when users get moved to the graveyard 
+# instead of being really deleted. Every entry must be prefixed
+# with an ISO 8601 date string e.g 200604301458Z. All times must 
+# be in zulu timezone.
+attributetype ( 1.3.6.1.4.1.19419.1.1.1.17
+  NAME 'kolabComment'
+  DESC 'multi-value comment'
+  EQUALITY caseIgnoreMatch
+  SUBSTR caseIgnoreSubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )
+
+# kolabFolderType describes the kind of Kolab folder
+# as defined in the kolab format specification. 
+# We will annotate all folders with an entry 
+# /vendor/kolab/folder-type containing the attribute 
+# value.shared set to: <type>[.<subtype>]. 
+# The <type> can be: mail, event, journal, task, note, 
+# or contact. The <subtype> for a mail folder can be 
+# inbox, drafts, sentitems, or junkemail (this one holds 
+# spam mails). For the other <type>s, it can only be 
+# default, or not set.  For other types of folders 
+# supported by the clients, these should be prefixed with 
+# "k-" for KMail, "h-" for Horde and "o-" for Outlook, and 
+# look like for example "kolab.o-voicemail". Other third-party
+# clients shall use the "x-" prefix.
+# We then use the ANNOTATEMORE IMAP extension to 
+# associate the folder type with a folder.
+attributetype ( 1.3.6.1.4.1.19414.2.1.7
+  NAME 'kolabFolderType'
+  DESC 'type of a kolab folder'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
+  SINGLE-VALUE )
+
+######################
+# postfix attributes #
+######################
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.501
+  NAME 'postfix-mydomain'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.502
+  NAME 'postfix-relaydomains'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.503
+  NAME 'postfix-mydestination'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.504
+  NAME 'postfix-mynetworks'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.505
+  NAME 'postfix-relayhost'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.506
+  NAME 'postfix-transport'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.507
+  NAME 'postfix-enable-virus-scan'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.508
+  NAME 'postfix-allow-unauthenticated'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.509
+  NAME 'postfix-virtual'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.510
+  NAME 'postfix-relayport'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+##########################
+# cyrus imapd attributes #
+##########################
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.601
+  NAME 'cyrus-autocreatequota'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.602
+  NAME 'cyrus-admins'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+# enable plain imap without ssl 
+attributetype ( 1.3.6.1.4.1.19414.2.1.603
+  NAME 'cyrus-imap'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 
+  SINGLE-VALUE )
+
+# enable legacy pop3
+attributetype ( 1.3.6.1.4.1.19414.2.1.604
+  NAME 'cyrus-pop3'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
+
+# user specific quota on the cyrus imap server
+attributetype ( 1.3.6.1.4.1.19414.2.1.605
+  NAME 'cyrus-userquota'
+  DESC 'Mailbox hard quota limit in MB'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+# enable secure imap 
+attributetype ( 1.3.6.1.4.1.19414.2.1.606
+  NAME 'cyrus-imaps'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
+
+# enable secure pop3
+attributetype ( 1.3.6.1.4.1.19414.2.1.607
+  NAME 'cyrus-pop3s'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
+
+# enable sieve support (required for forward and vacation services)
+attributetype ( 1.3.6.1.4.1.19414.2.1.608
+  NAME 'cyrus-sieve'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
+
+# installation wide percentage which determines when to send a 
+# warning to the user
+attributetype ( 1.3.6.1.4.1.19414.2.1.609
+  NAME 'cyrus-quotawarn'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+#############################
+# apache and php attributes #
+#############################
+
+# enable plain http (no ssl)
+attributetype ( 1.3.6.1.4.1.19414.2.1.701
+  NAME 'apache-http'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
+
+# Allow freebusy download without authenticating first
+attributetype ( 1.3.6.1.4.1.19414.2.1.702
+  NAME 'apache-allow-unauthenticated-fb'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
+
+##########################
+# kolabfilter attributes #
+##########################
+
+# enable trustable From:
+attributetype ( 1.3.6.1.4.1.19414.2.1.750
+  NAME 'kolabfilter-verify-from-header'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
+
+# should Sender header be allowed instead of From
+# when present?
+attributetype ( 1.3.6.1.4.1.19414.2.1.751
+  NAME 'kolabfilter-allow-sender-header'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
+
+# Should reject messages with From headers that dont match
+# the envelope? Default is to rewrite the header
+attributetype ( 1.3.6.1.4.1.19414.2.1.752
+  NAME 'kolabfilter-reject-forged-from-header'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
+
+######################
+# proftpd attributes #
+######################
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.901
+  NAME 'proftpd-defaultquota'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.902
+  NAME 'proftpd-ftp'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
+
+attributetype ( 1.3.6.1.4.1.19414.2.1.903
+  NAME 'proftpd-userPassword'
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+########################
+# kolab object classes #
+########################
+
+# main kolab server configuration
+# storing global values and user specific default values
+# like kolabFreeBusyFuture and kolabFreeBusyPast
+objectclass ( 1.3.6.1.4.1.19414.2.2.1 
+  NAME 'kolab'
+  DESC 'Kolab server configuration'
+  SUP top STRUCTURAL
+  MUST k
+  MAY ( kolabHost $
+        postfix-mydomain $
+        postfix-relaydomains $
+        postfix-mydestination $
+        postfix-mynetworks $
+        postfix-relayhost $
+        postfix-relayport $
+        postfix-transport $
+        postfix-virtual $
+        postfix-enable-virus-scan $
+        postfix-allow-unauthenticated $
+        cyrus-quotawarn $
+        cyrus-autocreatequota $
+        cyrus-admins $
+        cyrus-imap $
+        cyrus-pop3 $
+        cyrus-imaps $
+        cyrus-pop3s $
+        cyrus-sieve $
+        apache-http $
+        apache-allow-unauthenticated-fb $
+        kolabfilter-verify-from-header $
+        kolabfilter-allow-sender-header $
+        kolabfilter-reject-forged-from-header $
+        proftpd-ftp $
+        proftpd-defaultquota $
+        kolabFreeBusyFuture $
+        kolabFreeBusyPast $
+        uid $
+        userPassword ) )
+
+# public folders are typically visible to everyone subscribed to 
+# the server without the need for an extra login. Subfolders are
+# defined using the hiarchy seperator '/' e.g. "sf/sub1". Please note
+# that the term public folder is prefered to shared folder because 
+# normal user mailboxes can also share folders using acls.
+objectclass ( 1.3.6.1.4.1.19414.2.2.9 
+  NAME 'kolabSharedFolder'
+  DESC 'Kolab public shared folder'
+  SUP top AUXILIARY
+  MUST cn
+  MAY ( acl $
+        alias $
+        cyrus-userquota $
+        kolabHomeServer $
+        kolabFolderType $
+        kolabDeleteflag ) )
+
+# kolabNamedObject is used as a plain node for the LDAP tree. 
+# In contrast to unix filesystem directories LDAP nodes can 
+# and often do also have contents/attributes. We use the 
+# kolabNamedObject in order to put some structure in the 
+# LDAP directory tree.
+objectclass ( 1.3.6.1.4.1.5322.13.1.1 
+  NAME 'kolabNamedObject'
+  SUP top STRUCTURAL
+  MAY (cn $ ou) )
+
+# kolab account
+# we use an auxiliary in order to ease integration
+# with existing inetOrgPerson objects
+# Please note that userPassword is a may 
+# attribute in the schema but is mandatory for
+# Kolab 
+objectclass ( 1.3.6.1.4.1.19414.3.2.2
+  NAME 'kolabInetOrgPerson'
+  DESC 'Kolab Internet Organizational Person'
+  SUP top AUXILIARY
+  MAY ( c $
+        alias $
+        kolabHomeServer $
+        kolabHomeMTA $
+        unrestrictedMailSize $
+        kolabDelegate $
+        kolabEncryptedPassword $
+        cyrus-userquota $
+        kolabInvitationPolicy $
+        kolabFreeBusyFuture $
+        calFBURL $
+       kolabVacationBeginDateTime $
+       kolabVacationEndDateTime $
+       kolabVacationResendInterval $
+       kolabVacationAddress $
+       kolabVacationReplyToUCE $
+       kolabVacationReactDomain $
+       kolabForwardAddress $
+       kolabForwardKeepCopy $
+        kolabForwardUCE $
+        kolabDeleteflag $
+        kolabComment ) )
+
+# kolab organization with country support
+objectclass ( 1.3.6.1.4.1.19414.3.2.3 
+  NAME 'kolabOrganization'
+  DESC 'RFC2256: a Kolab organization'
+  SUP organization STRUCTURAL
+  MAY ( c $
+        mail $
+        kolabDeleteflag $
+        alias ) )
+
+# kolab organizational unit with country support
+objectclass ( 1.3.6.1.4.1.19414.3.2.4 
+  NAME 'kolabOrganizationalUnit'
+  DESC 'a Kolab organizational unit'
+  SUP organizationalUnit STRUCTURAL
+  MAY ( c $
+        mail $
+        kolabDeleteflag $
+        alias ) )
+
+# kolab groupOfNames with extra kolabDeleteflag and the required 
+# attribute mail.    
+# The mail attribute for kolab objects of the type kolabGroupOfNames 
+# is not arbitrary but MUST be a single attribute of the form 
+# of an valid SMTP address with the CN as the local part.
+# E.g cn@kolabdomain (e.g. employees@mydomain.com). The    
+# mail attribute MUST be globally unique.    
+objectclass ( 1.3.6.1.4.1.19414.3.2.5    
+  NAME 'kolabGroupOfNames'    
+  DESC 'Kolab group of names (DNs) derived from RFC2256'    
+  SUP top AUXILIARY    
+  MAY ( mail $    
+        kolabDeleteflag ) )
diff --git a/gosa-core/contrib/openldap/nagios.schema b/gosa-core/contrib/openldap/nagios.schema
new file mode 100644 (file)
index 0000000..caa56af
--- /dev/null
@@ -0,0 +1,183 @@
+#
+## schema file for OpenLDAP 2.x
+## Schema for storing Nagios User Configuration in LDAP
+## OIDs are owned by OpenSides
+##
+## number from 1 to 30 are for objectclasses
+## attributeype start at 31
+#
+# $Id: nagios.schema,v 1.5 2005/09/09 10:31:55 guiguidoc Exp $
+#
+# nagios/contacts.cfg
+#
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.31 NAME 'NagiosMail'
+        DESC 'short name used to identify the contact'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.32 NAME 'NagiosPager'
+        DESC 'pager number for the contact'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.33 NAME 'NagiosAlias'
+        DESC 'longer name or description for the contact'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.34 NAME 'ServiceNotificationPeriod'
+        DESC 'time period during wich the contact can be notified'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.35 NAME 'HostNotificationPeriod'
+        DESC 'time period during which the contact can be notified'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.36 NAME 'ServiceNotificationOptions'
+        DESC 'define the service states for which notifications can be sent out'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.37 NAME 'HostNotificationOptions'
+        DESC 'define the service states for which notifications can be sent out'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.38 NAME 'ServiceNotificationCommands'
+        DESC 'commands used to notify the contact'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.39 NAME 'HostNotificationCommands'
+        DESC 'commands used to notify the contact'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+#
+# nagios/cgi.cfg
+#
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.40 NAME 'AuthorizedSystemInformation'
+        DESC 'users who can view system/process information'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.41 NAME 'AuthorizedConfigurationInformation'
+        DESC 'users who can view configuration information'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.42 NAME 'AuthorizedSystemCommands'
+        DESC 'users who can issue system/process commands'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.43 NAME 'AuthorizedAllServices'
+        DESC 'users who can view status and configuration information'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.44 NAME 'AuthorizedAllHosts'
+        DESC 'users who can view status and configuration information'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.45 NAME 'AuthorizedAllServiceCommands'
+        DESC 'users who can issue commands for all services'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.46 NAME 'AuthorizedAllHostCommands'
+        DESC 'users who can issue commands for all hosts'
+        EQUALITY caseIgnoreIA5Match
+       SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+#
+# nagios/contactgroups.cfg
+#
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.47 NAME 'ContactGroupName'
+        DESC 'name used to identify the contact group'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.48 NAME 'ContactGroupAlias'
+        DESC 'description used to identify the contact group'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.1.49 NAME 'ContactGroupMembers'
+        DESC 'a list of the short names of contacts'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+#
+# all objectclass 
+#
+
+objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.1 NAME 'nagiosAuth' SUP top AUXILIARY
+ DESC 'nagiosAuth'
+ MAY ( AuthorizedSystemInformation $ AuthorizedConfigurationInformation $ 
+       AuthorizedSystemCommands $ AuthorizedAllServices $ AuthorizedAllHosts $
+       AuthorizedAllServiceCommands $ AuthorizedAllHostCommands ) )
+
+#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.2 NAME 'nagiosHost' SUP top AUXILIARY
+# DESC 'Host'
+
+#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.3 NAME 'nagiosService' SUP top AUXILIARY
+# DESC 'Service'
+
+objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.4 NAME 'nagiosContact' SUP top AUXILIARY
+ DESC 'Contact'
+ MUST (        uid $ NagiosAlias $ ServiceNotificationPeriod $ HostNotificationPeriod $ 
+       ServiceNotificationOptions $ HostNotificationOptions  ) 
+ MAY ( ServiceNotificationCommands $ HostNotificationCommands $ NagiosMail $ NagiosPager  ))
+
+#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.5 NAME 'nagiosHostGroup' SUP top AUXILIARY
+# DESC 'HostGroup'
+
+objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.6 NAME 'nagiosContactGroup' SUP top AUXILIARY
+ DESC 'ContactGroup'
+ MAY ( ContactGroupName $ ContactGroupAlias $ ContactGroupMembers  ))
+
+#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.7 NAME 'nagiosTimePeriod' SUP top AUXILIARY
+# DESC 'TimePeriod'
+
+#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.8 NAME 'nagiosCommand' SUP top AUXILIARY
+# DESC 'Command'
+
+#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.9 NAME 'nagiosServiceDependency' SUP top AUXILIARY
+# DESC 'ServiceDependency'
+
+#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.10 NAME 'nagiosServiceEscalation' SUP top AUXILIARY
+# DESC 'ServiceEscalation'
+
+#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.11 NAME 'nagiosHostDependency' SUP top AUXILIARY
+# DESC 'HostDependency'
+
+#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.12 NAME 'nagiosHostEscalation' SUP top AUXILIARY
+# DESC 'HostEscalation'
+
+#objectclass ( 1.3.6.1.4.1.22262.1.1.1.1.13 NAME 'nagiosHostGroupEscalation' SUP top AUXILIARY
+# DESC 'HostGroupEscalation'
+
diff --git a/gosa-core/contrib/openldap/openxchange.schema b/gosa-core/contrib/openldap/openxchange.schema
new file mode 100644 (file)
index 0000000..e32e837
--- /dev/null
@@ -0,0 +1,714 @@
+#
+# OPEN X CHANGE ORG - SCHEMA 0.1 
+#
+attributetype ( 1.1.2.1.1.1 NAME ( 'mailEnabled' )
+       DESC 'Is the user enabled or not, for pam_ldap,postfix etc. filtering...'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.2 NAME ( 'alias' )
+       DESC 'email alias'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
+
+attributetype ( 1.1.2.1.1.3 NAME ( 'imapServer' )
+       DESC 'Users Imap Server'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.4 NAME ( 'imapPort' )
+       DESC 'Users Imap Server Port'
+       SUP ipServicePort )
+
+attributetype ( 1.1.2.1.1.5 NAME ( 'sievePort' ) 
+       DESC 'Users SIEVE Server Port'
+       SUP ipServicePort )
+
+attributetype ( 1.1.2.1.1.6 NAME ( 'smtpServer' )
+       DESC 'Users SMTP Server'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.7 NAME ( 'smtpPort' )
+       DESC 'Users SMTP Server Port'
+       SUP ipServicePort )
+
+attributetype ( 1.1.2.1.1.8 NAME ( 'relClientCert' )
+       DESC 'Users Certificate for Ip Service like SMTP or IMAP'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.9 NAME ( 'userCountry' )
+        DESC 'Users country code'
+        SUP name SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.10 NAME ( 'loginDestination' )
+       DESC 'Users Destination - Groupware , Webmail, Config ...'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.11 NAME ( 'birthDay' )
+       DESC 'Users birthday'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.12 NAME ( 'colocRouteAddr' )
+       DESC 'route mail to this address'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.13 NAME ( 'reject' )
+       DESC 'Should contain the mailaddys to reject'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+attributetype ( 1.1.2.1.1.14 NAME ( 'lnetMailAccess' )
+       DESC 'Is the user able to send mail to the inet'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.15 NAME ( 'OXGroupwareStyle' )
+       DESC 'Groupware Style'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.16 NAME ( 'OXWebmailStyle' )
+       DESC 'Webmail Style'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.17 NAME 'OXGroupID'
+        DESC 'GIDs of the secondary Groups of the User'
+        EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27)
+
+attributetype ( 1.1.2.1.1.18 NAME ( 'OXAppointmentDays' )
+       DESC 'Days to display new appointments'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+
+attributetype ( 1.1.2.1.1.19 NAME ( 'OXTaskDays' )
+       DESC 'Days to display new tasks'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.20 NAME ( 'OXTimeZone' )
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.21 NAME ( 'groupwareServer' )
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.22 NAME ( 'groupwareServerPort' )
+       SUP ipServicePort )
+
+attributetype ( 1.1.2.1.1.23 NAME ( 'webmailServer' )
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.24 NAME ( 'webmailServerPort' )
+       SUP ipServicePort )
+
+attributetype ( 1.1.2.1.1.25 NAME ( 'DBServer' )
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.26 NAME ( 'DBServerPort' )
+       SUP ipServicePort SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.27 NAME ( 'DBServerType' )
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.29 NAME ( 'resourceGroupName' ) 
+       SUP name SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.30 NAME ( 'resourceGroupMember' )
+       DESC 'resource that is member of a resource group'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
+
+attributetype ( 1.1.2.1.1.31 NAME ( 'resourceGroupAvailable' )
+        DESC 'Ressource group available in OX'
+       EQUALITY booleanMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.32 NAME ( 'resourceGroupDescription' ) 
+       SUP description SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.33 NAME ( 'resourceName' ) 
+       SUP name SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.34 NAME ( 'resourceAvailable' )
+        DESC 'Ressource available in OX'
+       EQUALITY booleanMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.35 NAME ( 'resourceDescription' ) 
+       SUP description SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.36 NAME ( 'mailDomain' )
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.37 NAME ( 'vaddress' )
+       DESC 'vadress'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+attributetype ( 1.1.2.1.1.38  NAME ( 'MTALocaldomain' )
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.39 NAME ( 'mailDeliveryProgram' )
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
+
+attributetype ( 1.1.2.1.1.40 NAME ( 'deliverToUID' )
+       DESC 'direct mail delivery'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+attributetype ( 1.1.2.1.1.41 NAME ( 'fn' ) SUP name )
+
+attributetype ( 1.1.2.1.1.42 NAME ( 'smtpDomainTransportNexthop' )
+       DESC 'contain transport:[nexthop] mail routing information'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.43 NAME ( 'smtpDomain' )
+       DESC 'contain host/domain name, used with smtpDomainTransportNexthop'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
+
+
+
+########### Special Attributes for new Contact Handling (OL)  ###############################
+
+attributetype ( 1.1.2.1.1.44 NAME ( 'IPPhone' )
+        DESC 'User IPPhone Address in Outlook'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.1.2.1.1.45 NAME ( 'url' )
+        DESC 'Users business Homepage'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.46 NAME ( 'otherpager' )
+        DESC 'Users Business pager'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.47 NAME ( 'otherfacsimiletelephonenumber' )
+        DESC 'Users Home fax number'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.1.2.1.1.48 NAME ( 'middleName' )
+        DESC 'Users middlename'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.49 NAME ( 'conferenceInformation' )
+        DESC 'Users n3tmeeting Info'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+########### END - Special Attributes for new Contact Handling (OL)  ###############################
+
+########### Special Attributes for new Contact Handling (OX) ##############################
+
+attributetype ( 1.1.2.1.1.50 NAME ( 'OXUserPosition' )
+        DESC 'Users position'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.51 NAME ( 'OXUserSalesVolume' )
+        DESC 'Users sales volume'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.1.2.1.1.52 NAME ( 'OXUserCity' )
+        DESC 'Users City'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.1.2.1.1.53 NAME ( 'OXUserTaxID' )
+        DESC 'Users Tax ID'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.1.2.1.1.54 NAME ( 'OXUserComReg' )
+        DESC 'Users Commercial Register'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.1.2.1.1.55 NAME ( 'OXUserBranches' )
+        DESC 'Users Branches'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.1.2.1.1.56 NAME ( 'OXUserAssistant' )
+        DESC 'Users Assistant'
+       SUP manager )
+
+attributetype ( 1.1.2.1.1.57 NAME ( 'OXUserCategories' )
+        DESC 'Users Categories'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.58 NAME ( 'OXUserOtherStreet' )
+        DESC 'Users alternative Street'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.1.2.1.1.59 NAME ( 'OXUserOtherPostalCode' )
+        DESC 'Users alternative postal code'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.60 NAME ( 'OXUserOtherCity' )
+        DESC 'Users alternative city'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.61 NAME ( 'OXUserOtherState' )
+        DESC 'Users alternative State'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.1.2.1.1.62 NAME ( 'OXUserOtherCountry' )
+        DESC 'Users alternative Country'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.63 NAME ( 'OXUserTeleAssistant' )
+        DESC 'Users Assistant TelephoneNumber'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.1.2.1.1.64 NAME ( 'OXUserTeleBusiness2' )
+        DESC 'Users alternative business phone number'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.1.2.1.1.65 NAME ( 'OXUserTeleCallback' )
+        DESC 'Users Callback'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.1.2.1.1.66 NAME ( 'OXUserTeleCar' )
+        DESC 'Users Car Phone Number'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.67 NAME ( 'OXUserTeleCompany' )
+        DESC 'Users Company Phone'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.68 NAME ( 'OXUserTeleHome2' )
+        DESC 'Users 2nd. Home Phone '
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.69 NAME ( 'OXUserTeleMobile2' )
+        DESC 'Users 2nd mobile number'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.70 NAME ( 'OXUserTeleOther' )
+        DESC 'Users other Phone'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.71 NAME ( 'OXUserTeleFax2' )
+        DESC 'Users 2nd Telefax Number'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.72 NAME ( 'OXUserTelePrimary' )
+        DESC 'Users primary Phone'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.73 NAME ( 'OXUserTeleRadio' )
+        DESC 'Users Radio'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.74 NAME ( 'OXUserTeleTTY' )
+        DESC 'Users TTY/tdd '
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.75 NAME ( 'OXUserInstantMessenger' )
+        DESC 'Users IM'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.76 NAME ( 'OXUserInstantmessenger2' )
+        DESC 'Users 2nd IM'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.77 NAME ( 'OXUserEmail2' )
+        DESC 'Users 2nd Email'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.78 NAME ( 'OXUserEmail3' )
+        DESC 'Users 3rd Email'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.79 NAME ( 'OXUserUserUndef01' )
+        DESC 'Users custom field 01'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.80 NAME ( 'OXUserUserUndef02' )
+        DESC 'Users custom field 02'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.81 NAME ( 'OXUserUserUndef03' )
+        DESC 'Users custom field 03'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.82 NAME ( 'OXUserUserUndef04' )
+        DESC 'Users custom field 04'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.83 NAME ( 'OXUserUserUndef05' )
+        DESC 'Users custom field 05'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.84 NAME ( 'OXUserUserUndef06' )
+        DESC 'Users custom field 06'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.85 NAME ( 'OXUserUserUndef07' )
+        DESC 'Users custom field 07'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.86 NAME ( 'OXUserUserUndef08' )
+        DESC 'Users custom field 08'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.87 NAME ( 'OXUserUserUndef09' )
+        DESC 'Users custom field 09'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.88 NAME ( 'OXUserUserUndef10' )
+        DESC 'Users custom field 10'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.89 NAME ( 'OXUserUserUndef11' )
+        DESC 'Users custom field 11'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.90 NAME ( 'OXUserUserUndef12' )
+        DESC 'Users custom field 12'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.91 NAME ( 'OXUserUserUndef13' )
+        DESC 'Users custom field 13'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.92 NAME ( 'OXUserUserUndef14' )
+        DESC 'Users custom field 14'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.93 NAME ( 'OXUserUserUndef15' )
+        DESC 'Users custom field 15'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.94 NAME ( 'OXUserUserUndef16' )
+        DESC 'Users custom field 16'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.95 NAME ( 'OXUserUserUndef17' )
+        DESC 'Users custom field 17'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.96 NAME ( 'OXUserUserUndef18' )
+        DESC 'Users custom field 18'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.97 NAME ( 'OXUserUserUndef19' )
+        DESC 'Users custom field 19'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.98 NAME ( 'OXUserUserUndef20' )
+        DESC 'Users custom field 20'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.99 NAME ( 'OXUserSuffix' )
+        DESC 'Users Suffix Name'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.100 NAME ( 'OXUserPostalCode' )
+        DESC 'Users Postal Code address'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.101 NAME ( 'OXUserState' )
+        DESC 'Users State Name'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.102 NAME ( 'OXUserMaritalStatus' )
+        DESC 'Users marital status'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.103 NAME ( 'OXUserChildren' )
+        DESC 'The number of users children '
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.1.2.1.1.104 NAME ( 'OXUserProfession' )
+        DESC 'The Users profession'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.105 NAME ( 'OXUserNickName' )
+        DESC 'Users Nick Name'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.106 NAME ( 'OXUserSpouseName' )
+        DESC 'Users Spouse Name'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.107 NAME ( 'OXUserAnniversary' )
+        DESC 'Any user anniversary'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.108 NAME ( 'OXUserComment' )
+        DESC 'A comment about the Users'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.109 NAME ( 'OXUserDistributionList' )
+        DESC 'uid for the distribution List in the Databse'
+        EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+########### ADDED FOR OX GROUPWARE DAYVIEW ############
+attributetype ( 1.1.2.1.1.110 NAME ( 'OXDayviewInterval' )
+        DESC 'interval for displaying ox appointments on the dayview'
+        EQUALITY integerMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.1.2.1.1.111 NAME ( 'OXDayviewStartTime' )
+        DESC 'starttime for displaying ox appointments on the dayview'
+       EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetype ( 1.1.2.1.1.112 NAME ( 'OXDayviewEndTime' )
+        DESC 'endtime for displaying ox appointments on the dayview'
+       EQUALITY caseIgnoreMatch
+        SUBSTR caseIgnoreSubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+#######################################################
+
+
+### ADDED FOR VDOMAINOBJECT ###
+
+attributetype ( 1.1.2.1.1.113 NAME ( 'domainName' )
+        DESC 'The name of domain'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseIgnoreIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+###############################
+
+
+
+#########################################################################
+
+
+
+#
+# Here we go with the OX Objects ...
+#
+
+objectclass ( 1.1.2.2.1.1 NAME 'OXUserObject' SUP top AUXILIARY
+       DESC 'Additional Objectclass for OX User'
+       MAY ( alias $ imapServer $ imapPort $ sievePort $ mailDomain $ smtpServer $ smtpPort $
+       groupwareServer $ groupwareServerPort $ webmailServer $ webmailServerPort $
+       DBServer $ DBServerPort $ DBServerType $ reject $ relClientCert $ userCountry $ 
+       loginDestination $ birthDay $ colocRouteAddr $ mailEnabled $ lnetMailAccess $ vaddress $ 
+       IPPhone $ url $ otherpager $ otherfacsimiletelephonenumber $ homephone $ 
+       c $ info $ middleName $ co $ conferenceInformation $ telexNumber $
+       OXGroupwareStyle $ OXWebmailStyle $ OXGroupID $ OXAppointmentDays $ OXTaskDays $ OXDayViewInterval $ OXDayViewStartTime $ OXDayViewEndTime $ OXTimeZone $
+       OXUserSuffix $ OXUserPostalCode $ OXUserCity $ OXUserState $ OXUserMaritalStatus $ OXUserChildren $ OXUserProfession $
+       OXUserNickName $ OXUserSpouseName $ OXUserAnniversary $ OXUserComment $
+       OXUserPosition $ OXUserSalesVolume $ OXUserTaxID $ OXUserComReg $ OXUserBranches $
+       OXUserAssistant $ OXUserCategories $ OXUserOtherStreet $ OXUserOtherPostalCode $ OXUserOtherCity $
+       OXUserOtherState $ OXUserOtherCountry $ OXUserTeleAssistant $ OXUserTeleBusiness2 $ OXUserTeleCallback $
+       OXUserTeleCar $ OXUserTeleCompany $ OXUserTeleHome2 $ OXUserTeleMobile2 $ OXUserTeleOther $ OXUserTeleFax2 $
+       OXUserTelePrimary $ OXUserTeleRadio $ OXUserTeleTTY $ OXUserInstantMessenger $ OXUserInstantmessenger2 $
+       OXUserEmail2 $ OXUserEmail3 $ OXUserUserUndef01 $ OXUserUserUndef02 $ OXUserUserUndef03 $ OXUserUserUndef04 $
+       OXUserUserUndef05 $ OXUserUserUndef06 $ OXUserUserUndef07 $ OXUserUserUndef08 $ OXUserUserUndef09 $
+       OXUserUserUndef10 $ OXUserUserUndef11 $ OXUserUserUndef12 $ OXUserUserUndef13 $ OXUserUserUndef14 $
+       OXUserUserUndef15 $ OXUserUserUndef16 $ OXUserUserUndef17 $ OXUserUserUndef18 $ OXUserUserUndef19 $
+       OXUserUserUndef20 $ OXUserDistributionList
+       ))
+
+objectclass ( 1.1.2.2.1.2 NAME 'OXResourceGroupObject' SUP top STRUCTURAL
+       DESC 'Additional Objectclass for OX ResourceGroup'
+       MAY ( resourceGroupName $ resourceGroupMember $ resourceGroupAvailable $ resourceGroupDescription ))
+
+
+objectclass ( 1.1.2.2.1.3 NAME 'OXResourceObject' SUP top STRUCTURAL
+       DESC 'Additional Objectclass for OX Resource'
+       MAY ( resourceName $ resourceAvailable $ resourceDescription ))
+
+objectclass ( 1.1.2.2.1.4 NAME 'OXVDomainObject' SUP top STRUCTURAL
+        DESC 'virtual domains, can be used for lookups for MTA'
+        MUST ( MTALocaldomain $ domainName ))
+
+objectclass ( 1.1.2.2.1.5 NAME 'OXIMAPFolderObject' SUP top STRUCTURAL
+       DESC 'Shared IMAP Folder'
+       MUST fn
+       MAY ( mailDeliveryProgram $ description $ mailEnabled $
+             deliverToUID))
+
+objectclass ( 1.1.2.2.1.6 NAME 'OXMailTransportObject' SUP top STRUCTURAL
+       DESC 'Transport maps in LDAP'
+       MUST ( smtpDomainTransportNexthop $ smtpDomain $ cn )
+       MAY   description )
diff --git a/gosa-core/contrib/openldap/phpgwaccount.schema b/gosa-core/contrib/openldap/phpgwaccount.schema
new file mode 100644 (file)
index 0000000..3edd263
--- /dev/null
@@ -0,0 +1,79 @@
+# $Id egroupware : phpgwaccount.schema,v 1.0 2000/07/29 01:53:16 milosch Exp $
+
+# (C) 2001-2004 Miles Lott <milos@groupwhere.org>
+# Redistribution and use in original text and binary forms, with or
+# without modification, are permitted provided that the following
+# conditions are met:
+#
+# 1. Redistributions of this schema and/or documentation must retain
+#    the above copyright notice, this list of conditions and the
+#    following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+#    this list of conditions and the following disclaimer in the documentation
+#    and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+# lastlogin
+attributetype ( 1.3.6.1.4.1.9554.1
+       NAME 'phpgwAccountLastLogin'
+       DESC 'timestamp of last login'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+       SINGLE-VALUE )
+
+# lastloginfrom
+attributetype ( 1.3.6.1.4.1.9554.2
+       NAME 'phpgwAccountLastLoginFrom'
+       DESC 'IP address as a dotted decimal, eg. 192.168.1.1, omitting leading zeros'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
+
+# lastpasswdchange
+attributetype ( 1.3.6.1.4.1.9554.3
+       NAME 'phpgwLastPasswdChange'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+       SINGLE-VALUE )
+
+# accounttype
+attributetype ( 1.3.6.1.4.1.9554.4
+       NAME 'phpgwAccountType'
+       DESC 'Single-char u/g for user/group'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE )
+
+# status
+attributetype ( 1.3.6.1.4.1.9554.5
+       NAME 'phpgwAccountStatus'
+       DESC 'Single-char A/L for active/inactive'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+       SINGLE-VALUE )
+
+# expires
+attributetype ( 1.3.6.1.4.1.9554.6
+       NAME 'phpgwAccountExpires'
+       DESC 'timestamp for account expiration'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+       SINGLE-VALUE )
+
+# Objectclass definition for phpgwAccount
+objectclass ( 1.3.6.1.4.1.9554.0 NAME 'phpgwAccount' SUP top AUXILIARY
+       DESC 'Abstraction of an account with phpgw attributes'
+       MAY ( phpgwAccountLastLogin $ phpgwAccountLastLoginFrom $ phpgwLastPasswdChange $ phpgwAccountType $ phpgwAccountStatus $ phpgwAccountExpires) )
+
diff --git a/gosa-core/contrib/openldap/phpscheduleit.schema b/gosa-core/contrib/openldap/phpscheduleit.schema
new file mode 100644 (file)
index 0000000..b7450ba
--- /dev/null
@@ -0,0 +1,23 @@
+#
+## schema file for OpenLDAP 2.x
+## Schema for storing PHPscheduleit User Configuration in LDAP
+## OIDs are owned by OpenSides
+##
+## number from 1 to 50 are for objectclasses
+## attributeype start at 50
+#
+# $Id: phpscheduleit.schema,v 1.1 2005/11/02 16:48:16 guiguidoc Exp $
+#
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.3.1 NAME 'phpscheduleitAccountLogin'
+        DESC 'PHPscheduleit Account Login'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+#
+# all objectclass 
+#
+
+objectclass ( 1.3.6.1.4.1.22262.1.1.2.3.1 NAME 'phpscheduleitAccount' SUP top AUXILIARY
+ DESC 'PHPscheduleit Account'
+ MAY ( phpscheduleitAccountLogin  ))
\ No newline at end of file
diff --git a/gosa-core/contrib/openldap/pptp.schema b/gosa-core/contrib/openldap/pptp.schema
new file mode 100644 (file)
index 0000000..bf580c4
--- /dev/null
@@ -0,0 +1,42 @@
+#
+## schema file for OpenLDAP 2.x
+## Schema for storing PPTP User Configuration in LDAP
+## OIDs are owned by OpenSides
+##
+## number from 1 to 50 are for objectclasses
+## attributeype start at 50
+#
+# $Id: pptp.schema,v 1.5 2005/11/02 16:47:22 guiguidoc Exp $
+#
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.2.1 NAME 'pptpAccount'
+        DESC 'PPTP Server Account'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.2.2 NAME 'pptpAccountLogin'
+        DESC 'PPTP Server Account Login'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.2.3 NAME 'pptpAccountPassword'
+        DESC 'PPTP Server Account Password'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.4.1.22262.1.1.1.2.4 NAME 'pptpAccountServerIP'
+        DESC 'PPTP Server Account Server IP'
+        EQUALITY caseIgnoreIA5Match
+        SUBSTR caseExactIA5SubstringsMatch
+        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+#
+# all objectclass 
+#
+
+objectclass ( 1.3.6.1.4.1.22262.1.1.2.2.1 NAME 'pptpServerAccount' SUP top AUXILIARY
+ DESC 'PPTP Server Account'
+ MAY ( pptpAccount  ))
+
diff --git a/gosa-core/contrib/openldap/pureftpd.schema b/gosa-core/contrib/openldap/pureftpd.schema
new file mode 100644 (file)
index 0000000..1cf95ea
--- /dev/null
@@ -0,0 +1,64 @@
+# $Id: pureftpd.schema,v 1.2 2004/02/04 15:25:01 cajus Exp $
+#
+# pureftpd.schema
+#
+# Pure-FTPd User LDAP Schema
+# See README.LDAP in the Pure-FTPd documentation for more information.
+#
+# Written 2002-01-24 by Ben Gertzfield <che =AT= debian -DOT- org>
+#
+
+## Pure-FTPd-related LDAP attributes
+
+attributetype ( 1.3.6.1.4.1.6981.11.3.1 NAME 'FTPQuotaFiles'
+       DESC 'Quota (in number of files) for an FTP user'
+        EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.6981.11.3.2 NAME 'FTPQuotaMBytes'
+       DESC 'Quota (in megabytes) for an FTP user'
+        EQUALITY integerMatch        
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.6981.11.3.3 NAME 'FTPUploadRatio'
+       DESC 'Ratio (compared with FTPRatioDown) for uploaded files'
+        EQUALITY integerMatch        
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.6981.11.3.4 NAME 'FTPDownloadRatio'
+       DESC 'Ratio (compared with FTPRatioUp) for downloaded files'
+        EQUALITY integerMatch        
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.6981.11.3.5 NAME 'FTPUploadBandwidth'
+       DESC 'Bandwidth (in KB/s) to limit upload speeds to'
+        EQUALITY integerMatch        
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.6981.11.3.6 NAME 'FTPDownloadBandwidth'
+       DESC 'Bandwidth (in KB/s) to limit download speeds to'
+        EQUALITY integerMatch        
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.6981.11.3.7 NAME 'FTPStatus'
+       DESC 'Account status: enabled or disabled'
+        EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.6981.11.3.8 NAME 'FTPuid'
+       DESC 'System uid (overrides uidNumber if present)'
+        EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.6981.11.3.9 NAME 'FTPgid'
+       DESC 'System uid (overrides gidNumber if present)'
+        EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+## New Pure-FTPd object type
+
+objectclass ( 1.3.6.1.4.1.6981.11.2.3 NAME 'PureFTPdUser' SUP top AUXILIARY
+       DESC 'PureFTPd user with optional quota, throttling, and ratio'
+       MAY ( FTPStatus $ FTPQuotaFiles $ FTPQuotaMBytes $ FTPUploadRatio $ 
+              FTPDownloadRatio $ FTPUploadBandwidth $ FTPDownloadBandwidth $
+              FTPuid $ FTPgid ) )
diff --git a/gosa-core/contrib/openldap/rfc2307bis.schema b/gosa-core/contrib/openldap/rfc2307bis.schema
new file mode 100644 (file)
index 0000000..db34365
--- /dev/null
@@ -0,0 +1,288 @@
+# builtin
+#
+#attributetype ( 1.3.6.1.1.1.1.0 NAME 'uidNumber'
+#  DESC 'An integer uniquely identifying a user in an administrative domain'
+#  EQUALITY integerMatch
+#  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+#  SINGLE-VALUE )
+
+# builtin
+#
+#attributetype ( 1.3.6.1.1.1.1.1 NAME 'gidNumber'
+#  DESC 'An integer uniquely identifying a group in an
+#        administrative domain'
+#  EQUALITY integerMatch
+#  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+#  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.2 NAME 'gecos'
+  DESC 'The GECOS field; the common name'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.3 NAME 'homeDirectory'
+  DESC 'The absolute path to the home directory'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.4 NAME 'loginShell'
+  DESC 'The path to the login shell'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.6 NAME 'shadowMin'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.7 NAME 'shadowMax'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.8 NAME 'shadowWarning'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.9 NAME 'shadowInactive'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.10 NAME 'shadowExpire'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.11 NAME 'shadowFlag'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.12 NAME 'memberUid'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.1.1.1.13 NAME 'memberNisNetgroup'
+  EQUALITY caseExactIA5Match
+  SUBSTR caseExactIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
+  DESC 'Netgroup triple'
+  EQUALITY caseIgnoreIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.1.1.1.15 NAME 'ipServicePort'
+  DESC 'Service port number'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.16 NAME 'ipServiceProtocol'
+  DESC 'Service protocol name'
+  SUP name )
+
+attributetype ( 1.3.6.1.1.1.1.17 NAME 'ipProtocolNumber'
+  DESC 'IP protocol number'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.18 NAME 'oncRpcNumber'
+  DESC 'ONC RPC number'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+attributetype ( 1.3.6.1.1.1.1.19 NAME 'ipHostNumber'
+  DESC 'IPv4 addresses as a dotted decimal omitting leading
+        zeros or IPv6 addresses as defined in RFC2373'
+  SUP name )
+
+attributetype ( 1.3.6.1.1.1.1.20 NAME 'ipNetworkNumber'
+  DESC 'IP network as a dotted decimal, eg. 192.168,
+        omitting leading zeros'
+  SUP name
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.21 NAME 'ipNetmaskNumber'
+  DESC 'IP netmask as a dotted decimal, eg. 255.255.255.0,
+        omitting leading zeros'
+  EQUALITY caseIgnoreIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.22 NAME 'macAddress'
+  DESC 'MAC address in maximal, colon separated hex
+        notation, eg. 00:00:92:90:ee:e2'
+  EQUALITY caseIgnoreIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.1.1.1.23 NAME 'bootParameter'
+  DESC 'rpc.bootparamd parameter'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.1.1.1.24 NAME 'bootFile'
+  DESC 'Boot image name'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.1.1.1.26 NAME 'nisMapName'
+  DESC 'Name of a A generic NIS map'
+  SUP name )
+
+attributetype ( 1.3.6.1.1.1.1.27 NAME 'nisMapEntry'
+  DESC 'A generic NIS entry'
+  EQUALITY caseExactIA5Match
+  SUBSTR caseExactIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.28 NAME 'nisPublicKey'
+  DESC 'NIS public key'
+  EQUALITY octetStringMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.29 NAME 'nisSecretKey'
+  DESC 'NIS secret key'
+  EQUALITY octetStringMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.30 NAME 'nisDomain'
+  DESC 'NIS domain'
+  EQUALITY caseIgnoreIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.1.1.1.31 NAME 'automountMapName'
+  DESC 'automount Map Name'
+  EQUALITY caseExactIA5Match
+  SUBSTR caseExactIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.32 NAME 'automountKey'
+  DESC 'Automount Key value'
+  EQUALITY caseExactIA5Match
+  SUBSTR caseExactIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.33 NAME 'automountInformation'
+  DESC 'Automount information'
+  EQUALITY caseExactIA5Match
+  SUBSTR caseExactIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount' SUP top AUXILIARY
+  DESC 'Abstraction of an account with POSIX attributes'
+  MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
+  MAY ( userPassword $ loginShell $ gecos $
+        description ) )
+
+objectclass ( 1.3.6.1.1.1.2.1 NAME 'shadowAccount' SUP top AUXILIARY
+  DESC 'Additional attributes for shadow passwords'
+  MUST uid
+  MAY ( userPassword $ description $
+        shadowLastChange $ shadowMin $ shadowMax $
+        shadowWarning $ shadowInactive $
+        shadowExpire $ shadowFlag ) )
+
+objectclass ( 1.3.6.1.1.1.2.2 NAME 'posixGroup' SUP top AUXILIARY
+  DESC 'Abstraction of a group of accounts'
+  MUST gidNumber
+  MAY ( userPassword $ memberUid $
+        description ) )
+
+objectclass ( 1.3.6.1.1.1.2.3 NAME 'ipService' SUP top STRUCTURAL
+  DESC 'Abstraction an Internet Protocol service.
+        Maps an IP port and protocol (such as tcp or udp)
+        to one or more names; the distinguished value of
+        the cn attribute denotes the services canonical
+        name'
+  MUST ( cn $ ipServicePort $ ipServiceProtocol )
+  MAY description )
+
+objectclass ( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' SUP top STRUCTURAL
+  DESC 'Abstraction of an IP protocol. Maps a protocol number
+        to one or more names. The distinguished value of the cn
+        attribute denotes the protocols canonical name'
+  MUST ( cn $ ipProtocolNumber )
+  MAY description )
+
+objectclass ( 1.3.6.1.1.1.2.5 NAME 'oncRpc' SUP top STRUCTURAL
+  DESC 'Abstraction of an Open Network Computing (ONC)
+       [RFC1057] Remote Procedure Call (RPC) binding.
+       This class maps an ONC RPC number to a name.
+       The distinguished value of the cn attribute denotes
+       the RPC services canonical name'
+  MUST ( cn $ oncRpcNumber )
+  MAY description )
+
+objectclass ( 1.3.6.1.1.1.2.6 NAME 'ipHost' SUP top AUXILIARY
+  DESC 'Abstraction of a host, an IP device. The distinguished
+        value of the cn attribute denotes the hosts canonical
+        name. Device SHOULD be used as a structural class'
+  MUST ( cn $ ipHostNumber )
+  MAY ( userPassword $ l $ description $ manager ) )
+
+objectclass ( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' SUP top STRUCTURAL
+  DESC 'Abstraction of a network. The distinguished value of
+        the cn attribute denotes the networks canonical name'
+  MUST ipNetworkNumber
+  MAY ( cn $ ipNetmaskNumber $ l $ description $ manager ) )
+
+objectclass ( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL
+  DESC 'Abstraction of a netgroup. May refer to other netgroups'
+  MUST cn
+  MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) )
+
+objectclass ( 1.3.6.1.1.1.2.9 NAME 'nisMap' SUP top STRUCTURAL
+  DESC 'A generic abstraction of a NIS map'
+  MUST nisMapName
+  MAY description )
+
+objectclass ( 1.3.6.1.1.1.2.10 NAME 'nisObject' SUP top STRUCTURAL
+  DESC 'An entry in a NIS map'
+  MUST ( cn $ nisMapEntry $ nisMapName )
+  MAY description )
+
+objectclass ( 1.3.6.1.1.1.2.11 NAME 'ieee802Device' SUP top AUXILIARY
+  DESC 'A device with a MAC address; device SHOULD be
+        used as a structural class'
+  MAY macAddress )
+
+objectclass ( 1.3.6.1.1.1.2.12 NAME 'bootableDevice' SUP top AUXILIARY
+  DESC 'A device with boot parameters; device SHOULD be
+        used as a structural class'
+  MAY ( bootFile $ bootParameter ) )
+
+objectclass ( 1.3.6.1.1.1.2.14 NAME 'nisKeyObject' SUP top AUXILIARY
+  DESC 'An object with a public and secret key'
+  MUST ( cn $ nisPublicKey $ nisSecretKey )
+  MAY ( uidNumber $ description ) )
+
+objectclass ( 1.3.6.1.1.1.2.15 NAME 'nisDomainObject' SUP top AUXILIARY
+  DESC 'Associates a NIS domain with a naming context'
+  MUST nisDomain )
+
+objectclass ( 1.3.6.1.1.1.2.16 NAME 'automountMap' SUP top STRUCTURAL
+  MUST ( automountMapName )
+  MAY description )
+
+objectclass ( 1.3.6.1.1.1.2.17 NAME 'automount' SUP top STRUCTURAL
+  DESC 'Automount information'
+  MUST ( automountKey $ automountInformation )
+  MAY description )
+## namedObject is needed for groups without members
+objectclass ( 1.3.6.1.4.1.5322.13.1.1 NAME 'namedObject' SUP top
+       STRUCTURAL MAY cn )
+
diff --git a/gosa-core/contrib/openldap/rfc2739.schema b/gosa-core/contrib/openldap/rfc2739.schema
new file mode 100644 (file)
index 0000000..668628e
--- /dev/null
@@ -0,0 +1,134 @@
+# (c) 2004 Martin Konold <martin.konold@erfrakon.de>
+
+# This schema is derived from RFC 2739 and may act as a substitute
+# when used with OpenLDAP as the original schema from RFC 2739 
+# is syntactically not accepted by OpenLDAP 2.2.14
+#
+# Copyright (C) The Internet Society (2000).  All Rights Reserved.
+#
+#  This document and translations of it may be copied and furnished to
+#  others, and derivative works that comment on or otherwise explain it
+#  or assist in its implementation may be prepared, copied, published
+#  and distributed, in whole or in part, without restriction of any
+#  kind, provided that the above copyright notice and this paragraph are
+#  included on all such copies and derivative works.  However, this
+#  document itself may not be modified in any way, such as by removing
+#  the copyright notice or references to the Internet Society or other
+#  Internet organizations, except as needed for the purpose of
+#  developing Internet standards in which case the procedures for
+#  copyrights defined in the Internet Standards process must be
+#  followed, or as required to translate it into languages other than
+#  English.
+#
+#  The limited permissions granted above are perpetual and will not be
+#  revoked by the Internet Society or its successors or assigns.
+#
+#  This document and the information contained herein is provided on an
+#  "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+#  TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+#  BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+#  HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+#  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+# slapd.conf then looks like
+#  include /kolab/etc/openldap/schema/core.schema
+#  include /kolab/etc/openldap/schema/cosine.schema
+#  include /kolab/local/etc/openldap/schema/inetorgperson.schema
+#  include /kolab/local/etc/openldap/schema/rfc2739.schema
+#  include /kolab/local/etc/openldap/schema/kolab2.schema
+
+#
+################################
+# rfc 2739 calendar attributes #
+################################
+
+# contains the URI to a snapshot of the user's entire
+# default calendar
+attributetype ( 1.2.840.113556.1.4.478
+  NAME 'calCalURI'
+  DESC 'RFC2739: URI of entire default calendar'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  USAGE userApplications )
+
+# contains the URI to the user's default
+# busy time data
+attributetype (1.2.840.113556.1.4.479
+  NAME 'calFBURL'
+  DESC 'RFC2739: URI to the users default freebusy data'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  USAGE userApplications )
+
+# contains a URI that can be used to communicate with 
+# the user's calendar
+attributetype (1.2.840.113556.1.4.480
+  NAME 'calCAPURI'
+  DESC 'RFC2739: URI used to communicate with the users calendar'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  USAGE userApplications )
+
+# contains a URI that points to the location to which event
+# requests should be sent for that user
+attributetype (1.2.840.113556.1.4.481
+  NAME 'calCalAdrURI'
+  DESC 'RFC2739: URI for event equests destination'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  USAGE userApplications )
+
+# multi-valued property containing URIs to snapshots of 
+# other calendars that the user may have
+attributetype (1.2.840.113556.1.4.482
+  NAME 'calOtherCalURIs'
+  DESC 'RFC2739: multi-value URI for snapshots of other calendars'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  USAGE userApplications )
+
+# multi-valued property containing URIs to snapshots of other 
+# free/busy data that the user may have
+attributetype (1.2.840.113556.1.4.483
+  NAME 'calOtherFBURLs'
+  DESC 'RFC2739: multi-value URI for other free/busy data'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  USAGE userApplications )
+
+# multi-valued property containing URI to other calendars that
+# the user may have
+attributetype (1.2.840.113556.1.4.484
+  NAME 'calOtherCAPURIs'
+  DESC 'RFC2739: multi-value URI to other calendars'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  USAGE userApplications )
+
+#  URIs to other locations that a user may want
+#   event requests sent to
+attributetype (1.2.840.113556.1.4.485
+  NAME 'calOtherCalAdrURIs'
+  DESC 'RFC2739: multi-value URI to other request destinations'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  USAGE userApplications )
+
+objectclass (1.2.840.113556.1.5.87
+  NAME 'calEntry'
+  DESC 'RFC2739: Calendar Entry'
+  SUP top AUXILIARY
+  MAY ( calCalURI $ 
+        calFBURL $
+        calOtherCalURIs $
+        calOtherFBURLs $
+        calCAPURI $
+        calOtherCAPURIs ) )
diff --git a/gosa-core/contrib/openldap/samba.schema b/gosa-core/contrib/openldap/samba.schema
new file mode 100644 (file)
index 0000000..f71c344
--- /dev/null
@@ -0,0 +1,152 @@
+##
+## schema file for OpenLDAP 2.0.x
+## Schema for storing Samba's smbpasswd file in LDAP
+## OIDs are owned by the Samba Team
+##
+## Prerequisite schemas - uid (cosine.schema)
+##                      - displayName (inetorgperson.schema)
+##
+## 1.3.6.1.4.1.7165.2.1.x - attributetypes
+## 1.3.6.1.4.1.7165.2.2.x - objectclasses
+##
+
+##
+## Password hashes
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.1 NAME 'lmPassword'
+       DESC 'LanManager Passwd'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.2 NAME 'ntPassword'
+       DESC 'NT Passwd'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+##
+## Account flags in string format ([UWDX     ])
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.4 NAME 'acctFlags'
+       DESC 'Account Flags'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE )
+
+## 
+## Password timestamps & policies
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.3 NAME 'pwdLastSet'
+       DESC 'NT pwdLastSet'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.5 NAME 'logonTime'
+       DESC 'NT logonTime'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.6 NAME 'logoffTime'
+       DESC 'NT logoffTime'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.7 NAME 'kickoffTime'
+       DESC 'NT kickoffTime'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.8 NAME 'pwdCanChange'
+       DESC 'NT pwdCanChange'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.9 NAME 'pwdMustChange'
+       DESC 'NT pwdMustChange'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+##
+## string settings
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.10 NAME 'homeDrive'
+       DESC 'NT homeDrive'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.11 NAME 'scriptPath'
+       DESC 'NT scriptPath'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.12 NAME 'profilePath'
+       DESC 'NT profilePath'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.13 NAME 'userWorkstations'
+       DESC 'userWorkstations'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.17 NAME 'smbHome'
+       DESC 'smbHome'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.18 NAME 'domain'
+       DESC 'Windows NT domain to which the user belongs'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
+
+##
+## user and group RID
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.14 NAME 'rid'
+       DESC 'NT rid'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.15 NAME 'primaryGroupID'
+       DESC 'NT Group RID'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+##
+## The smbPasswordEntry objectclass has been depreciated in favor of the
+## sambaAccount objectclass
+##
+#objectclass ( 1.3.6.1.4.1.7165.2.2.1 NAME 'smbPasswordEntry' SUP top AUXILIARY
+#        DESC 'Samba smbpasswd entry'
+#        MUST ( uid $ uidNumber )
+#        MAY  ( lmPassword $ ntPassword $ pwdLastSet $ acctFlags ))
+
+#objectclass ( 1.3.6.1.4.1.7165.2.2.2 NAME 'sambaAccount' SUP top STRUCTURAL
+#      DESC 'Samba Account'
+#      MUST ( uid $ rid ) 
+#      MAY  ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+#               logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $ 
+#               displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
+#               description $ userWorkstations $ primaryGroupID $ domain ))
+
+## The X.500 data model (and therefore LDAPv3) says that each entry can 
+## only have one structural objectclass.  OpenLDAP 2.0 does not enforce 
+## this currently but will in v2.1
+
+objectclass ( 1.3.6.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY
+       DESC 'Samba Auxilary Account'
+       MUST ( uid $ rid ) 
+       MAY  ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+               logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $ 
+               displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
+               description $ userWorkstations $ primaryGroupID $ domain ))
+
+##
+## Used for Winbind experimentation
+##
+#objectclass ( 1.3.6.1.4.1.7165.1.2.2.3 NAME 'uidPool' SUP top AUXILIARY
+#      DESC 'Pool for allocating UNIX uids'
+#      MUST ( uidNumber $ cn ) )
+
+#objectclass ( 1.3.6.1.4.1.7165.1.2.2.4 NAME 'gidPool' SUP top AUXILIARY
+#      DESC 'Pool for allocating UNIX gids'
+#      MUST ( gidNumber $ cn ) )
+
diff --git a/gosa-core/contrib/openldap/samba3.schema b/gosa-core/contrib/openldap/samba3.schema
new file mode 100644 (file)
index 0000000..7dc4de5
--- /dev/null
@@ -0,0 +1,480 @@
+##
+## schema file for OpenLDAP 2.x
+## Schema for storing Samba user accounts and group maps in LDAP
+## OIDs are owned by the Samba Team
+##
+## Prerequisite schemas - uid         (cosine.schema)
+##                      - displayName (inetorgperson.schema)
+##                      - gidNumber   (nis.schema)
+##
+## 1.3.6.1.4.1.7165.2.1.x - attributetypes
+## 1.3.6.1.4.1.7165.2.2.x - objectclasses
+##
+## Printer support
+## 1.3.6.1.4.1.7165.2.3.1.x - attributetypes
+## 1.3.6.1.4.1.7165.2.3.2.x - objectclasses
+##
+## ----- READ THIS WHEN ADDING A NEW ATTRIBUTE OR OBJECT CLASS ------
+##
+## Run the 'get_next_oid' bash script in this directory to find the 
+## next available OID for attribute type and object classes.
+##
+##   $ ./get_next_oid
+##   attributetype ( 1.3.6.1.4.1.7165.2.1.XX NAME ....
+##   objectclass ( 1.3.6.1.4.1.7165.2.2.XX NAME ....
+##
+## Also ensure that new entries adhere to the declaration style
+## used throughout this file
+##
+##    <attributetype|objectclass> ( 1.3.6.1.4.1.7165.2.XX.XX NAME ....
+##                               ^ ^                        ^
+##
+## The spaces are required for the get_next_oid script (and for 
+## readability).
+##
+## ------------------------------------------------------------------
+
+# objectIdentifier SambaRoot 1.3.6.1.4.1.7165
+# objectIdentifier Samba3 SambaRoot:2
+# objectIdentifier Samba3Attrib Samba3:1
+# objectIdentifier Samba3ObjectClass Samba3:2
+
+########################################################################
+##                            HISTORICAL                              ##
+########################################################################
+
+##
+## Password hashes
+##
+#attributetype ( 1.3.6.1.4.1.7165.2.1.1 NAME 'lmPassword'
+#      DESC 'LanManager Passwd'
+#      EQUALITY caseIgnoreIA5Match
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.2 NAME 'ntPassword'
+#      DESC 'NT Passwd'
+#      EQUALITY caseIgnoreIA5Match
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+##
+## Account flags in string format ([UWDX     ])
+##
+#attributetype ( 1.3.6.1.4.1.7165.2.1.4 NAME 'acctFlags'
+#      DESC 'Account Flags'
+#      EQUALITY caseIgnoreIA5Match
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE )
+
+##
+## Password timestamps & policies
+##
+#attributetype ( 1.3.6.1.4.1.7165.2.1.3 NAME 'pwdLastSet'
+#      DESC 'NT pwdLastSet'
+#      EQUALITY integerMatch
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.5 NAME 'logonTime'
+#      DESC 'NT logonTime'
+#      EQUALITY integerMatch
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.6 NAME 'logoffTime'
+#      DESC 'NT logoffTime'
+#      EQUALITY integerMatch
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.7 NAME 'kickoffTime'
+#      DESC 'NT kickoffTime'
+#      EQUALITY integerMatch
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.8 NAME 'pwdCanChange'
+#      DESC 'NT pwdCanChange'
+#      EQUALITY integerMatch
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.9 NAME 'pwdMustChange'
+#      DESC 'NT pwdMustChange'
+#      EQUALITY integerMatch
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+##
+## string settings
+##
+#attributetype ( 1.3.6.1.4.1.7165.2.1.10 NAME 'homeDrive'
+#      DESC 'NT homeDrive'
+#      EQUALITY caseIgnoreIA5Match
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.11 NAME 'scriptPath'
+#      DESC 'NT scriptPath'
+#      EQUALITY caseIgnoreIA5Match
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.12 NAME 'profilePath'
+#      DESC 'NT profilePath'
+#      EQUALITY caseIgnoreIA5Match
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.13 NAME 'userWorkstations'
+#      DESC 'userWorkstations'
+#      EQUALITY caseIgnoreIA5Match
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.17 NAME 'smbHome'
+#      DESC 'smbHome'
+#      EQUALITY caseIgnoreIA5Match
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.18 NAME 'domain'
+#      DESC 'Windows NT domain to which the user belongs'
+#      EQUALITY caseIgnoreIA5Match
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
+
+##
+## user and group RID
+##
+#attributetype ( 1.3.6.1.4.1.7165.2.1.14 NAME 'rid'
+#      DESC 'NT rid'
+#      EQUALITY integerMatch
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.15 NAME 'primaryGroupID'
+#      DESC 'NT Group RID'
+#      EQUALITY integerMatch
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+##
+## The smbPasswordEntry objectclass has been depreciated in favor of the
+## sambaAccount objectclass
+##
+#objectclass ( 1.3.6.1.4.1.7165.2.2.1 NAME 'smbPasswordEntry' SUP top AUXILIARY
+#        DESC 'Samba smbpasswd entry'
+#        MUST ( uid $ uidNumber )
+#        MAY  ( lmPassword $ ntPassword $ pwdLastSet $ acctFlags ))
+
+#objectclass ( 1.3.6.1.4.1.7165.2.2.2 NAME 'sambaAccount' SUP top STRUCTURAL
+#      DESC 'Samba Account'
+#      MUST ( uid $ rid )
+#      MAY  ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+#               logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
+#               displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
+#               description $ userWorkstations $ primaryGroupID $ domain ))
+
+#objectclass ( 1.3.6.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY
+#      DESC 'Samba Auxiliary Account'
+#      MUST ( uid $ rid )
+#      MAY  ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+#              logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
+#              displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
+#              description $ userWorkstations $ primaryGroupID $ domain ))
+
+########################################################################
+##                        END OF HISTORICAL                           ##
+########################################################################
+
+#######################################################################
+##                Attributes used by Samba 3.0 schema                ##
+#######################################################################
+
+##
+## Password hashes
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword'
+       DESC 'LanManager Password'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword'
+       DESC 'MD4 hash of the unicode password'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+##
+## Account flags in string format ([UWDX     ])
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags'
+       DESC 'Account Flags'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE )
+
+##
+## Password timestamps & policies
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.27 NAME 'sambaPwdLastSet'
+       DESC 'Timestamp of the last password update'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.28 NAME 'sambaPwdCanChange'
+       DESC 'Timestamp of when the user is allowed to update the password'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.29 NAME 'sambaPwdMustChange'
+       DESC 'Timestamp of when the password will expire'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.30 NAME 'sambaLogonTime'
+       DESC 'Timestamp of last logon'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.31 NAME 'sambaLogoffTime'
+       DESC 'Timestamp of last logoff'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime'
+       DESC 'Timestamp of when the user will be logged off automatically'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.48 NAME 'sambaBadPasswordCount'
+       DESC 'Bad password attempt count'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.49 NAME 'sambaBadPasswordTime'
+       DESC 'Time of the last bad password attempt'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.55 NAME 'sambaLogonHours'
+       DESC 'Logon Hours'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{42} SINGLE-VALUE )
+
+##
+## string settings
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.33 NAME 'sambaHomeDrive'
+       DESC 'Driver letter of home directory mapping'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.34 NAME 'sambaLogonScript'
+       DESC 'Logon script path'
+       EQUALITY caseIgnoreMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.35 NAME 'sambaProfilePath'
+       DESC 'Roaming profile path'
+       EQUALITY caseIgnoreMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.36 NAME 'sambaUserWorkstations'
+       DESC 'List of user workstations the user is allowed to logon to'
+       EQUALITY caseIgnoreMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.37 NAME 'sambaHomePath'
+       DESC 'Home directory UNC path'
+       EQUALITY caseIgnoreMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName'
+       DESC 'Windows NT domain to which the user belongs'
+       EQUALITY caseIgnoreMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial'
+       DESC ''
+       EQUALITY caseExactMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.54 NAME 'sambaPasswordHistory'
+       DESC 'Concatenated MD4 hashes of the unicode passwords used on this account'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} )
+
+##
+## SID, of any type
+##
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.20 NAME 'sambaSID'
+       DESC 'Security ID'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
+
+
+##
+## Primary group SID, compatible with ntSid
+##
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.23 NAME 'sambaPrimaryGroupSID'
+       DESC 'Primary Group Security ID'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.51 NAME 'sambaSIDList'
+       DESC 'Security ID List'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} )
+
+##
+## group mapping attributes
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.19 NAME 'sambaGroupType'
+       DESC 'NT Group Type'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+##
+## Store info on the domain
+##
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.21 NAME 'sambaNextUserRid'
+       DESC 'Next NT rid to give our for users'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid'
+       DESC 'Next NT rid to give out for groups'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid'
+       DESC 'Next NT rid to give out for anything'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase'
+       DESC 'Base at which the samba RID generation algorithm should operate'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName'
+       DESC 'Share Name'
+       EQUALITY caseIgnoreMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName'
+       DESC 'Option Name'
+       EQUALITY caseIgnoreMatch
+       SUBSTR caseIgnoreSubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption'
+       DESC 'A boolean option'
+       EQUALITY booleanMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption'
+       DESC 'An integer option'
+       EQUALITY integerMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption'
+       DESC 'A string option'
+       EQUALITY caseExactIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption'
+       DESC 'A string list option'
+       EQUALITY caseIgnoreMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.50 NAME 'sambaPrivName' 
+       SUP name )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.52 NAME 'sambaPrivilegeList'
+       DESC 'Privileges List'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.53 NAME 'sambaTrustFlags'
+       DESC 'Trust Password Flags'
+       EQUALITY caseIgnoreIA5Match
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+
+#######################################################################
+##              objectClasses used by Samba 3.0 schema               ##
+#######################################################################
+
+## The X.500 data model (and therefore LDAPv3) says that each entry can
+## only have one structural objectclass.  OpenLDAP 2.0 does not enforce
+## this currently but will in v2.1
+
+##
+## added new objectclass (and OID) for 3.0 to help us deal with backwards
+## compatibility with 2.2 installations (e.g. ldapsam_compat)  --jerry
+##
+objectclass ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY
+       DESC 'Samba 3.0 Auxilary SAM Account'
+       MUST ( uid $ sambaSID )
+       MAY  ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $
+              sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $
+              sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $
+               displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $
+              sambaProfilePath $ description $ sambaUserWorkstations $
+              sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $
+              sambaBadPasswordCount $ sambaBadPasswordTime $
+              sambaPasswordHistory $ sambaLogonHours))
+
+##
+## Group mapping info
+##
+objectclass ( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY
+       DESC 'Samba Group Mapping'
+       MUST ( gidNumber $ sambaSID $ sambaGroupType )
+       MAY  ( displayName $ description $ sambaSIDList ))
+
+##
+## Trust password for trust relationships (any kind)
+##
+objectclass ( 1.3.6.1.4.1.7165.2.2.14 NAME 'sambaTrustPassword' SUP top STRUCTURAL
+       DESC 'Samba Trust Password'
+       MUST ( sambaDomainName $ sambaNTPassword $ sambaTrustFlags )
+       MAY ( sambaSID $ sambaPwdLastSet ))
+
+##
+## Whole-of-domain info
+##
+objectclass ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL
+       DESC 'Samba Domain Information'
+       MUST ( sambaDomainName $ 
+              sambaSID ) 
+       MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $
+             sambaAlgorithmicRidBase ) )
+
+##
+## used for idmap_ldap module
+##
+objectclass ( 1.3.6.1.4.1.7165.2.2.7 NAME 'sambaUnixIdPool' SUP top AUXILIARY
+        DESC 'Pool for allocating UNIX uids/gids'
+        MUST ( uidNumber $ gidNumber ) )
+
+
+objectclass ( 1.3.6.1.4.1.7165.2.2.8 NAME 'sambaIdmapEntry' SUP top AUXILIARY
+        DESC 'Mapping from a SID to an ID'
+        MUST ( sambaSID )
+       MAY ( uidNumber $ gidNumber ) )
+
+objectclass ( 1.3.6.1.4.1.7165.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL
+       DESC 'Structural Class for a SID'
+       MUST ( sambaSID ) )
+
+objectclass ( 1.3.6.1.4.1.7165.1.2.2.10 NAME 'sambaConfig' SUP top AUXILIARY
+       DESC 'Samba Configuration Section'
+       MAY ( description ) )
+
+objectclass ( 1.3.6.1.4.1.7165.2.2.11 NAME 'sambaShare' SUP top STRUCTURAL
+       DESC 'Samba Share Section'
+       MUST ( sambaShareName )
+       MAY ( description ) )
+
+objectclass ( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURAL
+       DESC 'Samba Configuration Option'
+       MUST ( sambaOptionName )
+       MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ 
+             sambaStringListoption $ description ) )
+
+
+objectclass ( 1.3.6.1.4.1.7165.2.2.13 NAME 'sambaPrivilege' SUP top AUXILIARY
+       DESC 'Samba Privilege'
+       MUST ( sambaSID )
+       MAY ( sambaPrivilegeList ) )
+
diff --git a/gosa-core/contrib/openldap/slapd.conf b/gosa-core/contrib/openldap/slapd.conf
new file mode 100644 (file)
index 0000000..ba0c986
--- /dev/null
@@ -0,0 +1,265 @@
+# This is the main ldapd configuration file. See slapd.conf(5) for more
+# info on the configuration options.
+
+##
+## NOTE: This is an example. You should use the template shipped
+##       with your distribution and adapt it to your needs.
+##
+
+# Schema and objectClass definitions, depending on your
+# LDAP setup
+include                /etc/ldap/schema/core.schema
+include                /etc/ldap/schema/cosine.schema
+include        /etc/ldap/schema/inetorgperson.schema
+include        /etc/ldap/schema/openldap.schema
+include                /etc/ldap/schema/nis.schema
+include                /etc/ldap/schema/misc.schema
+include          /etc/ldap/schema/trust.schema
+#include       /etc/ldap/schema/krb5-kdc.schema
+
+# These should be present for GOsa. In case of samba3,
+# replace samba.schema and gosa.schema by samba3.schema
+# and gosa+samba3.schema. Don't include both and remember
+# to adjust the indexing and acl stuff below!
+include                /etc/ldap/schema/samba.schema
+include                /etc/ldap/schema/pureftpd.schema
+include                /etc/ldap/schema/gofon.schema
+include                /etc/ldap/schema/gosystem.schema
+include                /etc/ldap/schema/goto.schema
+include                /etc/ldap/schema/gosa+samba3.schema
+include                /etc/ldap/schema/gofax.schema
+include                /etc/ldap/schema/goserver.schema
+include                /etc/ldap/schema/goto-mime.schema
+
+# Schema check allows for forcing entries to
+# match schemas for their objectClasses's
+schemacheck            on
+
+# Security settings
+# Parameters: sasl, ssf, tls, transport, update_sasl, update_ssf,
+#             update_tls, update_transport
+#security              update_sasl=128,uptate_tls=128
+
+# Require settings
+# Paramters: none, authc, bind, LDAPv3, SASL (strong)
+#require                       authc, LDAPv3
+
+# Allow settings
+# Parameters: none, bind_v2, tls_2_anon, bind_anon_cred, bind_anon_dn,
+#             update_anon
+#allow                 bind_v2
+
+# Disallow settings
+# Parameters: bind_anon, bind_simple_unprotected, tls_2_anon,
+#             bind_simple, bind_krbv4, tls_authc
+
+# Password hash default value
+# Parameters: {SHA}, {SMD5}, {MD4}, {CRYPT}, {CLEARTEXT}
+password-hash          {CRYPT}
+
+# Search base
+defaultsearchbase      dc=gonicus,dc=de
+
+
+# Where clients are refered to if no
+# match is found locally
+#referral      ldap://some.other.ldap.server
+
+## TLS setup, needs certificates
+#TLSCipherSuite HIGH:MEDIUM:+SSLv2
+#TLSCertificateFile /etc/ssl/certs/slapd.pem
+#TLSCertificateKeyFile /etc/ssl/certs/slapd.pem
+
+## SASL setup
+#sasl-authz-policy
+#sasl-host     gosa.gonicus.local
+#sasl-realm    GONICUS.LOCAL
+#sasl-regexp   cn=(.*),ou=(.*) cn=$1,ou=$2,ou=People,dc=gonicus,dc=de
+#sasl-secprops noanonymous
+
+## Kerberos setup
+#srvtab                /etc/krb5.keytab.ldap
+
+# Where the pid file is put. The init.d script
+# will not stop the server if you change this.
+pidfile                /var/run/slapd.pid
+
+# List of arguments that were passed to the server
+argsfile       /var/run/slapd.args
+
+# Read slapd.conf(5) for possible values
+loglevel       1024
+
+# Where the dynamically loaded modules are stored
+modulepath      /usr/lib/ldap
+moduleload      back_hdb
+moduleload      back_monitor
+#moduleload      back_shell
+
+# Some tuning parameters
+#threads               64
+#concurrency           32
+#conn_max_pending      100
+#conn_max_pending_auth 250
+#reverse-lookup                off
+#sizelimit             1000
+#timelimit             30
+#idletimeout           30
+
+# Limits
+#limits        anonymous       size.soft=500 time.soft=5
+#limits user           size=none time.soft=30
+
+access to dn.base=""
+        by * read
+
+access to dn.subtree=cn=Monitor
+        by * read
+
+# Access to schema information
+#access to dn.subtree=""
+#        by * read
+
+# The userPassword/shadow Emtries by default can be
+# changed by the entry owning it if they are authenticated.
+# Others should not be able to see it, except the admin
+# entry below
+access to attrs=userPassword,sambaPwdLastSet,sambaPwdMustChange,sambaPwdCanChange,shadowMax,shadowExpire
+       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
+       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
+       by anonymous auth
+       by self write
+       by * none 
+
+# Deny access to imap/fax/kerberos admin passwords stored
+# in ldap tree
+access to attrs=goImapPassword
+       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
+       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
+       by * none 
+access to attrs=goKrbPassword
+       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
+       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
+       by * none 
+access to attrs=goFaxPassword
+       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
+       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
+       by * none 
+
+# Let servers write last user attribute
+access to attrs=gotoLastUser
+       by * write
+
+# Samba passwords by default can be changed
+# by the entry owning it if they are authenticated.
+# Others should not be able to see it, except the
+# admin entry below
+access to attrs=sambaLmPassword,sambaNtPassword
+       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
+       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
+       by anonymous auth
+       by self write
+       by * none 
+
+# Enable write create access for the terminal admin
+access to dn="ou=incoming,dc=gonicus,dc=de"
+       by dn="cn=terminal-admin,dc=gonicus,dc=de" write
+       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
+       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
+       by * none
+
+access to dn.sub="ou=incoming,dc=gonicus,dc=de"
+       by dn="cn=terminal-admin,dc=gonicus,dc=de" write
+       by dn="cn=ldapadmin,dc=gonicus,dc=de" write
+       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" write
+       by * none
+
+# What trees should be readable, depends on your policy. Either
+# use this entry and specify what should be readable, or leave
+# the access to * => by * read below untouched
+#access to dn="ou=(people|groups)"
+#      by * read
+
+# The admin dn has full write access
+access to *
+       by dn="cn=ldapadmin,dc=gonicus,dc=de" =wrscx
+       by dn.regex="uid=[^/]+/admin\+(realm=GONICUS.LOCAL)?" =wrscx
+       by * read
+#      by peername="ip=127\.0\.0\.1" read
+#      by * none
+
+#######################################################################
+# database definitions
+#######################################################################
+
+# Monitor backend
+database       monitor
+
+# The backend type, ldbm, is the default standard
+database       hdb
+cachesize 5000
+mode             0600
+
+# The base of your directory
+suffix         "dc=gonicus,dc=de"
+checkpoint     512 720
+
+# Sample password is "tester", generate a new one using the mkpasswd
+# utility and put the string after {crypt}
+rootdn "cn=ldapadmin,dc=gonicus,dc=de"
+rootpw  {crypt}OuorOLd3VqvC2
+
+# Indexing
+index   default                                                sub
+index   uid,mail                                               eq
+index   gosaSnapshotDN                                         eq
+index   gosaSnapshotTimestamp                                  eq,sub
+index   gosaMailAlternateAddress,gosaMailForwardingAddress     eq
+index   cn,sn,givenName,ou                                     pres,eq,sub
+index   objectClass                                            pres,eq
+index   uidNumber,gidNumber,memberuid                          eq
+index   gosaSubtreeACL,gosaObject,gosaUser                     pres,eq
+
+# Indexing for Kolab
+#index alias                                                   eq,sub
+#index kolabDeleteFlag                                         eq
+#index kolabHomeServer                                         eq
+#index  member                                                 pres,eq
+
+# Indexing for Samba 3
+index   sambaSID                                               eq
+index   sambaPrimaryGroupSID                                   eq
+index   sambaDomainName                                        eq
+
+# Indexing for DHCP
+#index  dhcpHWAddress                                          eq
+#index  dhcpClassData                                          eq
+
+# Indexing for DNS
+#index  zoneName                                               eq
+#index  relativeDomainName                                     eq
+
+# Where the database file are physically stored
+directory      "/var/lib/ldap"
+
+# Log modifications and write entryUUID
+lastmod on
+
+
+# Example replication using admin account. This will require taking the
+# out put of this database using slapcat(8C), and then importing that into
+# the replica using slapadd(8C).
+
+# Replication setup
+#replogfile /var/log/ldap-replicalog
+#replica host=ldap-2.gonicus.local
+#      binddn="cn=replicator,dc=gonicus,dc=de" bindmethod=simple credentials=secret
+
+# Dummy database for config replication
+#database        shell
+#suffix          "dc=gonicus,dc=shell"
+#search          /etc/ldap/shell/process.pl
+#add            /etc/ldap/shell/process.pl
+
+# End of ldapd configuration file
+
diff --git a/gosa-core/contrib/openldap/trust.schema b/gosa-core/contrib/openldap/trust.schema
new file mode 100644 (file)
index 0000000..6b6fab0
--- /dev/null
@@ -0,0 +1,21 @@
+# this file goes into /etc/openldap/schema or into your schema directory for your LDAP v3 server
+# make sure you have it, otherwise, Directory administrator will complain when changing user accounts
+# unless you don't do schema checking
+
+attributetype ( 5.3.6.1.1.1.1.0 NAME 'trustModel'
+       DESC 'Access scheme'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 5.3.6.1.1.1.1.1 NAME 'accessTo'
+       DESC 'Access to which servers user is allowed'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+objectclass ( 5.3.6.1.1.1.2.0 NAME 'trustAccount' SUP top AUXILIARY
+       DESC 'Sets trust accounts information'
+       MUST ( trustModel )
+       MAY ( accessTo ) )
+
diff --git a/gosa-core/contrib/opensides/README.OpenSides b/gosa-core/contrib/opensides/README.OpenSides
new file mode 100644 (file)
index 0000000..cfd8453
--- /dev/null
@@ -0,0 +1,33 @@
+goSamba.pl - This script will help you populate your ldap tree with
+            the correct attribute when using the smbldap-tools
+            from idealx.
+
+goNagios.pl - This script will help you to manage the authentification
+              users inside of the cgi.cfg, contacts.cfg, contactgroups.cfg
+slapd.conf - The slapd.conf confg for openldap 2.2
+
+nagios.README - how to make the nagios plugin work
+
+pptp.README - how to make the pptp connectivity extension work
+
+phpscheduleit.README - how to make the phpscheduleit extension work
+
+xls-export.README - how to make the xls export xork
+
+
+The php_writeexcel library is coming from
+
+http://www.bettina-attack.de/jonny/projects/php_writeexcel/
+
+Author : <jonny@1409.org>
+
+LICENSE : GNU LESSER GENERAL PUBLIC LICENSE
+
+Bug: 
+
+It doesn't work on php5 we are working on it.
+
+Benoit Mortier <benoit.mortier@opensides.be>
+Guillaume Delecourt <guillaume.delecourt@opensides.be>
+Vincent Seynhaeve <vincent.seynhaeve@opensides.be>
diff --git a/gosa-core/contrib/opensides/glpi.README b/gosa-core/contrib/opensides/glpi.README
new file mode 100644 (file)
index 0000000..52cfcf2
--- /dev/null
@@ -0,0 +1,13 @@
+To use the glpi connectivity extension
+
+1) Add the glpi.schema to your schema directory
+
+2) Remove the comment in front of glpiAccount in gosa.conf
+
+<!--    <tab class="glpiAccount" /> -->
+
+Benoit Mortier
+OpenSides November 2005
+
+
+
diff --git a/gosa-core/contrib/opensides/goNagios.pl b/gosa-core/contrib/opensides/goNagios.pl
new file mode 100755 (executable)
index 0000000..754681d
--- /dev/null
@@ -0,0 +1,391 @@
+#!/usr/bin/perl -w
+
+
+# Copyright (C) 2005 Guillaume Delecourt <guillaume.delecourt@opensides.be>
+# Copyright (C) 2005 Vincent Senave <vincent.senave@opensides.be>
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#
+
+use Net::LDAP;
+use Getopt::Std;
+use Net::LDAP::Schema;
+use Net::LDAP::LDIF;
+use Data::Dumper;
+use MIME::Lite;
+use Sys::Syslog;
+use Switch; 
+use strict;
+
+# Variables a config
+
+my $admindef="admin";
+
+my $cgi_file="cgi.cfg";
+my $contacts_file="contacts.cfg";
+my $contacts_groups_file="contactgroups.cfg";
+
+my $TS_FILE='/tmp/gosa_timestamp';
+my %Options;
+my $nb_user=0;
+my $nb_groupe=0;
+
+my ($i,$file,$ldap,@nagiosmail,
+       $line,$text,$mesg,$entry,$userlist1,$userlist2,$userlist3,$userlist4,
+       $userlist5,$userlist6,$userlist7,$msg,@groupname,@groupmembers,@contactlias,
+       @groupdescription,@servicenotificationoptions,@servicenotificationperiod,
+       @hostnotificationoptions,@hostnotificationperiod,$stdout,
+       $usercontact,$members,@contactname,@nagiosalias,$j,@entries
+);
+
+# Les parametres de connexion proviennent du fichier smbldap-bind.conf
+my $gosa_bind_conf="/etc/gosa_bind.conf";
+my $gosa_ldap_conf="/etc/gosaldap.conf";
+my %config_bind = &read_conf($gosa_bind_conf);
+my %config = &read_conf($gosa_ldap_conf);
+
+my $peopleou=$config{peopleou};
+my $groupeou=$config{groupeou};
+my $base=$config{base};
+my $scope=$config{scope};# par defaut
+my $server=$config{server};
+
+my $admin=$config_bind{masterDN};
+my $password=$config_bind{masterPw};
+
+
+       $stdout.="\n\nSearch new Nagios attribute in user list\n";
+       $stdout.="-"x55;$stdout.="\n";
+       #my $ts = getTS;
+
+#      $ldap = &anonBind;
+#      $mesg = $ldap->search(
+#      base => $LDAP_BASE,
+#      filter => "(&(modifyTimestamp>=$ts)(!(objectClass=gosaUserTemplate)))"
+#      );
+
+       # Put timestamp to file
+       #putTS;
+
+       # Work if changes is present
+       #if($mesg->count > 0)
+       #{
+       #$stdout.="Processing records modified after $ts\n\n";
+       $ldap = Net::LDAP->new($server);
+       $mesg = $ldap->bind($admin,password=>$password) or syslog('error',$mesg->err) && print $mesg->code && die $mesg->error;
+
+       
+
+       #Partie pour l'objectClass NAgios Contact
+       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosContact))", base=>$peopleou,scope=>$scope);
+       @entries = $mesg->entries;
+       $i=0;
+       foreach $entry (@entries) {
+       $stdout.="\nContact $i : \nName\t\t\t";$contactname[$i]=$entry->get_value('uid');$stdout.=$contactname[$i];
+       $stdout.="\n\n\tmail:\t\t\t\t";$nagiosmail[$i]=$entry->get_value('NagiosMail');$stdout.=$nagiosmail[$i];
+       $stdout.="\n\talias:\t\t\t\t";$nagiosalias[$i]=$entry->get_value('NagiosAlias');$stdout.=$nagiosalias[$i];
+       $stdout.="\n\tHostNotificationPeriod:\t\t";$hostnotificationperiod[$i]=$entry->get_value('HostNotificationPeriod');$stdout.=$hostnotificationperiod[$i];
+       $stdout.="\n\tServiceNotificationPeriod:\t";$servicenotificationperiod[$i]=$entry->get_value('ServiceNotificationPeriod');$stdout.=$servicenotificationperiod[$i];
+       $stdout.="\n\tHostNotificationOptions:\t";$hostnotificationoptions[$i]=$entry->get_value('HostNotificationOptions');$stdout.=$hostnotificationoptions[$i];
+       $stdout.="\n\tServiceNotificationOptions:\t";$servicenotificationoptions[$i]=$entry->get_value('ServiceNotificationOptions');$stdout.=$servicenotificationoptions[$i];
+       $stdout.="\n"." "x15;$stdout.="-"x20;$stdout.=" "x 15;                          
+       $usercontact.=$entry->get_value('uid')."  ,";
+       $i++;
+       }
+       $nb_user=$i;
+               
+               
+       #Partie pour l'objectClass NAgios Group
+       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosContactGroup))", base=>$groupeou,scope=>$scope);
+       @entries = $mesg->entries;
+       $i=0;
+       foreach $entry (@entries) {
+       $stdout.="\nGroupe $i : \nName\t\t";$groupname[$i]=$entry->get_value('cn');$stdout.=$groupname[$i];
+       $stdout.="\n\n\talias:\t\t";$groupdescription[$i]=$entry->get_value('description');$stdout.=$groupdescription[$i];
+       $stdout.="\n\tmembers:\t";
+       $j=0;
+       foreach $members($entry->get_value('memberUid'))
+       {
+       $stdout.=$members." ";
+       $groupmembers[$i][$j]=$members;
+       $j++;
+       }
+       $stdout.="\n"." "x15;$stdout.="-"x20;$stdout.=" "x 15;                  
+       $i++;
+       }
+       $nb_groupe=$i;
+
+               $userlist1.=$admindef;
+
+       #Partie pour l'objectClass NagiosAuth
+       $stdout.="\n\n\n\n\nAuthorization for the different Information in Nagios\n"."-" x 53;$stdout.="\n";
+       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedSystemInformation~=checked))", base=>$peopleou,scope=>$scope);
+       @entries = $mesg->entries;
+       $stdout.="\nSystem infos :\t\t";
+       foreach $entry (@entries) {
+       $stdout.= $entry->get_value('uid')."\t";
+       $userlist1.=$entry->get_value('uid')."  ,";
+       }
+       $userlist1.=$admindef;
+
+       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedConfigurationInformation~=checked))", base=>$peopleou,scope=>$scope);
+       @entries = $mesg->entries;
+       $stdout.="\nConfiguration infos :\t";
+       foreach $entry (@entries) {
+       $stdout.= $entry->get_value('uid')."\t";
+       $userlist2.=$entry->get_value('uid')." , ";
+       }
+       $userlist2.=$admindef;
+
+       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedSystemCommands~=checked))", base=>$peopleou,scope=>$scope);
+       @entries = $mesg->entries;
+       $stdout.="\nSystem commands : \t";
+       foreach $entry (@entries) {
+       $stdout.= $entry->get_value('uid')."\t";
+       $userlist3.=$entry->get_value('uid')." , ";
+       }
+       $userlist3.=$admindef;
+
+       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedAllServices~=checked))", base=>$peopleou,scope=>$scope);
+       @entries = $mesg->entries;
+       $stdout.="\nAll services :\t\t";
+       foreach $entry (@entries) {
+       $stdout.= $entry->get_value('uid')."\t";
+       $userlist4.=$entry->get_value('uid')." ,";
+       }
+       $userlist4.=$admindef;
+
+       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedAllHosts~=checked))", base=>$peopleou,scope=>$scope);
+       @entries = $mesg->entries;
+       $stdout.="\nAll hosts :\t\t";
+       foreach $entry (@entries) {
+       $stdout.= $entry->get_value('uid')."\t";
+       $userlist5.=$entry->get_value('uid').",";
+       }
+       $userlist5.=$admindef;
+
+
+       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedAllServiceCommands~=checked))", base=>$peopleou,scope=>$scope);
+       @entries = $mesg->entries;
+       $stdout.="\nAll services commands :\t";
+       foreach $entry (@entries) {
+       $stdout.= $entry->get_value('uid')."\t";
+       $userlist6.=$entry->get_value('uid').",";
+       }
+       $userlist6.=$admindef;
+
+       $mesg = $ldap->search(filter=>"(&(objectClass~=nagiosAuth)(AuthorizedAllHostCommands~=checked))",base=>$peopleou,scope=>$scope);
+       @entries = $mesg->entries;
+       $stdout.="\nAll host commands :\t";
+       foreach $entry (@entries) {
+       $stdout.= $entry->get_value('uid')."\t";
+       $userlist7.=$entry->get_value('uid').",";
+       }
+       $userlist7.=$admindef;
+
+
+       &modiffile_cgi($cgi_file);
+       &modiffile_contact($contacts_file);
+       &modiffile_group($contacts_groups_file);
+       
+       $ldap->unbind;
+       $stdout.="\n";
+       switch($config{stdout})
+       {
+       case "mail"     {&mail()}
+       case "log"      {&writelog()}
+       case "normal"   {print $stdout}
+       }
+       exit(0);
+
+sub modiffile_contact()
+{
+       $file=$_[0];
+       my $text="";
+       open(FH,"$file") || die "Probleme d'ouverture du fichier $file";
+       $stdout.="\n\n"; $stdout.=" "x10;$stdout.="-"x25;$stdout.=" "x10;
+       $stdout.="\n\n$nb_user utilisateur(s) ajouté(s) dans le fichier $file\n";
+       for($i=0;$i<$nb_user;$i++)
+       {
+               $text.="\n\ndefine contact{\n";
+               $text.="\n\tcontact_name \t\t\t".$contactname[$i];
+               $text.="\n\talias \t\t\t\t".$nagiosalias[$i];
+               $text.="\n\thost_notification_period \t".$hostnotificationperiod[$i];
+               $text.="\n\thost_notification_options \t".$hostnotificationoptions[$i];
+               $text.="\n\tservice_notification_period \t".$servicenotificationperiod[$i];
+               $text.="\n\tservice_notification_options \t".$servicenotificationoptions[$i];
+               $text.="\n\temail \t\t\t\t".$nagiosmail[$i];
+               $text.="\n}\n\n";
+       }
+       close(FH);
+       open(FH,"> $file") || die "Probleme d'ouverture du fichier $file";
+       print  FH "$text";
+       close(FH);
+       
+}
+
+sub modiffile_group()
+{
+       $file=$_[0];
+       $text="";
+       $j=0;
+       $i=0;
+       open(FH,"$file") || die "Probleme d'ouverture du fichier $file";
+       $stdout.="\n\n"; $stdout.=" "x10;$stdout.="-"x25;$stdout.=" "x10;
+       $stdout.="\n\n$nb_groupe groupe(s) ajouté(s) dans le fichier $file\n";
+       for($i=0;$i<$nb_groupe;$i++)
+       {
+               $text.="\n\ndefine contact{\n";
+               $text.="\n\tcontactgroup_name \t".$groupname[$i];
+               $text.="\n\talias \t\t\t".$groupdescription[$i];
+               $text.="\n\tmembers \t\t";
+               while(defined($groupmembers[$i][$j]))
+               {
+                       $text.=$groupmembers[$i][$j]." ";
+                       $j++;
+               }
+               $text.="\n}\n\n";
+       }
+       
+       close(FH);
+       open(FH,"> $file") || die "Probleme d'ouverture du fichier $file";
+       print FH "$text";
+       close(FH);
+       
+}
+
+sub modiffile_cgi()
+{
+       $file=$_[0];
+       $text="";
+       open(FH,"$file") || die "Probleme d'ouverture du fichier $file";
+       while(<FH>)
+       {       
+               $line=$_;
+               #$stdout.="$line";
+               if($line =~ /^authorized_for_system_information=*/i){$text.="authorized_for_system_information=".$userlist1}
+               elsif($line =~ /^authorized_for_configuration_information=*/i){$text.="authorized_for_configuration_information=".$userlist2}
+               elsif($line =~ /^authorized_for_system_commands=*/i){$text.="authorized_for_system_commands=".$userlist3}
+               elsif($line =~ /^authorized_for_all_services=*/i){$text.="authorized_for_all_services=".$userlist4."\n"}
+               elsif($line =~ /^authorized_for_all_hosts=*/i){$text.="authorized_for_all_hosts=".$userlist5}
+               elsif($line =~ /^authorized_for_all_service_commands=*/i){$text.="authorized_for_all_host_commands=".$userlist6."\n"}
+               elsif($line =~ /^authorized_for_all_host_commands=*/i){$text.="authorized_for_all_service_commands=".$userlist7}
+               else {$text.=$line};
+       }
+       close(FH);
+       open(FH,"> $file") || die "Probleme d'ouverture du fichier $file";
+       print FH "$text";
+       close(FH);
+       
+}
+
+sub read_conf()
+{
+        my %conf;
+        open (CONFIGFILE, "$_[0]") || die "Unable to open $_[0] for reading !\n";
+        while (<CONFIGFILE>) {
+                chomp($_);
+                ## throw away comments
+                next if ( /^\s*#/ || /^\s*$/ || /^\s*\;/);
+                ## check for a param = value
+                my ($parameter,$value)=read_parameter($_);
+                $value = &subst_configvar($value,\%conf);
+                $conf{$parameter}=$value;
+          }
+        close (CONFIGFILE);
+        return(%conf);
+}
+
+
+
+
+sub read_parameter
+{
+        my $line=shift;
+        ## check for a param = value
+        if ($_=~/=/) {
+          my ($param,$val);
+          if ($_=~/"/) {
+                #my ($param,$val) = ($_=~/(.*)\s*=\s*"(.*)"/);
+                ($param,$val) = /\s*(.*?)\s*=\s*"(.*)"/;
+          } elsif ($_=~/'/) {
+                ($param,$val) = /\s*(.*?)\s*=\s*'(.*)'/;
+          } else {
+                ($param,$val) = /\s*(.*?)\s*=\s*(.*)/;
+          }
+          return ($param,$val);
+        }
+}
+
+sub subst_configvar
+{
+        my $value = shift;
+        my $vars = shift;
+
+        $value =~ s/\$\{([^}]+)\}/$vars->{$1} ? $vars->{$1} : $1/eg;
+        return $value;
+}
+
+sub mail
+{
+
+if($config{email}eq ""){$config{email}="root"}
+
+$msg = MIME::Lite->new(
+             From     => 'monperl@opensides.be',
+             To       => $config{email},
+             Subject  => "Plugin Nagios Gosa",
+             Data     => $stdout
+             );
+
+
+$msg->send;
+}
+
+sub writelog
+{
+       open(F, "> $config{logfile}");
+       print F $stdout;
+       close(F);
+}
+
+# Read timestamp
+sub getTS
+{
+       open(F, "< $TS_FILE");
+       my $ts = <F>;
+       chop $ts;
+       $ts ||= "19700101000000Z";
+       return $ts;
+}
+
+# save timestamp
+sub putTS
+{
+       my $ts = `date -u '+%Y%m%d%H%M%SZ'`;
+       open(F, "> $TS_FILE");
+       $stdout.= F $ts;
+}
+
+#connexion anonyme
+sub anonBind
+{
+       my $ldap = Net::LDAP->new( $server);
+       my $mesg = $ldap->bind();
+       $mesg->code && die $mesg->error;
+       return $ldap;
+}
diff --git a/gosa-core/contrib/opensides/goSamba.pl b/gosa-core/contrib/opensides/goSamba.pl
new file mode 100755 (executable)
index 0000000..ef7b210
--- /dev/null
@@ -0,0 +1,162 @@
+#!/usr/bin/perl
+
+
+# Copyright (C) 2005 Guillaume Delecourt <guillaume.delecourt@opensides.be>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#
+
+use Net::LDAP;
+use Getopt::Std;
+use Net::LDAP::Schema;
+use Net::LDAP::LDIF;
+
+# Variables a config
+$admin="cn=ldapadmin,dc=example,dc=be";
+$password="";
+$peopleou="ou=People,dc=example,dc=be";
+$base="dc=example,dc=be";
+$scope="one"; # par defaut
+$dump_file="myldaptree.ldif";
+$server="localhost";
+
+
+my %Options;
+
+my $ok = getopts('?', \%Options);
+
+#Verifying if help is needed
+if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
+       &help();
+}
+
+print "We backup the whole tree before every operation\n";
+&dump();
+
+$comm=$ARGV[0];
+
+if($comm eq "del" && @ARGV >1 )
+{      
+       print "You asked to delete attribute : ";
+       $i=1;
+       while($ARGV[$i] ne "")
+       {       
+                       print $ARGV[$i]." ";
+                       $i++;
+       }
+       print "\n";
+       $ldap = Net::LDAP->new($server);
+       $ldap->bind($admin,password=>$password);
+
+
+       print "ldap connection" .$ldap;
+
+       $mesg = $ldap->search(filter=>"(objectClass=*)",base=>$peopleou,scope=>$scope);
+       @entries = $mesg->entries;
+
+       foreach $entry (@entries) {
+               $i=1;
+               print $entry->dn()."\n";
+               while($ARGV[$i] ne "")
+               {       
+                       if($ARGV[$i] eq "obj"){$obj=1;$i++;next}
+                       if($obj==1)
+                       {
+                               $mesg = $ldap->modify($entry->dn(), delete => {"ObjectClass"=>"$ARGV[$i]"});
+                               print "\t objectClass: ".$ARGV[$i];
+                       }
+                       else
+                       {
+                               $mesg = $ldap->modify($entry->dn(), delete => [$ARGV[$i]]);
+                               print "\t attribut: ".$ARGV[$i];
+                       }
+                       $obj=0;
+                       $i++;
+               }
+               
+               print "\n";
+       }
+       $ldap->unbind;
+       exit(0);
+}
+elsif($comm eq "gosa" && @ARGV ==1)
+{
+       print "Add GOsa attribute for the following users\n";
+       print "---------------------------------------------\n";
+       $ldap = Net::LDAP->new($server);
+       $ldap->bind($admin,password=>$password);
+       $mesg = $ldap->search(filter=>"&(!(objectClass~=gosaAccount))", base=>$peopleou,scope=>$scope);
+       @entries = $mesg->entries;
+
+       foreach $entry (@entries) {
+               $mesg = $ldap->modify($entry->dn(), add => { "ObjectClass" => "gosaAccount"});
+               $mesg = $ldap->modify($entry->dn(), add => { "ObjectClass" => "organizationalPerson"});
+               $mesg = $ldap->modify($entry->dn(), add => { "ObjectClass" => "Person"});
+               print $entry->dn();
+               print "\n";
+       }
+       $ldap->unbind;
+       exit(0);
+}
+elsif($comm eq "modif" && @ARGV >1)
+{
+       print "Modifications asked\n";
+       print "------------------------\n";
+       $ldap = Net::LDAP->new($server);
+       $ldap->bind($admin,password=>$password);
+
+       $mesg = $ldap->search(filter=>"(objectClass=*)",base=>$peopleou,scope=>$scope);
+       @entries = $mesg->entries;
+       foreach $entry (@entries) {
+       $mesg = $ldap->modify($entry->dn(), replace => { "$ARGV[1]" => "$ARGV[2]" } );
+       print $entry->dn()."\n\tattribut $ARGV[1] modifié avec la valeur $ARGV[2]\n";
+       }
+       $ldap->unbind;
+       exit(0);
+}
+elsif($comm eq "dump" && @ARGV ==1)
+{
+       &dump();
+}
+else
+{
+       &help();
+}
+
+sub help()
+{
+    print_banner;
+    print "Usage: $0 [-?] command\n";
+    print "\t-?        show this help message\n";
+    print "\tgosa -> add GOsa attributes for the whole the people branch !\n";
+    print "\tdel attribut  -> Remove an attribute for the whole people branch !\n";
+    print "\tmodif <attribute> <attribute value> -> to modify the attribute\n";
+    print "\tdump to dump the whole ldap tree\n";
+    exit (1);
+}
+
+sub dump()
+{
+    $ldap = Net::LDAP->new($server) or die "$@";
+    $ldap->bind($admin,password=>$password);
+    my $ldif = Net::LDAP::LDIF->new($dump_file,'w') ;
+    $mesg = $ldap->search ( 
+                               base   => "$base",
+                               filter => "(objectclass=*)"
+                       );
+    $ldif->write_entry($mesg->entries) ;
+    $ldap->unbind;
+}
diff --git a/gosa-core/contrib/opensides/nagios.README b/gosa-core/contrib/opensides/nagios.README
new file mode 100644 (file)
index 0000000..5878e40
--- /dev/null
@@ -0,0 +1,20 @@
+To use the nagios plugin
+
+1) Add the nagios schema to your schema directory
+
+2) Remove the comment in front of nagiosAccount in gosa.conf
+
+<!--                     <plugin acl="default" class="nagiosAccount" icon="monitoring.png"
+                                path="plugins/personal/nagios" /> -->
+
+
+<!--    <nagios>
+                <tab class="nagiosAccount" />
+        </nagios> -->
+
+Benoit Mortier
+Guillaume Delecourt
+OpenSides October-November 2005
+
+
+
diff --git a/gosa-core/contrib/opensides/phpscheduleit.README b/gosa-core/contrib/opensides/phpscheduleit.README
new file mode 100644 (file)
index 0000000..4b634c8
--- /dev/null
@@ -0,0 +1,10 @@
+To use the phpscheduleit connectivity extension
+
+1) Add the schema phpscheduleit.schema in your schema directory
+
+2) Remove the comment in front of phpscheduleitAccount in gosa.conf
+
+<!--    <tab class="pptpAccount" /> -->
+
+Guillaume Delecourt
+OpenSides November 2005
diff --git a/gosa-core/contrib/opensides/pptp.README b/gosa-core/contrib/opensides/pptp.README
new file mode 100644 (file)
index 0000000..556e274
--- /dev/null
@@ -0,0 +1,13 @@
+To use the pptp connectivity extension
+
+1) Add the pptp.schema to your schema directory
+
+2) Remove the comment in front of pptpAccount in gosa.conf
+
+<!--    <tab class="pptpAccount" /> -->
+
+Guillaume Delecourt
+OpenSides November 2005
+
+
+
diff --git a/gosa-core/contrib/opensides/xls-export.README b/gosa-core/contrib/opensides/xls-export.README
new file mode 100644 (file)
index 0000000..e9b0606
--- /dev/null
@@ -0,0 +1,7 @@
+To use the xls export ldapamanager addon uncomment the following line in your gosa.conf :
+
+<!--            <tab class="xlsexport" name="Excel Export" />   -->
+
+Guillaume Delecourt
+Vincent Seynhaeve
+OpenSides October 2005
diff --git a/gosa-core/contrib/openxchange/README.openxchange b/gosa-core/contrib/openxchange/README.openxchange
new file mode 100644 (file)
index 0000000..52effd8
--- /dev/null
@@ -0,0 +1,437 @@
+### Small tutorial for use GOsa with open-xchange ###
+
+Once installed open-xchange (http://www.open-xchange.org) and php4-pgsql 
+module we must do some changes to get open-xchange running with GOsa.
+
+- php.ini must have extension=pg_sql.so
+
+- The webserver must have access to the Postgresql server.
+
+- In the connectivity section of gosa.conf must have something like this:
+                <tab class="oxchangeAccount"
+                        pghost="server"
+                        pguser="openexchange"
+                        pgpasswd="test"
+                        pgdbname="openexchange"
+               />
+
+
+
+We suppose that openxchage is installed in /usr/local/openxchange, 
+and the base for GOsa ldap tree is dc=example,dc=org
+
+
+- Make changes to admintools.conf (/usr/local/openxchange/etc/admintools.conf):
+
+OXBASE="dc=example,dc=org"
+OX_LEAF="$OXBASE"
+# Where are the OX Users
+USER_BASEDN="ou=people,$OX_LEAF"
+# Where are the OX Groups
+GROUP_BASEDN="ou=groups,$OX_LEAF"
+# Where are the OX Resources
+RESOURCES_BASEDN="ou=Resources,ou=ResourceObjects,ou=OxObjects,$OX_LEAF"
+# Where are the OX Resource Groups
+RESOURCE_GROUPS_BASEDN="ou=ResourceGroups,ou=ResourceObjects,ou=OxObjects,$OX_LEAF"
+# Where is the Global Adressbook
+GLOBAL_ADDRESSBOOKDN="o=AddressBook,ou=OxObjects,$OX_LEAF"
+# where are the adressbook admins
+GLOBAL_ADDRESSBOOK_ADMINSDN="cn=AddressAdmins,ou=OxObjects,$GLOBAL_ADDRESSBOOKDN"
+
+- Make changes in login.pm (usually in /usr/lib/cgi-bin/login.pm):
+my $ldap_userBase = 'ou=Users,ou=OxObjects,';
+to
+my $ldap_userBase = 'ou=people,';
+
+- Put the Base in ldap.conf (/usr/local/openxchange/etc/groupware/ldap.conf)
+BASE    dc=example,dc=org
+
+- If you are using as GOsa dnmode "uid", You must change in ldap.properties 
+(/usr/local/openxchange/etc/groupware/ldap.properties):
+
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeuserCountryName=userCountry
+ to
+com.openexchange.groupware.ldap.OXUserObjectAttributeuserCountryName=st
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeimapServerName=imapServer
+ to
+com.openexchange.groupware.ldap.OXUserObjectAttributeimapServerName=gosaMailServer
+
+com.openexchange.groupware.ldap.OXUserObjectAttributesmtpServerName=smtpServer
+ to 
+com.openexchange.groupware.ldap.OXUserObjectAttributesmtpServerName=gosaMailServer
+
+com.openexchange.groupware.ldap.userBaseDN=ou\u003DUsers,ou\u003DOxObjects
+to
+com.openexchange.groupware.ldap.userBaseDN=ou\u003Dpeople
+
+
+
+- If you are using as GOsa dnmode "cn", the ldap.properties  
+(/usr/local/openxchange/etc/groupware/ldap.properties) 
+configuration of open-xchange must be like this:
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributebusinessCategoryName=businessCategory
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributecnName=cn
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeCountryName=c
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributedescriptionName=description
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributedisplayNameName=displayName
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributeemployeeNumberName=employeeNumber
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributeemployeeTypeName=employeeType
+
+com.openexchange.groupware.ldap.OXUserObjectAttributecoName=co
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributehomePhoneName=homePhone
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributehomePostalAddressName=homePostalAddress
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeInfoName=info
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributeinitialsName=initials
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributeinternationaliSDNNumberName=internationaliSDNNumber
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeIPPhoneName=IPPhone
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeotherfacsimiletelephonenumberName=otherfacsimiletelephonenumber
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributeroomNumberName=roomNumber
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributetelexNumberName=telexNumber
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributeuidName=uid
+
+com.openexchange.groupware.ldap.inetOrgPersonClassName=inetOrgPerson
+
+com.openexchange.groupware.ldap.OXUserObjectAttributebirthDayName=birthDay
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeDistributionListName=OXUserDistributionList
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeAnniversaryName=OXUserAnniversary
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeBranchesName=OXUserBranches
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeCategoriesName=OXUserCategories
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeChildrenName=OXUserChildren
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeCityName=OXUserCity
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeCommentName=OXUserComment
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeComRegName=OXUserComReg
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeEmail2Name=OXUserEmail2
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeEmail3Name=OXUserEmail3
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeInstantMessenger2Name=OXUserInstantMessenger2
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeInstantMessengerName=OXUserInstantMessenger
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeMaritalStatusName=OXUserMaritalStatus
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeNickNameName=OXUserNickName
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeOtherCityName=OXUserOtherCity
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeOtherCountryName=OXUserOtherCountry
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeOtherPostalCodeName=OXUserOtherPostalCode
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeOtherStateName=OXUserOtherState
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeOtherStreetName=OXUserOtherStreet
+
+com.openexchange.groupware.ldap.OXUserObjectAttributePositionName=OXUserPosition
+
+com.openexchange.groupware.ldap.OXUserObjectAttributePostalCodeName=OXUserPostalCode
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeProfessionName=OXUserProfession
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeSalesVolumeName=OXUserSalesVolume
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeSpouseNameName=OXUserSpouseName
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeStateName=OXUserState
+
+com.openexchange.groupware.ldap.OXUserObjectAttributesuffixName=OXUserSuffix
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeTaxIDName=OXUserTaxID
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeTeleAssistantName=OXUserTeleAssistant
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeTeleBusiness2Name=OXUserTeleBusiness2
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeTeleCallbackName=OXUserTeleCallback
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeTeleCarName=OXUserTeleCar
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeTeleCompanyName=OXUserTeleCompany
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeTeleFax2Name=OXUserTeleFax2
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeTeleHome2Name=OXUserTeleHome2
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeTeleMobile2Name=OXUserTeleMobile2
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeTeleOtherName=OXUserTeleOther
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeTelePrimaryName=OXUserTelePrimary
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeTeleRadioName=OXUserTeleRadio
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeTeleTTYName=OXUserTeleTTY
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeurlName=url
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef01Name=OXUserUserUndef01
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef02Name=OXUserUserUndef02
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef03Name=OXUserUserUndef03
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef04Name=OXUserUserUndef04
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef05Name=OXUserUserUndef05
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef06Name=OXUserUserUndef06
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef07Name=OXUserUserUndef07
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef08Name=OXUserUserUndef08
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef09Name=OXUserUserUndef09
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef10Name=OXUserUserUndef10
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef11Name=OXUserUserUndef11
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef12Name=OXUserUserUndef12
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef13Name=OXUserUserUndef13
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef14Name=OXUserUserUndef14
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef15Name=OXUserUserUndef15
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef16Name=OXUserUserUndef16
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef17Name=OXUserUserUndef17
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef18Name=OXUserUserUndef18
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef19Name=OXUserUserUndef19
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeUserUndef20Name=OXUserUserUndef20
+
+com.openexchange.groupware.ldap.OXUserObjectClassName=OXUserObject
+
+com.openexchange.groupware.ldap.AllContactUIDSearch=(&(objectClass\u003DinetOrgPerson)(objectClass\u003DOXUserObject))
+
+!com.openexchange.groupware.ldap.AllContactUIDSearchScope=1
+
+com.openexchange.groupware.ldap.credentialsBaseDN=[credentialsBaseDN]
+
+com.openexchange.groupware.ldap.credentialsDN=cn\u003D[uid],[userBaseDN],[credentialsBaseDN]
+
+com.openexchange.groupware.ldap.groupOfNamesAttributememberName=member
+
+com.openexchange.groupware.ldap.AddressAdminsDN=cn\u003DAddressAdmins,[globalAddressBookBaseDN]
+
+com.openexchange.groupware.ldap.globalAddressBookBaseDN=o\u003DAddressBook
+
+com.openexchange.groupware.ldap.GlobalAddressBookEntryDN=cn\u003D[contactid],[globalAddressBookBaseDN]
+
+com.openexchange.groupware.ldap.InternalUsersForeSureNameUIDPatternSearchFilter=(&(objectClass\u003DinetOrgPerson)(objectClass\u003DOXUserObject)(|(sn\u003D[pattern])(givenname\u003D[pattern])(cn\u003D[pattern]))(mailEnabled\u003Dok))
+
+com.openexchange.groupware.ldap.InternalUsersStartingLetterSearchFilter=(&(objectClass\u003DinetOrgPerson)(objectClass\u003DOXUserObject)(sn\u003D[letter]*)(mailEnabled\u003Dok))
+
+com.openexchange.groupware.ldap.UserAddressBookEntryDN=cn\u003D[contactid],[UserAddressBookDN]
+
+com.openexchange.groupware.ldap.localDomainsBaseDN=ou\u003DDNSObjects,ou\u003DAdminObjects
+
+com.openexchange.groupware.ldap.OXVDomainAttributedomainNameName=domainName
+
+com.openexchange.groupware.ldap.LocalDomainsSearchFilter=(&(objectClass\u003DOXVDomainObject)(MTALocaldomain\u003Dtrue))
+
+com.openexchange.groupware.ldap.OXIMAPFolderAttributefnName=fn
+
+com.openexchange.groupware.ldap.sharedFolderBaseDN=ou\u003DSharedFolder
+
+com.openexchange.groupware.ldap.SharedFolderSearchFilter=(&(objectclass\u003DOXIMAPFolderObject)(mailenabled\u003Dok))
+
+!com.openexchange.groupware.ldap.sharedFolderSearchScope=1
+
+com.openexchange.groupware.ldap.OXResourceGroupAttributeresourceGroupAvailableName=resourceGroupAvailable
+
+com.openexchange.groupware.ldap.OXResourceGroupAttributeresourceGroupMemberName=resourceGroupMember
+
+com.openexchange.groupware.ldap.OXResourceGroupAttributeresourceGroupNameName=resourceGroupName
+
+com.openexchange.groupware.ldap.ResourceGroupDN=resourceGroupName\u003D[group],[resourceGroupBaseDN]
+
+com.openexchange.groupware.ldap.ResourceGroupPatternSearchFilter=(&(objectclass\u003DOXResourceGroupObject)(resourceGroupName\u003D[pattern]))
+
+com.openexchange.groupware.ldap.ResourceGroupSearchFilter=(objectclass\u003DOXResourceGroupObject)
+
+!com.openexchange.groupware.ldap.ResourceGroupSearchScope=1
+
+com.openexchange.groupware.ldap.OXResourceAttributeresourceNameName=resourceName
+
+#Where are the resources?
+com.openexchange.groupware.ldap.resourceBaseDN=ou\u003DResources,ou\u003DResourceObjects
+
+com.openexchange.groupware.ldap.ResourceDN=resourceName\u003D[resource],[resourceBaseDN]
+
+#Where are the resource groups?
+com.openexchange.groupware.ldap.resourceGroupBaseDN=ou\u003DResourceGroups,ou\u003DResourceObjects
+
+#Searches resources with the a pattern.
+com.openexchange.groupware.ldap.ResourcePatternSearchFilter=(&(objectclass\u003DOXResourceObject)(resourceName\u003D[pattern]))
+
+!com.openexchange.groupware.ldap.ResourceSearchScope=1
+
+com.openexchange.groupware.ldap.DNForDefaultMail=cn\u003Dmailadmin,[userBaseDN]
+
+com.openexchange.groupware.ldap.Factory.AuthenticationSupport=com.openexchange.groupware.ldap.DefaultAuthenticationSupport
+
+com.openexchange.groupware.ldap.Factory.ContactSupport=com.openexchange.groupware.ldap.DefaultContactSupport
+
+com.openexchange.groupware.ldap.Factory.MailSupport=com.openexchange.groupware.ldap.DefaultMailSupport
+
+com.openexchange.groupware.ldap.Factory.ResourcesHandle=com.openexchange.groupware.ldap.DefaultResourcesHandle
+
+#Class, that implementes UserGroupHandle, ResourcesHandle
+com.openexchange.groupware.ldap.Factory.UserGroupHandle=com.openexchange.groupware.ldap.DefaultUserGroupHandle
+
+#Where to search for groups?
+com.openexchange.groupware.ldap.groupBaseDN=ou\u003DGroups
+
+#Complete dn of a group.
+com.openexchange.groupware.ldap.GroupDN=cn\u003D[gid],[groupBaseDN]
+
+com.openexchange.groupware.ldap.GroupSearchFilter=(objectclass\u003DposixGroup)
+
+#Searches all groups for the user
+com.openexchange.groupware.ldap.GroupsForUserSearchFilter=(&(objectclass\u003DposixGroup)(memberUid\u003D[uid]))
+
+com.openexchange.groupware.ldap.GroupsPatternSearchFilter=(&(objectclass\u003DposixGroup)(cn\u003D[pattern]))
+
+!com.openexchange.groupware.ldap.GroupSearchScope=1
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributefacsimileName=facsimileTelephoneNumber
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributegivenNameName=givenName
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributelabeledURIName=labeledURI
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributelName=l
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributemailName=mail
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributemobileName=mobile
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributeoName=o
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributeouName=ou
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributepagerName=pager
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributepostalCodeName=postalCode
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributepreferredLanguageName=preferredLanguage
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributesnName=sn
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributestName=st
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributestreetName=street
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributetelephoneNumberName=telephoneNumber
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributetitleName=title
+
+com.openexchange.groupware.ldap.OXUserObjectAttributealiasName=alias
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeappointmentDaysName=OXAppointmentDays
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeimapServerName=gosaMailServer
+
+com.openexchange.groupware.ldap.OXUserObjectAttributemailDomainName=mailDomain
+
+com.openexchange.groupware.ldap.OXUserObjectAttributesmtpServerName=gosaMailServer
+
+com.openexchange.groupware.ldap.OXUserObjectAttributetaskDaysName=OXTaskDays
+
+com.openexchange.groupware.ldap.OXUserObjectAttributetimeZoneName=OXTimeZone
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeuserCountryName=st
+
+com.openexchange.groupware.ldap.OXUserObjectAttributevaddressName=vaddress
+
+com.openexchange.groupware.ldap.posixAccountAttributecnName=cn
+
+com.openexchange.groupware.ldap.posixAccountAttributeuidName=uid
+
+com.openexchange.groupware.ldap.posixGroupAttributecnName=cn
+
+com.openexchange.groupware.ldap.posixGroupAttributememberUidName=memberUid
+
+com.openexchange.groupware.ldap.UserAddressBookDN=ou\u003Daddr,cn\u003D[uid],[userBaseDN]
+
+com.openexchange.groupware.ldap.UserAttributeOpenLDAPaciName=OpenLDAPaci
+
+com.openexchange.groupware.ldap.userBaseDN=ou\u003Dpeople
+
+#DN to the user object
+com.openexchange.groupware.ldap.UserDN=cn\u003D[uid],[userBaseDN]
+
+com.openexchange.groupware.ldap.UsersCNPatternSearchFilter=(&(objectclass\u003DposixAccount)(objectClass\u003DinetOrgPerson)(|(cn\u003D[pattern])(givenName\u003D[pattern])(cn\u003D[pattern])))
+
+com.openexchange.groupware.ldap.UserSearchFilter=(&(cn\u003D[uid])(objectClass\u003DOXUserObject))
+
+!com.openexchange.groupware.ldap.UserSearchScope=1
+
+com.openexchange.groupware.ldap.UsersForeSureNamePatternSearchFilter=(&(objectclass\u003DposixAccount)(|(givenName\u003D[pattern])(sn\u003D[pattern])))
+
+com.openexchange.groupware.ldap.UsersForeSureNameUIDPatternSearchFilter=(&(objectclass\u003DposixAccount)(objectClass\u003DinetOrgPerson)(|(givenName\u003D[pattern])(sn\u003D[pattern])(cn\u003D[pattern])))
+
+com.openexchange.groupware.ldap.UsersPatternSearchFilter=(&(objectclass\u003DposixAccount)(cn\u003D[pattern]))
+
+#Define the objectClasses an user object should belong to if you are performing pattern searches.
+com.openexchange.groupware.ldap.UsersPatternSearchObjectClasses=posixAccount,inetOrgPerson,OXUserObject
+
+com.openexchange.groupware.ldap.GlobalAddressBookSearchScope=1
+
+com.openexchange.groupware.ldap.inetOrgPersonAttributejpegPhotoName=jpegPhoto
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeDayViewEndTimeName=OXDayViewEndTime
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeDayViewStartTimeName=OXDayViewStartTime
+
+com.openexchange.groupware.ldap.OXUserObjectAttributeDayViewIntervalName=OXDayViewInterval
+
+!com.openexchange.groupware.ldap.LocalDomainsSearchScope=1
+
+
+
+
+
+
+This configuration is based in documentation gets from 
+http://www.open-xchange.org/oxwiki/
+
+TODO:
+- more testing
+- check cn configuration
+- check addressbook
+- subtree support
+
diff --git a/gosa-core/contrib/patches/imap-2001a-quota.patch b/gosa-core/contrib/patches/imap-2001a-quota.patch
new file mode 100644 (file)
index 0000000..304488d
--- /dev/null
@@ -0,0 +1,20 @@
+diff -Naur imap-2001a/src/c-client/imap4r1.c imap-2001a.patched/src/c-client/imap4r1.c
+--- imap-2001a/src/c-client/imap4r1.c  Wed Nov 14 23:50:55 2001
++++ imap-2001a.patched/src/c-client/imap4r1.c  Wed May 21 09:54:35 2003
+@@ -2358,10 +2358,12 @@
+       do {                    /* for each list item */
+       *s++ = c;               /* write prefix character */
+       if (list) {             /* sigh, QUOTA has bizarre syntax! */
+-        for (t = (char *) list->text.data; *t; *s++ = *t++);
+-        sprintf (s," %lu",list->text.size);
+-        s += strlen (s);
+-        c = ' ';              /* prefix character for subsequent strings */
++        if (list->text.size != 0){
++          for (t = (char *) list->text.data; *t; *s++ = *t++);
++          sprintf (s," %lu",list->text.size);
++          s += strlen (s);
++          c = ' ';            /* prefix character for subsequent strings */
++        }
+       }
+       }
+       while (list = list->next);
diff --git a/gosa-core/contrib/patches/php4-imap-getacl.patch b/gosa-core/contrib/patches/php4-imap-getacl.patch
new file mode 100644 (file)
index 0000000..ae3a235
--- /dev/null
@@ -0,0 +1,97 @@
+--- php-imap-4.3.9/php_imap.c.fix      2004-08-06 15:04:17 +0400
++++ php-imap-4.3.9/php_imap.c  2004-08-06 15:11:43 +0400
+@@ -138,6 +138,7 @@ function_entry imap_functions[] = {
+       PHP_FE(imap_get_quotaroot,                                              NULL)
+       PHP_FE(imap_set_quota,                                                  NULL)
+       PHP_FE(imap_setacl,                                                             NULL)
++        PHP_FE(imap_getacl,                                                             NULL)
+ #endif
+       PHP_FE(imap_mail,                                                               NULL)
+@@ -377,6 +378,22 @@ void mail_getquota(MAILSTREAM *stream, c
+ /* }}} */
+ #endif
++/* {{{ mail_getquota 
++ *
++ * Mail GET_ACL callback
++ * Called via the mail_parameter function in c-client:src/c-client/mail.c
++ */
++void mail_getacl(MAILSTREAM *stream, char *mailbox, ACLLIST *alist)
++{
++      TSRMLS_FETCH();
++
++      /* walk through the ACLLIST */
++      for (; alist; alist = alist->next)
++      {
++              add_assoc_stringl(IMAPG(imap_acl_list), alist->identifier, alist->rights, strlen(alist->rights), 1);
++      }
++}
++/* }}} */
+ /* {{{ php_imap_init_globals
+  */
+@@ -402,6 +419,7 @@ static void php_imap_init_globals(zend_i
+       imap_globals->folderlist_style = FLIST_ARRAY;
+ #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001)
+       imap_globals->quota_return = NULL;
++        imap_globals->imap_acl_list = NIL;
+ #endif
+ }
+ /* }}} */
+@@ -985,6 +1003,37 @@ PHP_FUNCTION(imap_setacl)
+ }
+ /* }}} */
++/* {{{ proto array imap_get_quota(int stream_id, string mailbox)
++      Gets the ACL for a given mailbox */
++PHP_FUNCTION(imap_getacl)
++{
++      zval **streamind, **mailbox;
++      pils *imap_le_struct;
++
++      if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &streamind, &mailbox) == FAILURE) {
++              ZEND_WRONG_PARAM_COUNT();
++      }
++
++      ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap);
++
++      convert_to_string_ex(mailbox);
++
++    /* initializing the special array for the return values */
++    array_init(return_value);
++
++    IMAPG(imap_acl_list) = return_value;
++
++      /* set the callback for the GET_ACL function */
++      mail_parameters(NIL, SET_ACL, (void *) mail_getacl);
++      if(!imap_getacl(imap_le_struct->imap_stream, Z_STRVAL_PP(mailbox))) {
++              php_error(E_WARNING, "c-client imap_getacl failed");
++              RETURN_FALSE;
++      }
++
++    IMAPG(imap_acl_list) = NIL;
++}
++/* }}} */
++
+ #endif /* HAVE_IMAP2000 || HAVE_IMAP2001 */
+--- php-imap-4.3.9/php_imap.h.fix      2004-08-06 15:09:33 +0400
++++ php-imap-4.3.9/php_imap.h  2004-08-06 15:10:42 +0400
+@@ -172,6 +172,7 @@ PHP_FUNCTION(imap_get_quota);
+ PHP_FUNCTION(imap_get_quotaroot);
+ PHP_FUNCTION(imap_set_quota);
+ PHP_FUNCTION(imap_setacl);
++PHP_FUNCTION(imap_getacl);
+ #endif
+@@ -202,6 +203,7 @@ ZEND_BEGIN_MODULE_GLOBALS(imap)
+       unsigned long status_uidvalidity;
+ #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001)
+       zval **quota_return;
++        pval *imap_acl_list;
+ #endif
+ ZEND_END_MODULE_GLOBALS(imap)
diff --git a/gosa-core/contrib/resolutions b/gosa-core/contrib/resolutions
new file mode 100755 (executable)
index 0000000..9233805
--- /dev/null
@@ -0,0 +1,4 @@
+480x320
+640x480
+1024x768
+1280x1024
diff --git a/gosa-core/contrib/scripts/README b/gosa-core/contrib/scripts/README
new file mode 100644 (file)
index 0000000..023f428
--- /dev/null
@@ -0,0 +1,17 @@
+goQuota.pl - run this script via cron (each 5-10 min for examle). It makes
+             cache file (quota.db) with traffic usage and user info from LDAP
+
+goQuotaView.pl - read collected data from quota.db and print it to
+                 stdout in human readable format
+
+goSquid.pl - connect this script to squid
+             redirect_program /usr/local/sbin/goSquid
+
+goAgent.pl - one script to create home directories and mailboxes on
+             filesystem. run it via cron
+  
+mkHash.pl  - create hash file for black list
+
+At this time all scripts have no config file. Please, edit source to configure.
+
+Igor Muratov <migor@altlinux.org>
diff --git a/gosa-core/contrib/scripts/goAgent.pl b/gosa-core/contrib/scripts/goAgent.pl
new file mode 100644 (file)
index 0000000..41b991e
--- /dev/null
@@ -0,0 +1,225 @@
+#!/usr/bin/perl
+#
+# Igor Muratov <migor@altlinux.org>
+#
+# Find changes at LDAP and put this to filesystem
+#
+#
+# Igor Muratov <migor@altlinux.org>
+# 20041004
+# - Added rebuildVirtual function
+# 
+# Igor Muratov <migor@altlinux.org>
+# 20040617:
+# - Changed search fiter to exclude gosaUserTemplate entries
+#
+# Simon Liebold <s.liebold@gmx.de>:
+# 20040617:
+# - Changed $TS_FILE-location
+#
+# $Id: goAgent.pl,v 1.4 2004/11/19 21:46:56 migor-guest Exp $ 
+#
+
+use strict;
+use Net::LDAP;
+
+my $LDAP_HOST='localhost';
+my $LDAP_PORT='389';
+my $LDAP_BASE='dc=example,dc=com';
+#my $LDAP_USER='cn=admin,dc=example,dc=com';
+#my $LDAP_PASS='secret';
+
+my $HOME_DIR='/home';
+my $TS_FILE='/tmp/gosa_timestamp';
+my $KEYS_DIR='/etc/openssh/authorized_keys2';
+my $MAIL_DIR='/var/spool/mail';
+my $VLOCAL='/etc/postfix/virtual_local';
+my $VFORWARD='/etc/postfix/virtual_forward';
+my ($ldap, $mesg, $entry);
+my $virtuals = 0;
+
+# Anonymous bind to LDAP
+sub anonBind
+{
+       my $ldap = Net::LDAP->new( $LDAP_HOST, port => $LDAP_PORT );
+       my $mesg = $ldap->bind();
+       $mesg->code && die $mesg->error;
+       return $ldap;
+}
+
+# Bind as LDAP user
+#sub userBind
+#{
+#      my $ldap = Net::LDAP->new( $LDAP_HOST, port => $LDAP_PORT );
+#      my $mesg = $ldap->bind($LDAP_USER, password=>$LDAP_PASS);
+#      $mesg->code && die $mesg->error;
+#      return $ldap;
+#}
+
+# Read timestamp
+sub getTS
+{
+       open(F, "< $TS_FILE");
+       my $ts = <F>;
+       chop $ts;
+       $ts ||= "19700101000000Z";
+       return $ts;
+}
+
+# save timestamp
+sub putTS
+{
+       my $ts = `date -u '+%Y%m%d%H%M%SZ'`;
+       open(F, "> $TS_FILE");
+       print F $ts;
+}
+
+sub rebuildVirtuals
+{
+       print "Rebuild virtuals table for postfix\n";
+       $mesg = $ldap->search(
+               base => $LDAP_BASE,
+               filter => "(&(objectClass=gosaMailAccount)(gosaMailDeliveryMode=[*L*])(|(mail=*)(gosaMailAlternateAddress=*)))",
+               attrs =>  [
+                       'mail',
+                       'uid',
+                       'gosaMailForwardingAddress',
+                       'memberUid'
+               ],
+       );
+
+       # Work if changes is present
+       open(VIRT, "> $VLOCAL");
+       foreach my $entry ($mesg->all_entries)
+       {
+               foreach my $addr ($entry->get_value('mail'))
+               {
+                       print VIRT "$addr\t";
+                       print VIRT join(",", (
+                               $entry->get_value("uid"),
+                               $entry->get_value("gosaMailForwardingAddress"),
+                               $entry->get_value("memberUid"),
+                       ));
+                       print VIRT "\n";
+               }
+       }
+       close(VIRT);
+       `postmap $VLOCAL`;
+
+       $mesg = $ldap->search(
+               base => $LDAP_BASE,
+               filter => "(&(objectClass=gosaMailAccount)(!(gosaMailDeliveryMode=[*L*]))(|(mail=*)(gosaMailAlternateAddress=*)))",
+               attrs =>  [
+                       'gosaMailForwardingAddress',
+               ],
+       );
+
+       # Work if changes is present
+       open(VIRT, "> $VFORWARD");
+       foreach my $entry ($mesg->all_entries)
+       {
+               foreach my $addr ($entry->get_value('mail'))
+               {
+                       print VIRT "$addr\t";
+                       print VIRT join(",", (
+                               $entry->get_value("gosaMailForwardingAddress"),
+                       ));
+                       print VIRT "\n";
+               }
+       }
+       close(VIRT);
+       `postmap $VFORWARD`;
+}
+
+sub posixAccount
+{
+       my $entry = shift;
+       my $uid = ($entry->get_value('uid'))[0];
+       my $home = ($entry->get_value('homeDirectory'))[0];
+       my $uidNumber = ($entry->get_value('uidNumber'))[0];
+       my $gidNumber = ($entry->get_value('gidNumber'))[0];
+
+       print "Update posixAccount: $uid\n";
+       `install -dD -m0701 -o$uidNumber:$gidNumber $home`;
+       #`install -d -m0700 -o$uidNumber:$gidNumber $home/.ssh`;
+       #`install -d -m0751 -o$uidNumber:$gidNumber $home/.public_html`;
+       print "\tEntry ".$entry->dn()." updated\n";
+}
+
+# Get ssh keys and place to system directory
+sub strongAuthenticationUser
+{
+       my $entry = shift;
+       my $uid = ($entry->get_value('uid'))[0];
+       open(KEYS, "> $KEYS_DIR/$uid");
+       print KEYS $_ foreach ($entry->get_value('userCertificate;binary'));
+}
+
+# Create mailbox if need
+sub inetLocalMailRecipient
+{
+       my $entry = shift;
+       my $uid = ($entry->get_value('uid'))[0];
+       my $mail = ($entry->get_value('mailLocalAddress'))[0];
+       my $addr = ($entry->get_value('mailRoutingAddress'))[0];
+       my $uidNumber = ($entry->get_value('uidNumber'))[0];
+       my $mailbox = "$MAIL_DIR/$uid";
+
+       print "Update inetLocalMailRecipient: $mail\n";
+       if( $uid eq $addr )
+       {
+               if( -f "$mailbox" )
+               {
+                       print "Warning: mailbox $mailbox alredy exists. No changes.\n";
+               } else {
+                       `install -m660 -o$uidNumber -gmail /dev/null $mailbox`;
+               }
+       }
+       print "\tEntry ".$entry->dn()." updated\n";
+}
+
+sub disassemble
+{
+       my $entry = shift;
+
+       foreach my $attr ($entry->get_value('objectClass'))
+       {
+               if( $attr eq "posixAccount" ) {
+                       posixAccount($entry);
+               } elsif( $attr eq "inetLocalMailRecipient" ) {
+                       inetLocalMailRecipient($entry);
+               } elsif( $attr eq "strongAuthenticationUser" ) {
+                       strongAuthenticationUser($entry);
+               } elsif( $attr eq "gosaMailAccount" ) {
+                       $virtuals++;
+               }
+       }
+}
+
+#
+# Start main process
+#
+
+# Read timestamp from file
+my $ts = getTS;
+
+$ldap = anonBind;
+$mesg = $ldap->search(
+       base => $LDAP_BASE,
+       filter => "(&(modifyTimestamp>=$ts)(!(objectClass=gosaUserTemplate)))"
+);
+
+# Put timestamp to file
+putTS;
+
+# Work if changes is present
+if($mesg->count > 0)
+{
+       print "Processing records modified after $ts\n\n";
+
+       foreach my $entry ($mesg->all_entries)
+       {
+               disassemble($entry);
+       }
+       rebuildVirtuals if $virtuals;
+}
diff --git a/gosa-core/contrib/scripts/goQuota.pl b/gosa-core/contrib/scripts/goQuota.pl
new file mode 100644 (file)
index 0000000..cceeffa
--- /dev/null
@@ -0,0 +1,294 @@
+#!/usr/bin/perl
+#
+# Parse squid log and write current traffic usage by users into cache
+#
+# Igor Muratov <migor@altlinux.org>
+#
+# $Id: goQuota.pl,v 1.4 2005/04/03 00:46:14 migor-guest Exp $
+#
+
+use strict;
+use Time::Local;
+use Net::LDAP;
+use DB_File;
+use POSIX qw(strftime);
+
+my $debug = 0;
+$|=1;
+
+my $LDAP;
+my $LDAP_HOST = "localhost";
+my $LDAP_PORT = "389";
+my $LDAP_BASE = "ou=People,dc=example,dc=com";
+
+my $ACCESS_LOG = '/var/log/squid/access.log';
+my $CACHE_FILE = '/var/spool/squid/quota.db';
+my $DEFAULT_PERIOD = 'm';
+my $FORMAT = "A16 A5 S S L A5 L L L";
+
+my %cache;
+my @lines;
+
+sub timestamp
+{
+       return strftime("%a %b %X goQuota[$$]: ", localtime);
+}
+
+sub anonBind
+{
+       my $ldap = Net::LDAP->new( $LDAP_HOST, port => $LDAP_PORT );
+       if($ldap)
+       {
+               my $mesg = $ldap->bind();
+               $mesg->code && warn timestamp, "Can't bind to ldap://$LDAP_HOST:$LDAP_PORT:", $mesg->error, "\n";
+               return $ldap;
+       }
+       else
+       {
+               warn timestamp, "Can't connect to ldap://$LDAP_HOST:$LDAP_PORT\n";
+               return undef;
+       }
+}
+
+# Retrive users's data from LDAP
+sub update_userinfo
+{
+       my $user = shift;
+       my $uid = $user->{uid};
+
+       return undef unless $LDAP;
+
+       # User unknown or cache field is expired
+       my $result = $LDAP->search( base=>$LDAP_BASE,
+               filter=>"(&(objectClass=gosaProxyAccount)(uid=$uid))",
+               attrs=>[
+                       'uid',
+                       'gosaProxyAcctFlags',
+                       'gosaProxyQuota',
+                       'gosaProxyQuotaPeriod',
+                       'gosaProxyWorkingStop',
+                       'gosaProxyWorkingStart',
+                       'modifyTimestamp'
+               ]
+       );
+       $result->code && warn timestamp, "Failed to search: ", $result->error;
+
+       # Get user's data
+       if($result->count)
+       {
+               my $entry = ($result->entries)[0];
+
+               $user->{uid} = ($entry->get_value('uid'))[0];
+               $user->{modifyTimestamp} = ($entry->get_value('modifyTimestamp'))[0];
+               $user->{gosaProxyWorkingStart} = ($entry->get_value('gosaProxyWorkingStart'))[0];
+               $user->{gosaProxyWorkingStop} = ($entry->get_value('gosaProxyWorkingStop'))[0];
+               $user->{gosaProxyAcctFlags} = ($entry->get_value('gosaProxyAcctFlags'))[0];
+
+               my ($quota, $unit) = ($entry->get_value('gosaProxyQuota'))[0] =~ /(\d+)(\S)/g;
+               $user->{gosaProxyQuota} = $quota;
+               $user->{gosaProxyQuota} *= 1024 if $unit =~ /[Kk]/;
+               $user->{gosaProxyQuota} *= 1048576 if $unit =~ /[Mm]/;
+               $user->{gosaProxyQuota} *= 1073741824 if $unit =~ /[Gg]/;
+
+               $user->{gosaProxyQuotaPeriod} = ($entry->get_value('gosaProxyQuotaPeriod'))[0] || $DEFAULT_PERIOD;
+               # Return
+               warn timestamp, "User $uid found in LDAP.\n";
+               return 1;
+       } else {
+               # Unknown user
+               warn timestamp, "User $uid does not exists in LDAP.\n";
+               $user->{uid} = $uid;
+               $user->{gosaProxyAcctFlags} = '[FTB]';
+               $user->{gosaProxyQuota} = 0;
+               $user->{gosaProxyQuotaPeriod} = 'y';
+               return 0;
+       }
+}
+
+sub get_update
+{
+       my $ts = shift;
+       my %update;
+       my $result = $LDAP->search( base=>$LDAP_BASE,
+               filter=>"(&(objectClass=gosaProxyAccount)(modifyTimestamp>=$ts))",
+               attrs=>'uid'
+       );
+
+       # Get user's data
+       if($result->count)
+       {
+               my $entry = ($result->entries)[0];
+               $update{($entry->get_value('uid'))[0]}++;
+       }
+       return %update;
+}
+
+# Check quota
+sub update_quota
+{
+       my $user = shift;
+       my $uid = $user->{uid};
+
+       my $period = 0;
+       $period = 3600 if $user->{gosaProxyQuotaPeriod} eq 'h';
+       $period = 86400 if $user->{gosaProxyQuotaPeriod} eq 'd';
+       $period = 604800 if $user->{gosaProxyQuotaPeriod} eq 'w';
+       $period = 2592000 if $user->{gosaProxyQuotaPeriod} eq 'm';
+       $period = 220752000 if $user->{gosaProxyQuotaPeriod} eq 'y';
+
+       if($user->{lastRequest} - $user->{firstRequest} > $period)
+       {
+               if($user->{trafficUsage} > $user->{gosaProxyQuota})
+               {
+                       warn timestamp, "Reduce quota for $uid while $period seconds.\n";
+                       $user->{trafficUsage} -= $user->{gosaProxyQuota};
+                       $user->{firstRequest} += $period;
+               }
+               else
+               {
+                       warn timestamp, "Restart quota for $uid.\n";
+                       $user->{trafficUsage} = 0;
+                       $user->{firstRequest} = $user->{lastRequest};
+               }
+       }
+}
+
+sub dump_data
+{
+       my $user = shift;
+       print "User: ",$user->{uid},"\n";
+       print "\t",$user->{modifyTimestamp},"\n";
+       print "\t",$user->{gosaProxyAcctFlags},"\n";
+       print "\t",$user->{gosaProxyWorkingStart},"\n";
+       print "\t",$user->{gosaProxyWorkingStop},"\n";
+       print "\t",$user->{gosaProxyQuota},"\n";
+       print "\t",$user->{gosaProxyQuotaPeriod},"\n";
+       print "\t",$user->{trafficUsage},"\n";
+       print "\t",$user->{firstRequest},"\n";
+       print "\t",$user->{lastRequest},"\n";
+}
+
+sub unpack_user
+{
+       my $uid = shift;
+       my $user;
+
+       $user->{uid} = $uid;
+       (
+               $user->{modifyTimestamp},
+               $user->{gosaProxyAcctFlags},
+               $user->{gosaProxyWorkingStart},
+               $user->{gosaProxyWorkingStop},
+               $user->{gosaProxyQuota},
+               $user->{gosaProxyQuotaPeriod},
+               $user->{trafficUsage},
+               $user->{firstRequest},
+               $user->{lastRequest}
+       ) = unpack($FORMAT, $cache{$uid});
+
+       return $user;
+}
+
+sub pack_user
+{
+       my $user = shift;
+
+       $cache{$user->{uid}} = pack(
+               $FORMAT,
+               $user->{modifyTimestamp},
+               $user->{gosaProxyAcctFlags},
+               $user->{gosaProxyWorkingStart},
+               $user->{gosaProxyWorkingStop},
+               $user->{gosaProxyQuota},
+               $user->{gosaProxyQuotaPeriod},
+               $user->{trafficUsage},
+               $user->{firstRequest},
+               $user->{lastRequest}
+       );
+}
+
+#--------------------------------------
+$LDAP = anonBind or die timestamp, "No lines processed.\n";
+
+# This is a first time parsing?
+my $firstStart = 1;
+$firstStart = 0 if -e $CACHE_FILE;
+
+# Open log file and cache
+my $cache = tie(%cache, 'DB_File', $CACHE_FILE, O_CREAT|O_RDWR);
+my $log = tie(@lines, 'DB_File', $ACCESS_LOG, O_RDWR, 0640, $DB_RECNO)
+       or die "Cannot open file $ACCESS_LOG: $!\n";
+
+# Mark users which updated in LDAP
+my %updated;
+if(! $firstStart)
+{
+       my $ts = strftime("%Y%m%d%H%M%SZ", gmtime);
+       %updated = get_update($cache{MODIFY_TIMESTAMP} || "19700101000000Z");
+
+       my @count = %updated;
+       $cache{MODIFY_TIMESTAMP} = $ts if $#count;
+
+       foreach my $u (keys %updated)
+       {
+               warn timestamp, "User $u has been updated in LDAP. Refresh data.\n";
+               my $user = unpack_user($u);
+               update_userinfo($user);
+               pack_user($user);
+       }
+}
+
+# Processing log file
+my $index = $cache{TIMESTAMP} < (split / +/, $lines[0])[0]
+       ? 0 : $cache{STRING_NUMBER};
+warn timestamp, "Cache update start at line $index.\n";
+while($lines[$index])
+{
+       # There are array named lines with elements
+       # 0 - line timestamp
+       # 1 - ?? (unused)
+       # 2 - client's IP (unused)
+       # 3 - squid's cache status TEXT_CODE/num_code (unused)
+       # 4 - object size in bytes
+       # 5 - metod (unused)
+       # 6 - URL (unused)
+       # 7 - username
+       # 8 - load status TYPE/source
+       # 9 - mime type (unused)
+       my @line = split / +/, $lines[$index++];
+
+       # Skip line if have no incoming traffic
+       (my $errcode = $line[8]) =~ s/\/\S+//;
+       next if $errcode eq "NONE";
+
+       # Get data from cache
+       (my $uid = $line[7]) =~ s/^-$/anonymous/;
+       my $user = unpack_user($uid);
+
+       # Update user info from LDAP if need
+       if ( !exists($cache{$uid}) )
+       {
+               warn timestamp, "User $uid is not in cache. Go to search LDAP.\n";
+               update_userinfo($user);
+       }
+
+       # Update traffic info
+       $user->{trafficUsage} += $line[4];
+       $user->{firstRequest} |= $line[0];
+       $user->{lastRequest} = $line[0];
+
+       update_quota($user);
+       pack_user($user);
+
+       dump_data($user) if $debug;
+
+       $cache{TIMESTAMP} = $user->{lastRequest};
+}
+
+warn timestamp, $index - $cache{STRING_NUMBER}, " new lines processed.\n";
+$cache{STRING_NUMBER} = $index;
+
+$LDAP->unbind;
+untie @lines;
+untie %cache;
+
diff --git a/gosa-core/contrib/scripts/goQuotaView.pl b/gosa-core/contrib/scripts/goQuotaView.pl
new file mode 100644 (file)
index 0000000..7dd1497
--- /dev/null
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+#
+# Show user info from cache
+#
+# Igor Muratov <migor@altlinux.org>
+#
+# $Id: goQuotaView.pl,v 1.2 2005/04/03 00:46:14 migor-guest Exp $
+#
+
+use strict;
+use DB_File;
+
+my $CACHE_FILE = '/var/spool/squid/quota.db';
+my $FORMAT = "A16 A5 S S L A5 L L L";
+
+my %cache;
+
+sub min2time
+{
+       my $min = shift;
+       return sprintf("%2d:%02d",$min/60,$min%60);
+}
+
+sub show_user
+{
+       my $uid = shift;
+
+       my (
+               $modifyTimestamp, $gosaProxyAcctFlags, $gosaProxyWorkingStart,
+               $gosaProxyWorkingStop, $gosaProxyQuota, $gosaProxyQuotaPeriod,
+               $trafficUsage, $firstRequest, $lastRequest
+       ) = unpack($FORMAT, $cache{$uid});
+
+       my ($ts_Y, $ts_M, $ts_D, $ts_h, $ts_m, $ts_s)
+               = $modifyTimestamp =~ /(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/g;
+       my $ts = "$ts_D\.$ts_M\.$ts_Y $ts_h:$ts_m:$ts_s GMT";
+
+       $gosaProxyAcctFlags =~ s/[\[\]]//g;
+       $gosaProxyAcctFlags =~ s/F/unwanted content, /g;
+       $gosaProxyAcctFlags =~ s/T/work time, /g;
+       $gosaProxyAcctFlags =~ s/B/traffic/g;
+
+       $gosaProxyQuotaPeriod =~ s/h/hour/;
+       $gosaProxyQuotaPeriod =~ s/d/day/;
+       $gosaProxyQuotaPeriod =~ s/w/week/;
+       $gosaProxyQuotaPeriod =~ s/m/month/;
+       $gosaProxyQuotaPeriod =~ s/y/year/;
+
+       $firstRequest = localtime($firstRequest);
+       $lastRequest = localtime($lastRequest);
+
+       printf "User: %s
+  LDAP modify timestamp\t%s
+  Limited by\t\t%s
+  Work time from\t%s
+  Work time to\t\t%s
+  Quota period\t\tOne %s
+  Traffic quota size\t%s bytes
+  Current traffic usage\t%s bytes
+  First request time\t%s
+  Last request time\t%s\n",
+       $uid, $ts, $gosaProxyAcctFlags, min2time($gosaProxyWorkingStart),
+       min2time($gosaProxyWorkingStop), $gosaProxyQuotaPeriod, $gosaProxyQuota,
+       $trafficUsage, $firstRequest, $lastRequest;
+}
+
+#------------------------
+tie(%cache, 'DB_File', $CACHE_FILE, O_CREAT|O_RDWR);
+
+if($ARGV[0])
+{
+       show_user($ARGV[0]);
+}
+else
+{
+       print "eee\n";
+       printf "LAST STRING: %d\nLAST CACHE UPDATE: %s\nLDAP LAST CHANGE:  %s\n",
+               $cache{STRING_NUMBER},
+               time2str("%d.%m.%Y %H:%M:%S",$cache{TIMESTAMP}),
+               $cache{MODIFY_TIMESTAMP};
+
+       foreach my $user (keys %cache)
+       {
+               next if $user eq "TIMESTAMP";
+               next if $user eq "STRING_NUMBER";
+               next if $user eq "MODIFY_TIMESTAMP";
+               show_user($user);
+       }
+}
+
+untie %cache;
diff --git a/gosa-core/contrib/scripts/goSquid.pl b/gosa-core/contrib/scripts/goSquid.pl
new file mode 100644 (file)
index 0000000..b91db16
--- /dev/null
@@ -0,0 +1,136 @@
+#!/usr/bin/perl
+#
+# Squid redirect programm for GOsa project
+#
+# Igor Muratov <migor@altlinux.org>
+#
+# $Id: goSquid.pl,v 1.3 2005/04/03 00:46:14 migor-guest Exp $
+#
+
+use strict;
+use POSIX qw(strftime);
+use Time::Local;
+use DB_File;
+
+my $debug = 0;
+$|=1;
+
+my $DEFAULT_URL = "http://www.squid-cache.org/Squidlogo2.gif";
+my $black_list = '/var/spool/squid/domains.db';
+my $cache_file = '/var/spool/squid/quota.db';
+my $format = "A16 A5 S S L A5 L L L";
+
+my %cache;
+my %blacklist;
+
+sub timestamp
+{
+       return strftime("%a %b %X goSquid[$$]: ", localtime);
+}
+
+# Check url in our blacklist
+sub unwanted_content
+{
+       my $url = shift;
+       my $host = (split(/\//, $url))[2];
+
+       return 1 if exists($blacklist{$host}) and $blacklist{$host} > 0;
+       return undef;
+}
+
+# Check work time limit
+sub work_time
+{
+       my $user = shift;
+       my ($min,$hour) = (localtime)[1,2];
+       my $time = $hour * 60 + $min;
+
+       return 1 if $user->{gosaProxyWorkingStart} < $time and $user->{gosaProxyWorkingStop} > $time;
+       return undef;
+}
+
+sub quota_exceed
+{
+       my $user = shift;
+
+       return 1 if $user->{trafficUsage} > $user->{gosaProxyQuota};
+       return undef;
+}
+
+sub check_access
+{
+       my ($user, $url) = @_;
+
+       $user->{timed} = 0;
+       $user->{quoted} = 0;
+       $user->{filtered} = 0;
+
+       if($user->{gosaProxyAcctFlags} =~ m/[F]/)
+       {
+               # Filter unwanted content
+               $user->{filtered} = 1 if unwanted_content($url);
+       }
+       if($user->{gosaProxyAcctFlags} =~ m/[T]/)
+       {
+               # Filter unwanted content during working hours only
+               $user->{timed} = 1 if work_time($user);
+       }
+       if($user->{gosaProxyAcctFlags} =~ m/B/)
+       {
+               $user->{quoted} = 1 if quota_exceed($user);
+       }
+}
+
+#--------------------------------------
+while (<>) {
+       my ($url, $addr, $uid, $method) = split;
+       my $time = timelocal(localtime);
+       tie(%blacklist, 'DB_File', $black_list, O_RDONLY);
+       tie(%cache, 'DB_File', $cache_file, O_RDONLY);
+
+       if( exists($cache{$uid}) )
+       {
+               my $user;
+               $user->{uid} = $uid;
+               (
+                       $user->{modifyTimestamp},
+                       $user->{gosaProxyAcctFlags},
+                       $user->{gosaProxyWorkingStart},
+                       $user->{gosaProxyWorkingStop},
+                       $user->{gosaProxyQuota},
+                       $user->{gosaProxyQuotaPeriod},
+                       $user->{trafficUsage},
+                       $user->{firstRequest},
+                       $user->{lastRequest}
+               ) = unpack($format, $cache{$uid});
+
+               check_access($user, $url);
+
+               if($user->{'disabled'})
+               {
+                       warn timestamp, "Access denied for unknown user $uid\n";
+               }
+               elsif($user->{'timed'})
+               {
+                       warn timestamp, "Access denied by worktime for $uid\n";
+               }
+               elsif($user->{'quoted'})
+               {
+                       warn timestamp, "Access denied by quota for $uid\n";
+               }
+               elsif($user->{'filtered'})
+               {
+                       warn timestamp, "Content $url filtered for $uid\n";
+               }
+               else
+               {
+                       print "$url\n";
+                       next;
+               }
+       }
+
+       untie %blacklist;
+       untie %cache;
+
+       print "$DEFAULT_URL\n";
+}
diff --git a/gosa-core/contrib/scripts/gosa b/gosa-core/contrib/scripts/gosa
new file mode 100755 (executable)
index 0000000..d6cd93a
--- /dev/null
@@ -0,0 +1,128 @@
+#!/bin/sh
+# Start script for GOsa to be started via mozilla
+
+url=""
+if [ $# -ne 1 ]; then
+       echo "Usage: $(basename $0) <URL>"
+       exit 1
+fi
+
+# Check for presence of gosa profile
+if [ ! -d $HOME/.mozilla/firefox/*.gosa ]; then
+       firefox -CreateProfile gosa
+       config=`echo $HOME/.mozilla/firefox/*.gosa/`
+
+       cat << EOF > $config/prefs.js
+# Mozilla User Preferences
+
+/* Do not edit this file.
+ *
+ * If you make changes to this file while the browser is running,
+ * the changes will be overwritten when the browser exits.
+ *
+ * To make a manual change to preferences, you can visit the URL about:config
+ * For more information, see http://www.mozilla.org/unix/customizing.html#prefs
+ */
+
+user_pref("app.update.autoUpdateEnabled", false);
+user_pref("app.update.enabled", false);
+user_pref("browser.download.folderList", 2);
+user_pref("browser.download.manager.showWhenStarting", false);
+user_pref("browser.formfill.enable", false);
+user_pref("browser.preferences.lastpanel", 1);
+user_pref("browser.search.selectedEngine", "Damnfresh");
+user_pref("browser.startup.homepage", "$url");
+user_pref("browser.startup.homepage_override.mstone", "rv:1.8.1.1");
+user_pref("extensions.disabledObsolete", true);
+user_pref("extensions.lastAppVersion", "2.0.0.1");
+user_pref("extensions.update.autoUpdateEnabled", false);
+user_pref("intl.charsetmenu.browser.cache", "ISO-8859-1");
+user_pref("network.cookie.prefsMigrated", true);
+user_pref("security.OCSP.URL", "");
+user_pref("security.OCSP.signingCA", "Builtin Object Token:IPS CLASE1 root");
+user_pref("security.warn_entering_secure", false);
+user_pref("security.warn_leaving_secure", false);
+user_pref("security.warn_submit_insecure", false);
+user_pref("security.warn_viewing_mixed", false);
+user_pref("signon.rememberSignons", false);
+user_pref("security.warn_submit_insecure", false);
+EOF
+
+       cat << EOF > $config/84795799.s
+#2c
+http://vserver-02
+.
+EOF
+
+       [ ! -d $config/chrome ] && mkdir -p $config/chrome
+       cat << EOF > $config/chrome/userChrome.css
+#main-menubar {
+        display: none;
+}
+#navigator-throbber {
+        display: none;
+}
+EOF
+
+cat << EOF > $config/localstore.rdf
+<?xml version="1.0"?>
+<RDF:RDF xmlns:NC="http://home.netscape.com/NC-rdf#"
+         xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+  <RDF:Description RDF:about="chrome://mozapps/content/downloads/unknownContentType.xul#unknownContentType"
+                   screenX="267"
+                   screenY="304" />
+  <RDF:Description RDF:about="chrome://browser/content/browser.xul#PersonalToolbar"
+                   currentset="__empty"
+                   collapsed="true" />
+  <RDF:Description RDF:about="chrome://browser/content/browser.xul#toolbar-menubar"
+                   currentset="__empty"
+                   collapsed="true" />
+  <RDF:Description RDF:about="chrome://browser/content/browser.xul#sidebar-box"
+                   collapsed="true"
+                   sidebarcommand=""
+                   width=""
+                   src="" />
+  <RDF:Description RDF:about="chrome://browser/content/browser.xul#status-bar"
+                   hidden="true" />
+  <RDF:Description RDF:about="chrome://browser/content/browser.xul">
+    <NC:persist RDF:resource="chrome://browser/content/browser.xul#main-window"/>
+    <NC:persist RDF:resource="chrome://browser/content/browser.xul#sidebar-box"/>
+    <NC:persist RDF:resource="chrome://browser/content/browser.xul#sidebar-title"/>
+    <NC:persist RDF:resource="chrome://browser/content/browser.xul#nav-bar"/>
+    <NC:persist RDF:resource="chrome://browser/content/browser.xul#PersonalToolbar"/>
+    <NC:persist RDF:resource="chrome://browser/content/browser.xul#toolbar-menubar"/>
+  </RDF:Description>
+  <RDF:Description RDF:about="chrome://mozapps/content/downloads/unknownContentType.xul">
+    <NC:persist RDF:resource="chrome://mozapps/content/downloads/unknownContentType.xul#unknownContentType"/>
+  </RDF:Description>
+  <RDF:Description RDF:about="chrome://global/content/customizeToolbar.xul">
+    <NC:persist RDF:resource="chrome://global/content/customizeToolbar.xul#CustomizeToolbarWindow"/>
+  </RDF:Description>
+  <RDF:Description RDF:about="chrome://help/content/help.xul#help"
+                   screenX="350"
+                   screenY="225"
+                   width="700"
+                   height="550" />
+  <RDF:Description RDF:about="chrome://browser/content/browser.xul#main-window"
+                   screenX="50"
+                   screenY="25"
+                   sizemode="normal"
+                   width="994"
+                   height="962" />
+  <RDF:Description RDF:about="chrome://help/content/help.xul">
+    <NC:persist RDF:resource="chrome://help/content/help.xul#help"/>
+  </RDF:Description>
+  <RDF:Description RDF:about="chrome://browser/content/browser.xul#nav-bar"
+                   currentset="__empty"
+                   collapsed="true" />
+</RDF:RDF>
+
+
+
+EOF
+fi
+
+
+# Start mozilla with GOsa profile
+firefox -P gosa
+
diff --git a/gosa-core/contrib/scripts/mkHash.pl b/gosa-core/contrib/scripts/mkHash.pl
new file mode 100644 (file)
index 0000000..84f4bd1
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/perl
+
+use strict;
+use DB_File;
+
+my $db = "/var/spool/squid/domains.db";
+my %db;
+
+tie(%db, 'DB_File', $db);
+
+while(<>)
+{
+       chomp;
+       unless(exists($db{$_}))
+       {
+               $db{$_} = 1;
+       }
+}
+
+untie %db;
diff --git a/gosa-core/contrib/scripts/net-resolver.sh b/gosa-core/contrib/scripts/net-resolver.sh
new file mode 100755 (executable)
index 0000000..bd12026
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# Check for number of parameters
+if [ $# -ne 1 ]; then
+       echo Usage: $(basename $0) dns-name
+       exit 1
+fi
+
+# Check for needed commands
+for cmd in /usr/bin/host /usr/bin/fping /usr/sbin/arp; do
+       if [ ! -x $cmd ]; then
+               echo $cmd command not found - aborting
+               exit 2
+       fi
+       eval $(echo ${cmd##*/}=$cmd)
+done
+
+mac=""
+ip=$(LANG=C $host $1 | grep address | head -n1 | sed 's/^.*[^0-9]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/g')
+if [ -z "$ip" ]; then
+       echo ";"
+       exit 0
+fi
+if $fping -c1 -r3 -t500 $ip &> /dev/null; then
+       mac=$($arp -n | awk "/^$ip/ {print \$3}")
+fi
+echo "$ip;$mac"
diff --git a/gosa-core/contrib/scripts/sieve_vacation/IMAP/Sieve.pm b/gosa-core/contrib/scripts/sieve_vacation/IMAP/Sieve.pm
new file mode 100644 (file)
index 0000000..ec10808
--- /dev/null
@@ -0,0 +1,401 @@
+# $Id: Sieve.pm,v 0.4.9b 2001/06/15 19:25:00 alain Exp $
+
+package IMAP::Sieve;
+
+use strict;
+use Carp;
+use IO::Select;
+use IO::Socket;
+use IO::Socket::INET;
+#use Text::ParseWords qw(parse_line);
+use Cwd;
+
+use vars qw($VERSION);
+
+$VERSION = '0.4.9b';
+
+sub new {
+    my $class = shift;
+    my $self = {};
+    bless $self, $class;
+    if ((scalar(@_) % 2) != 0) {
+       croak "$class called with incorrect number of arguments";
+    }
+    while (@_) {
+       my $key = shift(@_);
+       my $value = shift(@_);
+       $self->{$key} = $value;
+    }
+    $self->{'CLASS'} = $class;
+    $self->_initialize;
+    return $self;
+}
+
+sub _initialize {
+    my $self = shift;
+    my ($len,$userpass,$encode);
+    if (!defined($self->{'Server'})) {
+       croak "$self->{'CLASS'} not initialized properly : Server parameter missing";
+    }
+    if (!defined($self->{'Port'})) {
+       $self->{'Port'} = 2000; # default sieve port;
+    }
+    if (!defined($self->{'Login'})) {
+       croak "$self->{'CLASS'} not initialized properly : Login parameter missing";
+    }
+    if (!defined($self->{'Password'})) {
+       croak "$self->{'CLASS'} not initialized properly : Password parameter missing";
+    }
+    if (!defined($self->{'Proxy'})) {
+       $self->{'Proxy'} = ''; # Proxy;
+    }
+    if (defined($self->{'SSL'})) {
+       my $cwd= cwd;
+       my %ssl_defaults = (
+                         'SSL_use_cert' => 0,
+                         'SSL_verify_mode' => 0x00,
+                         'SSL_key_file' => $cwd."/certs/client-key.pem",
+                         'SSL_cert_file' => $cwd."/certs/client-cert.pem",
+                         'SSL_ca_path' => $cwd."/certs",
+                         'SSL_ca_file' => $cwd."/certs/ca-cert.pem",
+                         );
+       my @ssl_options;
+       my $ssl_key;
+       my $key;
+       foreach $ssl_key (keys(%ssl_defaults)) {
+               if (!defined($self->{$ssl_key})) {
+                       $self->{$ssl_key} = $ssl_defaults{$ssl_key};
+               }
+       }
+       foreach $ssl_key (keys(%{$self})) {
+               if ($ssl_key =~ /^SSL_/) {
+                       push @ssl_options, $ssl_key,$self->{$ssl_key};
+               }
+       }
+        my $SSL_try="use IO::Socket::SSL";
+       eval $SSL_try;
+       if (!eval {$self->{'Socket'} =
+               IO::Socket::SSL->new(PeerAddr => $self->{'Server'},
+                                    PeerPort => $self->{'Port'},
+                                    Proto => 'tcp',
+                                    Reuse => 1,
+                                    Timeout => 5,
+                                    @ssl_options);}) {
+               $self->_error("initialize", "couldn't establish a sieve SSL connection to",$self->{'Server'}, "[$!]","path=$cwd");
+               delete $self->{'Socket'};
+               return;
+       }
+     }
+     else {
+
+       if (!eval {$self->{'Socket'} = IO::Socket::INET->new(PeerAddr => $self->{'Server'},
+                                                        PeerPort => $self->{'Port'},
+                                                        Proto => 'tcp',
+                                                        Reuse => 1); })
+       {
+               $self->_error("initialize", "could'nt establish a Sieve connection to",$self->{'Server'});                              
+               return;
+       }
+    } # if SSL
+
+    my $fh = $self->{'Socket'};
+     $_ = $self->_read; #get banner
+    my $try=$_;
+    if (!/timsieved/i) {
+       $self->close;
+       $self->_error("initialize","bad response from",$self->{'Server'},$try);
+       return;
+    }
+    chomp;
+    if (/\r$/) {
+       chop;
+    }
+    if (/IMPLEMENTATION/) {
+       $self->{'Implementation'}=$1 if /^"IMPLEMENTATION" +"(.*)"/;
+       #version 2 of cyrus imap/timsieved
+       # get capability
+       # get OK as well
+       $_=$self->_read;
+        while (!/^OK/) {
+          $self->{'Capability'}=$1 if /^"SASL" +"(.*)"/;
+          $self->{'Sieve'}=$1 if /^"SIEVE" +"(.*)"/;
+          $_ = $self->_read;
+##        $_=$self->_read;
+       }
+    }
+    else {
+       $self->{'Capability'}=$_;
+    }
+    $userpass = "$self->{'Proxy'}\x00".$self->{'Login'}."\x00".$self->{'Password'};
+    $encode=encode_base64($userpass);
+    $len=length($encode);
+    print $fh "AUTHENTICATE \"PLAIN\" {$len+}\r\n";
+    print $fh "$encode\r\n";
+    
+    $_ = $self->_read;
+    $try=$_;
+    if ($try=~/NO/) {
+       $self->close;
+       $self->_error("Login incorrect while connecting to $self->{'Server'}", $try);
+       return;
+    } elsif (/OK/) {
+       $self->{'Error'}= "No Errors";
+       return;
+    } else {
+       #croak "$self->{'CLASS'}: Unknown error -- $_";
+       $self->_error("Unknown error",$try);
+       return;
+    }
+    $self->{'Error'}="No Errors";
+    return;
+}
+sub encode_base64 ($;$)
+{
+    my $res = "";
+    my $eol = $_[1];
+    $eol = "\n" unless defined $eol;
+    pos($_[0]) = 0;                          # ensure start at the beginning
+    while ($_[0] =~ /(.{1,45})/gs) {
+       $res .= substr(pack('u', $1), 1);
+       chop($res);
+    }
+    $res =~ tr|` -_|AA-Za-z0-9+/|;               # `# help emacs
+    # fix padding at the end
+    my $padding = (3 - length($_[0]) % 3) % 3;
+    $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
+    # break encoded string into lines of no more than 76 characters each
+    if (length $eol) {
+       $res =~ s/(.{1,76})/$1$eol/g;
+    }
+    $res;
+}
+
+
+sub _error {
+    my $self = shift;
+    my $func = shift;
+    my @error = @_;
+
+    $self->{'Error'} = join(" ",$self->{'CLASS'}, "[", $func, "]:", @error);
+}
+
+sub _read {
+       my $self = shift;
+       my $buffer ="";
+       my $char = "";
+       my $bytes= 1;
+       while ($bytes == 1) {
+               $bytes = sysread $self->{'Socket'},$char,1;
+               if ($bytes == 0) {
+                       if (length ($buffer) != 0) {
+                               return $buffer;
+                       }
+                       else {
+                               return;
+                       }
+               }
+               else {
+                       if (($char eq "\n") or ($char eq "\r")) {
+                               if (length($buffer) ==0) {
+                                       # remove any cr or nl leftover
+                               }
+                               else {
+                                       return $buffer;
+                               }
+                       }
+                       else {
+                               $buffer.=$char;
+                       }
+               }
+       }
+}
+                               
+                               
+sub close {
+    my $self = shift;
+     if (!defined($self->{'Socket'})) {
+       return 0;
+     }
+     my $fh =$self->{'Socket'};
+    print $fh "LOGOUT\r\n";
+    close($self->{'Socket'});
+    delete $self->{'Socket'};
+}
+
+sub putscript {
+    my $self = shift;
+    my $len;
+
+    if (scalar(@_) != 2)  {
+       $self->_error("putscript", "incorrect number of arguments");
+       return 1;
+    }
+
+    my $scriptname = shift;
+    my $script = shift;
+
+    if (!defined($self->{'Socket'})) {
+       $self->_error("putscript", "no connection open to", $self->{'Server'});
+       return 1;
+    }
+    $len=length($script);
+    my $fh = $self->{'Socket'};
+    print $fh "PUTSCRIPT \"$scriptname\" {$len+}\r\n";
+    print $fh "$script\r\n";
+    $_ = $self->_read;
+    if (/^OK/) {
+       $self->{'Error'} = 'No Errors';
+       return 0;
+    } else {
+       $self->_error("putscript", "couldn't save script", $scriptname, ":", $_);
+       return 1;
+    }
+}
+
+sub deletescript {
+    my $self = shift;
+
+    if (scalar(@_) != 1) {
+       $self->_error("deletescript", "incorrect number of arguments");
+       return 1;
+    }
+    my $script = shift;
+    if (!defined($self->{'Socket'})) {
+       $self->_error("deletescript", "no connection open to", $self->{'Server'});
+       return 1;
+    }
+    my $fh = $self->{'Socket'};
+    print $fh "DELETESCRIPT \"$script\"\r\n";
+    $_ = $self->_read;
+    if (/^OK/) {
+       $self->{'Error'} = 'No Errors';
+       return 0;
+    } else {
+       $self->_error("deletescript", "couldn't delete", $script, ":", $_);
+       return 1;
+    }
+}
+sub getscript { # returns a string
+    my $self = shift;
+    my $allscript;
+
+    if (scalar(@_) != 1) {
+       $self->_error("getscript", "incorrect number of arguments");
+       return 1;
+    }
+    my $script = shift;
+    if (!defined($self->{'Socket'})) {
+       $self->_error("getscript", "no connection open to", $self->{'Server'});
+       return 1;
+    }
+    my $fh = $self->{'Socket'};
+    print $fh "GETSCRIPT \"$script\"\r\n";
+    $_ = $self->_read;
+    if (/^{.*}/) { $_ = $self->_read;  } # remove file size line
+
+    # should probably use the file size to calculate how much to read in
+    while ((!/^OK/) && (!/^NO/)) {
+       $_.="\n" if $_ !~/\n.*$/; # replace newline that _read removes
+       $allscript.=$_; 
+       $_ = $self->_read;
+    }
+    if (/^OK/) {
+       return $allscript;
+    } else {
+       $self->_error("getscript", "couldn't get script", $script, ":", $_);
+       return;
+    }
+}
+
+sub setactive {
+    my $self = shift;
+
+    if (scalar(@_) != 1) {
+       $self->_error("setactive", "incorrect number of arguments");
+       return 1;
+    }
+    my $script = shift;
+    if (!defined($self->{'Socket'})) {
+       $self->_error("setactive", "no connection open to", $self->{'Server'});
+       return 1;
+    }
+    my $fh = $self->{'Socket'};
+    print $fh "SETACTIVE \"$script\"\r\n";
+    $_ = $self->_read;
+    if (/^OK/) {
+       $self->{'Error'} = "No Errors";
+       return 0;
+    } else {
+       $self->_error("setactive", "couldn't set as active", $script, ":", $_);
+       return 1;
+    }
+}
+
+
+sub noop {
+    my $self = shift;
+    my ($id, $acl);
+
+    if (!defined($self->{'Socket'})) {
+       $self->_error("noop", "no connection open to", $self->{'Server'});
+       return 1;
+    }
+    my $fh = $self->{'Socket'};
+    print $fh "NOOP\r\n";
+       $_ = $self->_read;
+       if (!/^OK/) {
+           $self->_error("noop", "couldn't do noop"
+                        );
+           return 1;
+       }
+    $self->{'Error'} = 'No Errors';
+    return 0;
+}
+
+
+sub listscripts {
+    my $self = shift;
+    my (@scripts);
+
+    if (!defined($self->{'Socket'})) {
+       $self->_error("listscripts", "no connection open to", $self->{'Server'});
+       return;
+    }
+
+    #send the command
+    $self->{'Socket'}->print ("LISTSCRIPTS\r\n");
+
+    # While we have more to read
+    while (defined ($_ = $self->_read)) {
+
+                       # Exit the loop if we're at the end of the text
+               last if (m/^OK.*/);
+
+                       # Select the stuff between the quotes (without the asterisk)
+               # m/^"([^"]+?)\*?"\r?$/;
+               # Select including the asterisk (to determine the default script)
+#              m/^"([^"]+?\*?)"\r?$/;
+               $_=~s/"//g;
+                       # Get the name of the script
+                       push @scripts, $_;
+     } 
+
+     if (/^OK/) {
+        return @scripts;
+     } else {
+
+
+
+    }
+    if (/^OK/) {
+       return @scripts;
+    } else {
+       $self->_error("list", "couldn't get list for",  ":", $_);
+       return;
+    }
+}
+
+1;
+__END__
+
diff --git a/gosa-core/contrib/scripts/sieve_vacation/update-vacation.pl b/gosa-core/contrib/scripts/sieve_vacation/update-vacation.pl
new file mode 100755 (executable)
index 0000000..aeef964
--- /dev/null
@@ -0,0 +1,600 @@
+#!/usr/bin/perl -w -I/usr/local/lib/perl
+#
+# This code is part of GOsa (https://gosa.gonicus.de)
+# Copyright (C) 2007 Frank Moeller
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+use strict;
+use IMAP::Sieve;
+use XML::Simple;
+use Data::Dumper;
+use Net::LDAP;
+use URI;
+use utf8;
+use Getopt::Std;
+use Date::Format;
+use vars qw/ %opt /;
+
+#
+# Definitions
+#
+my $gosa_config = "/etc/gosa/gosa.conf";
+my $opt_string = 'l:hs';
+my $location = "";
+my $today_gmt = time ();
+my $today = $today_gmt + 3600;
+my $server_attribute = "";
+my $alternate_address_attribute = "";
+my $gosa_sieve_script_name = "gosa";
+my $simple_bind_dn = "";
+my $simple_bind_dn_pwd = "";
+my $gosa_sieve_script_status = "FALSE";
+my $gosa_sieve_spam_header = "Sort mails with higher spam level";
+my ($ss,$mm,$hh,$day,$month,$year,$zone);
+
+#
+# Templates
+#
+my $gosa_sieve_header = "\#\#\#GOSA\nrequire\ \[\"fileinto\",\ \"reject\",\ \"vacation\"\]\;\n\n";
+my $vacation_header_template = "\# Begin vacation message";
+my $vacation_footer_template = "\# End vacation message";
+
+#
+# Placeholder
+#
+my $start_date_ph = "##STARTDATE##";
+my $stop_date_ph = "##STOPDATE##";
+
+#
+# Usage
+#
+sub usage {
+       die "Usage:\nperl $0 [option]\n
+            \twithout any option $0 uses the default location\n
+            \tOptions:
+            \t\t-l <\"location name\">\tuse special location
+            \t\t-s\t\t\tshow all locations
+            \t\t-h\t\t\tthis help \n";
+}
+
+#
+# Config import
+#
+sub read_config {
+       my $input = shift || die "need config file: $!";
+       my $stream = "";
+       open ( FILE, "< $input" ) or die "Error opening file $input: $! \n";
+       {
+               local $/ = undef;
+               $stream = <FILE>;
+       }
+       close ( FILE );
+       return $stream;
+}
+
+#
+# XML parser
+#
+sub parseconfig {
+       my $c_location = shift;
+       my $xmldata = shift;
+       chomp $c_location;
+       chomp $xmldata;
+       my $data = $xmldata;
+       my $xml = new XML::Simple ();
+       my $c_data = $xml -> XMLin( $xmldata);
+       my $config = {};
+       my $config_base;
+       my $ldap_admin;
+       my $ldap_admin_pwd;
+       my $url;
+       my $mailMethod;
+       #print Dumper ($c_data->{main}->{location}->{config});
+       if ( $c_data->{main}->{location}->{config} ) {
+               #print "IF\n";
+               $config_base = $c_data->{main}->{location}->{config};
+               $url = $c_data->{main}->{location}->{referral}->{url};
+               $ldap_admin = $c_data->{main}->{location}->{referral}->{admin};
+               $ldap_admin_pwd = $c_data->{main}->{location}->{referral}->{password};
+               $mailMethod = $c_data->{main}->{location}->{mailMethod};
+       } else {
+               #print "ELSE\n";
+               $config_base = $c_data->{main}->{location}->{$c_location}->{config};
+               $url = $c_data->{main}->{location}->{$c_location}->{referral}->{url};
+               $ldap_admin = $c_data->{main}->{location}->{$c_location}->{referral}->{admin};
+               $ldap_admin_pwd = $c_data->{main}->{location}->{$c_location}->{referral}->{password};
+               $mailMethod = $c_data->{main}->{location}->{$c_location}->{mailMethod};
+       }
+       print "$config_base -- $url -- $ldap_admin -- $ldap_admin_pwd -- $mailMethod\n";
+       $config->{config_base} = $config_base;
+       $config->{url} = $url;
+       $config->{mailMethod} = $mailMethod;
+       $config->{ldap_admin} = $ldap_admin;
+       $config->{ldap_admin_pwd} = $ldap_admin_pwd;
+
+       return $config;
+}
+
+#
+# Get default location
+#
+sub get_default_location {
+       my $xmldata = shift;
+       my $xml = new XML::Simple ( RootName=>'conf' );
+       my $c_data = $xml -> XMLin( $xmldata );
+       my $default = $c_data->{main}->{default};
+
+       return $default;
+}
+
+#
+# List all location
+#
+sub list_locations {
+       my $xmldata = shift;
+       my $xml = new XML::Simple ( RootName=>'conf' );
+       my $c_data = $xml -> XMLin( $xmldata );
+       my $default = get_default_location ( $xmldata );
+       $default = $default . " (default)";
+       my @locations = ( $default );
+       my $data_ref = $c_data->{main}->{location};
+       my @keys = keys ( %{$data_ref} );
+       @locations = (@locations, @keys);
+
+       return @locations;
+}
+
+#
+# LDAP error handling
+#
+sub ldap_error {
+       my ($from, $mesg) = @_;
+       print "Return code: ", $mesg->code;
+       print "\tMessage: ", $mesg->error_name;
+       print " :",          $mesg->error_text;
+       print "MessageID: ", $mesg->mesg_id;
+       print "\tDN: ", $mesg->dn;
+}
+
+
+#
+# LDAP search
+#
+sub ldap_search {
+       my $url = shift;
+       my $searchString = shift;
+       my $scope = shift;
+       my $base = shift;
+       my $attrs = shift;
+       my $bind_dn = shift;
+       my $bind_dn_pwd = shift;
+       
+       if ( $base eq "NULL" ) {
+               $base = "";
+       }
+       my $ldap = Net::LDAP->new( $url ) or die "$@";
+       if ( ( ! ( $bind_dn ) ) || ( ! ( $bind_dn_pwd ) ) ) {
+               $ldap->bind;
+       } else {
+               $ldap->bind ( $bind_dn, password => $bind_dn_pwd );
+       }
+
+       my $result = $ldap->search (    base    => "$base",
+                                       scope   => "$scope",
+                                       filter  => "$searchString",
+                                       attrs   =>  $attrs
+                                       );
+       if ( $result->code ) {
+               ldap_error ( "Searching", $result );
+       }
+
+       $ldap->unbind;
+       
+       return $result;
+}
+
+#
+# Retrieve LDAP server
+#
+sub get_ldap_server {
+       my $url = shift;
+       
+       my $uri = URI->new($url);
+
+       my $scheme = $uri->scheme;
+       my $host = $uri->host;
+       my $port = $uri->port;
+       #print "$scheme - $host - $port\n";
+       my $server = $scheme . "://" . $host . ":" . $port;
+
+       return $server;
+}
+
+#
+# Retrieve LDAP base
+#
+sub get_ldap_base {
+       my $url = shift;
+       my $config_base = shift;
+       my $bind_dn = shift;
+       my $bind_dn_pwd = shift;
+       my $filter = "(objectClass=*)";
+       my $init_base = "NULL";
+       my $scope = "base";
+       my $attributes = [ 'namingcontexts' ];
+       my $entry = {};
+       my $base = "";
+
+       $config_base =~ s/\,\ +/\,/g;
+       #print $url."\n";
+       #print $config_base."\n";
+       my $result = ldap_search ( $url, $filter, $scope, $init_base, $attributes, $bind_dn, $bind_dn_pwd );
+       my @entries = $result->entries;
+       my $noe = @entries;
+       #print $noe."\n";
+       foreach $entry ( @entries ) {
+               my $tmp = $entry->get_value ( 'namingcontexts' );
+               #print $tmp."\n";
+               $tmp =~ s/\,\ +/\,/g;
+               if ( $config_base =~ m/$tmp/ ) {
+                       $base = $entry->get_value ( 'namingcontexts' );
+               }
+       }
+
+       return $base;
+}
+
+#
+# SIEVE functions
+#
+sub opensieve {
+       my $admin = shift;
+       my $pass = shift;
+       my $user = shift;
+       my $server = shift;
+       my $port = shift;
+
+       #print ( "##### Proxy => $user, Server => $server, Login => $admin, Password => $pass, Port => $port ####\n" );
+
+       my $sieve = IMAP::Sieve->new ( 'Proxy' => $user, 'Server' => $server, 'Login' => $admin, 'Password' => $pass, 'Port' => $port );
+       return $sieve;
+}
+
+sub closesieve {
+       my $sieve = shift;
+
+       if ($sieve) {$sieve->close};
+}
+
+sub listscripts {
+       my $sieve = shift;
+
+       my @scripts = $sieve->listscripts;
+       my $script_list = join("\n",@scripts)."\n";
+       #print $script_list;
+       return $script_list;
+}
+
+sub getscript {
+       my $sieve = shift;
+       my $script = shift;
+       my $scriptfile;
+       chomp $script;
+       #print "$sieve\n";
+       #print "$script\n";
+
+       $scriptfile = $sieve->getscript($script);
+       return $scriptfile;
+}
+
+sub putscript {
+       my $sieve = shift;
+       my $scriptname = shift;
+       my $script = shift;
+       #print "$sieve\n";
+       #print "$scriptname\n";
+       #print "$script\n";
+
+       my $res=$sieve->putscript($scriptname,$script);
+       if ($res) {print $sieve->{'Error'}}
+       return;
+}
+
+sub setactive {
+       my $sieve = shift;
+       my $script = shift;
+
+       my $res=$sieve->setactive($script);
+       if ($res) { print $sieve->{'Error'};}
+       return;
+}
+
+#
+# main ()
+#
+# read options
+getopts( "$opt_string", \%opt );
+
+# read GOsa config
+my $input_stream = read_config ( $gosa_config );
+
+# get location
+if ( $opt{l} ) {
+       $location = $opt{l};
+} elsif ( $opt{h} ) {
+       usage ();
+       exit (0);
+} elsif ( $opt{s} ) {
+       my $loc;
+       my $counter = 1;
+       my @locations = list_locations ( $input_stream );
+       print "\nConfigured Locations: \n";
+       print "---------------------\n";
+       foreach $loc ( @locations ) {
+               print $counter . ". " . $loc . "\n";
+               $counter++;
+       }
+       print "\n\n";
+       exit (0);
+} else {
+       $location = get_default_location ( $input_stream );
+}
+
+# parse config
+my $config = parseconfig ( $location, $input_stream );
+my $ldap_url = get_ldap_server ( $config->{url} );
+my $gosa_config_base = $config->{config_base};
+my $bind_dn = $config->{ldap_admin};
+my $bind_dn_pwd = $config->{ldap_admin_pwd};
+my $mailMethod = $config->{mailMethod};
+utf8::encode($ldap_url);
+utf8::encode($gosa_config_base);
+utf8::encode($mailMethod);
+
+# default mailMethod = kolab
+if ( $mailMethod =~ m/kolab/i ) {
+       $server_attribute = "kolabHomeServer";
+       $alternate_address_attribute = "alias";
+} elsif ( $mailMethod =~ m/cyrus/i ) {
+       $server_attribute = "gosaMailServer";
+       $alternate_address_attribute = "gosaMailAlternateAddress";
+} else {
+       exit (0);
+}
+
+# determine LDAP base
+my $ldap_base = get_ldap_base ( $ldap_url, $gosa_config_base, $simple_bind_dn, $simple_bind_dn_pwd );
+
+# retrieve user informations with activated vacation feature
+my $filter = "(&(objectClass=gosaMailAccount)(gosaMailDeliveryMode=*V*)(!(gosaMailDeliveryMode=*C*)))";
+my $list_of_attributes = [ 'uid', 'mail', $alternate_address_attribute, 'gosaVacationMessage', 'gosaVacationStart', 'gosaVacationStop', $server_attribute ];
+my $search_scope = "sub";
+my $result = ldap_search ( $ldap_url, $filter, $search_scope, $ldap_base, $list_of_attributes, $simple_bind_dn, $simple_bind_dn_pwd );
+
+my @entries = $result->entries;
+my $noe = @entries;
+#print "NOE = $noe\n";
+my $entry = {};
+foreach $entry ( @entries ) {
+       # INITIALISATIONS
+       $gosa_sieve_script_status = "FALSE";
+       my @sieve_scripts = "";
+       my $script_name = "";
+       my $sieve_script = "";
+       my $sieve_vacation = "";
+       # END INITIALISATIONS
+       my $uid_v = $entry->get_value ( 'uid' );
+       #print "$uid_v\n";
+       my $mail_v = $entry->get_value ( 'mail' );
+       my @mailalternate = $entry->get_value ( $alternate_address_attribute );
+       my $vacation = $entry->get_value ( 'gosaVacationMessage' );
+       my $start_v = $entry->get_value ( 'gosaVacationStart' );
+       my $stop_v = $entry->get_value ( 'gosaVacationStop' );
+       my $server_v = $entry->get_value ( $server_attribute );
+
+       # temp. hack to compensate old gosa server name style
+       #if ( $server_v =~ m/^imap\:\/\//i ) {
+       #       $server_v =~ s/^imap\:\/\///;
+       #}
+       if ( ! ( $uid_v ) ) {
+               $uid_v = "";
+       }
+       if ( ! ( $mail_v ) ) {
+               $mail_v = "";
+       }
+       my @mailAddress = ($mail_v);
+       my $alias = "";
+       foreach $alias ( @mailalternate ) {
+               push @mailAddress, $alias;
+       }
+       my $addresses = "";
+       foreach $alias ( @mailAddress ) {
+               $addresses .= "\"" . $alias . "\", ";
+       }
+       $addresses =~ s/\ *$//;
+       $addresses =~ s/\,$//;
+       if ( ! ( $vacation ) ) {
+               $vacation = "";
+       }
+
+       if ( ! ( $start_v ) ) {
+               $start_v = 0;
+               next;
+       }
+       #print time2str("%d.%m.%Y", $start_v)."\n";
+       my $start_date_string = time2str("%d.%m.%Y", $start_v)."\n";
+
+       if ( ! ( $stop_v ) ) {
+               $stop_v = 0;
+               next;
+       }
+       #print time2str("%d.%m.%Y", $stop_v)."\n";
+       my $stop_date_string = time2str("%d.%m.%Y", $stop_v)."\n";
+
+       chomp $start_date_string;
+       chomp $stop_date_string;
+       $vacation =~ s/$start_date_ph/$start_date_string/g;
+       $vacation =~ s/$stop_date_ph/$stop_date_string/g;
+
+       if ( ! ( $server_v ) ) {
+               $server_v = "";
+               next;
+       }
+       #print $uid_v . " | " .
+       #       $addresses . " | " .
+       #       "\n";
+
+       my ($sieve_user, $tmp) = split ( /\@/, $mail_v );
+
+       print "today = $today\nstart = $start_v\nstop = $stop_v\n";
+       my $real_stop = $stop_v + 86400;
+       if ( ( $today >= $start_v ) && ( $today < $real_stop ) ) {
+               print "activating vacation for user $uid_v\n";
+
+               my $srv_filter = "(&(goImapName=$server_v)(objectClass=goImapServer))";
+               my $srv_list_of_attributes = [ 'goImapSieveServer', 'goImapSievePort', 'goImapAdmin', 'goImapPassword' ];
+               my $srv_result = ldap_search ( $ldap_url, $srv_filter, $search_scope, $ldap_base, $srv_list_of_attributes, $bind_dn, $bind_dn_pwd );
+               my @srv_entries = $srv_result->entries;
+               my $srv_entry = {};
+               my $noe = @srv_entries;
+               if ( $noe == 0 ) {
+                       printf STDERR "Error: no $server_attribute defined! Aboarting...";
+               } elsif ( $noe > 1 ) {
+                       printf STDERR "Error: multiple $server_attribute defined! Aboarting...";
+               } else {
+                       my $goImapSieveServer = $srv_entries[0]->get_value ( 'goImapSieveServer' );
+                       my $goImapSievePort = $srv_entries[0]->get_value ( 'goImapSievePort' );
+                       my $goImapAdmin = $srv_entries[0]->get_value ( 'goImapAdmin' );
+                       my $goImapPassword = $srv_entries[0]->get_value ( 'goImapPassword' );
+                       if ( ( $goImapSieveServer ) && ( $goImapSievePort ) && ( $goImapAdmin ) && ( $goImapPassword ) ) {
+#                              if ( ! ( $sieve_user = $uid_v ) ) {
+#                                      $sieve_user = $uid_v;
+#                              }
+                               #my $sieve = opensieve ( $goImapAdmin, $goImapPassword, $sieve_user, $goImapSieveServer, $goImapSievePort);
+                               my $sieve = opensieve ( $goImapAdmin, $goImapPassword, $uid_v, $goImapSieveServer, $goImapSievePort);
+                               @sieve_scripts = listscripts ( $sieve );
+                               #print Dumper (@sieve_scripts);
+                               $script_name = "";
+                               if ( @sieve_scripts ) {
+                                       foreach $script_name ( @sieve_scripts ) {
+                                               if ( $script_name =~ m/$gosa_sieve_script_name/ ) {
+                                                       $gosa_sieve_script_status = "TRUE";
+                                               }
+                                       }
+                                       if ( $gosa_sieve_script_status eq "TRUE" ) {
+                                               print "retrieving and modifying gosa sieve script for user $uid_v\n";
+                                               # requirements
+                                               $sieve_script = getscript( $sieve, $gosa_sieve_script_name );
+                                               #print "$sieve_script\n";
+                                               if ( ! ( $sieve_script ) ) {
+                                                       print "No Sieve Script! Creating New One!\n";
+                                                       $sieve_script = $gosa_sieve_header;
+                                               }
+                                               if ( $sieve_script =~ m/require.*\[.*["|'] *vacation *["|'].*\]/ ) {
+                                                       print "require vacation ok\n";
+                                               } else {
+                                                       print "require vacation not ok\n";
+                                                       print "modifying require statement\n";
+                                                       $sieve_script =~ s/require(.*\[.*)\]/require$1\, "vacation"\]/;
+                                               }
+                                               if ( ! ( $sieve_script =~ m/$vacation_header_template/ ) ) {
+                                                       print "no match header template\n";
+                                                       $sieve_vacation = $vacation_header_template .
+                                                                               "\n" .
+                                                                               "vacation :addresses [$addresses]\n" .
+                                                                               "\"" .
+                                                                               $vacation . 
+                                                                               "\n\"\;" .
+                                                                               "\n" .
+                                                                               $vacation_footer_template .
+                                                                               "\n\n";
+                                               }
+                                               #print ( "$sieve_vacation\n" );
+                                               #print ( "$sieve_script\n" );
+                                               # including vacation message
+                                               if ( $sieve_script =~ m/$gosa_sieve_spam_header/ ) {
+                                                       #print "MATCH\n";
+                                                       $sieve_script =~ s/($gosa_sieve_spam_header[^{}]*{[^{}]*})/$1\n\n$sieve_vacation/;
+                                               } else {
+                                                       $sieve_script =~ s/require(.*\[.*\]\;)/require$1\n\n$sieve_vacation/;
+                                               }
+                                               #print ( "START SIEVE $sieve_script\nSTOP SIEVE" );
+                                               # uploading new sieve script
+                                               putscript( $sieve, $gosa_sieve_script_name, $sieve_script );
+                                               # activating new sieve script
+                                               setactive( $sieve, $gosa_sieve_script_name );
+                                       } else {
+                                               print "no gosa script available for user $uid_v, creating new one";
+                                               $sieve_script = $gosa_sieve_header . "\n\n" . $sieve_vacation;
+                                               # uploading new sieve script
+                                               putscript( $sieve, $gosa_sieve_script_name, $sieve_script );
+                                               # activating new sieve script
+                                               setactive( $sieve, $gosa_sieve_script_name );
+                                       }
+                               }
+                               closesieve ( $sieve );
+                       }
+               }
+       } elsif ( $today >= $real_stop ) {
+               print "deactivating vacation for user $uid_v\n";
+
+               my $srv_filter = "(&(goImapName=$server_v)(objectClass=goImapServer))";
+               my $srv_list_of_attributes = [ 'goImapSieveServer', 'goImapSievePort', 'goImapAdmin', 'goImapPassword' ];
+               my $srv_result = ldap_search ( $ldap_url, $srv_filter, $search_scope, $ldap_base, $srv_list_of_attributes, $bind_dn, $bind_dn_pwd );
+               my @srv_entries = $srv_result->entries;
+               my $srv_entry = {};
+               my $noe = @srv_entries;
+               if ( $noe == 0 ) {
+                       printf STDERR "Error: no $server_attribute defined! Aboarting...";
+               } elsif ( $noe > 1 ) {
+                       printf STDERR "Error: multiple $server_attribute defined! Aboarting...";
+               } else {
+                       my $goImapSieveServer = $srv_entries[0]->get_value ( 'goImapSieveServer' );
+                       my $goImapSievePort = $srv_entries[0]->get_value ( 'goImapSievePort' );
+                       my $goImapAdmin = $srv_entries[0]->get_value ( 'goImapAdmin' );
+                       my $goImapPassword = $srv_entries[0]->get_value ( 'goImapPassword' );
+                       if ( ( $goImapSieveServer ) && ( $goImapSievePort ) && ( $goImapAdmin ) && ( $goImapPassword ) ) {
+                               #my $sieve = opensieve ( $goImapAdmin, $goImapPassword, $sieve_user, $goImapSieveServer, $goImapSievePort);
+                               my $sieve = opensieve ( $goImapAdmin, $goImapPassword, $uid_v, $goImapSieveServer, $goImapSievePort);
+                               @sieve_scripts = listscripts ( $sieve );
+                               $script_name = "";
+                               if ( @sieve_scripts ) {
+                                       foreach $script_name ( @sieve_scripts ) {
+                                               if ( $script_name =~ m/$gosa_sieve_script_name/ ) {
+                                                       $gosa_sieve_script_status = "TRUE";
+                                               }
+                                       }
+                                       if ( $gosa_sieve_script_status eq "TRUE" ) {
+                                               # removing vacation part
+                                               $sieve_script = getscript( $sieve, $gosa_sieve_script_name );
+                                               if ( $sieve_script ) {
+                                                       #print "OLD SIEVE SCRIPT:\n$sieve_script\n\n";
+                                                       $sieve_script =~ s/$vacation_header_template[^#]*$vacation_footer_template//;
+                                                       #print "NEW SIEVE SCRIPT:\n$sieve_script\n\n";
+                                                       # uploading new sieve script
+                                                       putscript( $sieve, $gosa_sieve_script_name, $sieve_script );
+                                                       # activating new sieve script
+                                                       setactive( $sieve, $gosa_sieve_script_name );
+                                               }
+                                       }
+                               }
+                               closesieve ( $sieve );
+                       }
+               }
+       } else {
+               print "no vacation process necessary for user $uid_v\n";
+       }
+}
diff --git a/gosa-core/contrib/shells b/gosa-core/contrib/shells
new file mode 100644 (file)
index 0000000..e8805ec
--- /dev/null
@@ -0,0 +1,6 @@
+/bin/ash
+/bin/bash
+/bin/csh
+/bin/sh
+/bin/ksh
+/bin/tcsh
diff --git a/gosa-core/contrib/socket_server/client.php b/gosa-core/contrib/socket_server/client.php
new file mode 100755 (executable)
index 0000000..a8ec842
--- /dev/null
@@ -0,0 +1,25 @@
+#!/usr/bin/php5 -q
+<?php
+
+require_once("../../include/class_socketClient.inc");
+error_reporting(E_ALL);
+
+$sock = new Socket_Client("10.89.1.155","9999",TRUE,1);
+#$sock = new Socket_Client("169.254.2.248","9999",TRUE,1);
+$sock->setEncryptionKey("ferdinand_frost");
+
+if($sock->connected()){
+       /* Prepare a hunge bunch of data to be send */
+       $data = "<xml><header>ping</header><source>192.168.1.36:10001</source><target>192.168.1.36:10000</target></xml>";
+       $sock->write($data);
+  
+  #$sock->setEncryptionKey("ferdinand_frost");
+
+       $answer = $sock->read();        
+  echo "$answer\n";
+       $sock->close(); 
+}else{
+       echo "... FAILED!\n";
+}
+
+?>
diff --git a/gosa-core/contrib/socket_server/server.php b/gosa-core/contrib/socket_server/server.php
new file mode 100755 (executable)
index 0000000..8bf4265
--- /dev/null
@@ -0,0 +1,117 @@
+#!/usr/bin/php5 -q
+<?php
+
+error_reporting(E_ALL);
+
+//IP to bind to, use 0 for all 
+$bind_ip = 0;
+
+// Port to bind  
+$bind_port = 10000;
+
+// Max clients 
+$max_clients = 3;
+
+// Rijndal encrypt key 
+$enable_encryption = TRUE;
+$encrypt_key = "ferdinand_frostferdinand_frostfe";
+
+/* Create Socket - 
+ *  AF_INET means IPv4 Socket 
+ *  SOCK_STREAM means Fullduplex TCP
+ *  SOL_TCP - Protocol type TCP
+ */
+$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
+
+/* Enable reuse of local address */
+socket_set_option($socket,SOL_SOCKET,SO_REUSEADDR,1);
+
+/* Bind to socket */
+socket_bind($socket,$bind_ip,$bind_port);
+socket_listen($socket,$max_clients);
+
+$clients = array('0' => array('socket' => $socket));
+
+echo "\nServer startet on port : $bind_port\n";
+
+
+/* Open the cipher */
+$td = mcrypt_module_open('rijndael-128', '', 'cbc', '');
+
+/* Create the IV and determine the keysize length */
+$iv = substr(md5('GONICUS GmbH'),0, mcrypt_enc_get_iv_size($td));
+$ks = mcrypt_enc_get_key_size($td);
+echo "IV-Size: ".mcrypt_enc_get_iv_size($td)."\n";
+
+/* Create key */
+$key = substr(md5('ferdinand_frost'), 0, $ks);
+echo "Key: $key\n";
+
+/* Intialize encryption */
+mcrypt_generic_init($td, $key, $iv);
+
+/* Accept connections till server is killed */
+while(TRUE) {
+
+       /* Create an array of sockets to read from */
+       $read[0] = $socket;
+       for($i=1;$i<count($clients)+1;$i++) {
+               if(isset($clients[$i] ) && $clients[$i] != NULL) {
+                       $read[$i+1] = $clients[$i]['socket'];
+               }
+       }
+
+       $ready = socket_select($read,$write=NULL,$except=NULL,0);
+
+       /* Handle incoming connections / Incoming data */
+       if(in_array($socket,$read)) {
+
+               /* Check each client slot for a new connection */
+               for($i=1;$i<$max_clients+1;$i++) {
+               
+                       /* Accept new connections */
+                       if(!isset($clients[$i])) {
+                               $clients[$i]['socket'] = socket_accept($socket);
+                               socket_getpeername($clients[$i]['socket'],$ip);
+                               $clients[$i]['ipaddy'] = $ip;
+
+                               echo("New client connected: " . $clients[$i]['ipaddy'] . " \n");
+                               break;
+                       }
+                       elseif($i == $max_clients - 1) {
+                               echo("To many Clients connected! \n");
+                       }
+                       if($ready < 1) {
+                               continue;
+                       }
+               }
+       }
+
+       /* Check if there is data to read from the client sockets */
+       for($i=1;$i<$max_clients+1;$i++) {
+
+               /* Check if socket has send data to the server */
+               if(isset($clients[$i]) && in_array($clients[$i]['socket'],$read)) {
+
+                       /* Read socket data */
+                       $data = @socket_read($clients[$i]['socket'],1024000, PHP_NORMAL_READ);
+
+                       /* Client disconnected */
+                       if ($data === FALSE) {
+                               unset($clients[$i]);
+                               echo "Client disconnected!\n";
+                               continue;
+                       }
+
+                       $data = mdecrypt_generic($td, trim($data));
+                       echo "Client (".$clients[$i]['ipaddy'].") sent: ".$data."... \n";
+
+                       echo "Sending reply... \n";
+                       socket_write($clients[$i]['socket'],mcrypt_generic($td, $data));
+
+                       @socket_close($clients[$i]);
+               }
+       }
+}
+
+?> 
diff --git a/gosa-core/contrib/vacation_example.txt b/gosa-core/contrib/vacation_example.txt
new file mode 100644 (file)
index 0000000..58cad15
--- /dev/null
@@ -0,0 +1,9 @@
+DESC: Funny message
+I am currently out at a job interview and will reply to you if I fail
+to get the position. Be prepared for my mood. In urgent cases you can
+reach me on the cell phone via %mobile or write a snail mail to:
+
+%homePostalAddress
+
+Greetings,
+%givenName %sn